Skip to content

Commit

Permalink
Merge pull request #3 from sts2885/DS-50--.-Step_3_deploy_monitoring_…
Browse files Browse the repository at this point in the history
…system

Ds 50  . step 3 deploy monitoring system
  • Loading branch information
sts2885 authored May 7, 2023
2 parents 2263251 + 3848b98 commit fa43abc
Show file tree
Hide file tree
Showing 53 changed files with 2,767 additions and 191 deletions.
273 changes: 97 additions & 176 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,198 +1,119 @@
현황 :
1. 테라폼 책보고 따라 만들어서 ALB에 ASG도 있지만, default vpc에서 만들었으며, 1티어다.
# Project 1 Terraform으로 3tier 구성하고 monitoring system 띄우기

2. 블로그 하나를 보니까 vpc를 나눴지만 2티어며 ALB와 ASG가 없다.
프로젝트 해설 블로그 : 비밀번호 있음
https://cherry-blossome-in-march.tistory.com/12

개요

전체 프로젝트 목표
=> 테라폼 - 쿠버네티스 - 젠킨스 - 서비스 1종류 이상

phase 1. 테라폼으로 인프라 생성하기

실행법
1. terraform 설치
2. git clone
3. terraform provider 채워 넣고
4. terraform init
5. terraform plan
6. terraform apply
7. ip 확인하기
8. prometheus ip 집어넣기
9. grafana 연결하기
10. dash board import

3. AWS 강의 들은 곳에서는 3tier로 서비스를 만들었는데 테라폼으로는 아직이다.

그래서 이거 3개를 다 합쳐볼 생각이다.
1. Terraform을 설치한다. (다른 블로그를 참고 하면 좋다.)
https://may9noy.tistory.com/422

2. git clone https://github.com/sts2885/devops_study_project.git

여기에는 문제 인식, 문제 해결 과정, trouble shooting 과정을 모두 기입하겠다.
3. terraform provider 채워 넣기

provider_example.tf를 열고

# step 1 blog 따라 만들기 #clear
profile에 본인 계정의 iam_user_name을 입력하고
access_key와 secret_key 를 채워넣으면 끝이다.

# step 2 기존 코드에 vpc 올리기
4. terraform init
5. terraform plan
6. terraform apply
을 진행하면 인프라는 생성 완료

이거도 금방끝나는 작업일듯 -> 둘이 합치기만 하면 끝임
=> 라고 생각했는데 subnet만 바꿔 주면 될거 같은데 좀 복잡하네?
7. ip 확인하기
Terraform에서는 생성된 인스턴스의 ip 등을 볼 수 있는 기능이 있다. 다만 이건 resource에서 직접 지정해서 만든 인스턴스에 국한되며,
ASG가 생성한 인스턴스는 Terraform이 직접 만든게 아니라 정보가 저장되어 있지는 않다.
이에 대한 우회법의 한 종류를 terraform github의 issue에서 얻었다.
https://github.com/hashicorp/terraform-provider-aws/issues/511

이를 참고해 print_private_ips.tf 에는 auto scaling group을 통해 생성된 인스턴스들의 ip를 출력하는 output 코드를 작성했다.
근데 여기에는 문제가 하나 있는데 terraform은 목표한 인프라 생성이 끝나면 바로 output을 출력하는데
이때는 아직 인스턴스들에 private ip가 제대로 부여되지 않은 모양이다.
근데 terraform은 이걸 기다려야 될 이유가 없으므로 그냥 빈 리스트를 출력해버린다.

한번에 하려니까 생각보다 복잡한거같아.

중간 단계들로 나누자
## ALB, NLB의 domain name 과 EIP를 부여한 monitoring server의 ip는 잘 출력되지만, 인스턴스들의 private ip는 비어있다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
db_lb_dns_name = "terraform-db-nlb-06666bd7e7991201.elb.us-east-1.amazonaws.com"
db_private_ips = tolist([])
monitoring_ip = "52.203.56.113"
was_lb_dns_name = "terraform-was-nlb-6054bea8c8eef84c.elb.us-east-1.amazonaws.com"
was_private_ips = tolist([])
web_alb_dns_name = "terraform-web-alb-931314618.us-east-1.elb.amazonaws.com"
web_private_ips = tolist([])
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

step 2-1
아직 100퍼센트 해결법은 잘 모르겠다. 그냥 위 링크한 이슈에서 다른 유저들이 쓴 방법을 쓰면 될 수 도 있겠다.
(하지만 이게 제일 간단했으니까...)

3티어 나눴지만 마치 1티어인것처럼 만들자
=> 이러면 기존이랑 똑같다고 생각하고 subnet id만 바꾸면 되겠지?
이에 대한 간단한 해결책은 그냥 terraform apply를 한번 더 입력하면

변경점 : terraform aws_autoscaling_group에서
vpc_identifier 부분에 subnet id가 리스트로 들어감
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group
~ db_private_ips = [
+ "10.1.0.239",
+ + "10.1.0.212",
+ ~ was_private_ips = [
+ "10.1.0.175",
+ + "10.1.0.149",
+ ~ web_private_ips = [
+ "10.1.0.82",
+ + "10.1.0.104",

설계도 보고 콘솔에서, 코드 만들수 있나 해보자
하단에 private ip가 표기될거다.(이때쯤이면 인스턴스 생성이 끝났을 테니까.)

=> 다 하고 설계도 그려봤는데
=> 실제 콘솔에서 하는 거랑 다른데? 코드는 ALB랑 ASG가 직접 연결이 안되어 있고 lb target group정도가 ASG에서 가지고 있다 정도만 있는데?
=> 콘솔에서는 직접 연결함
그리고 apply 하시겠습니까? 는 no를 입력해라 (apply 일어나면 monitoring server가 삭제되고 새로 생성된다.)


왜 연결이 될까에 대해서 책에서 설명이 한번 되어 있음
8. prometheus ip 집어넣기
monitoring 서버에는 이미 prometheus docker 가 설치되어 있으니까
/home/ubuntu/prometheus.yml 파일을 수정하고 다시 실행해준다.(아래 명령어에 ip를 넣고 복붙하면 된다.)

AWS first-class integration 덕분에 된다고 하는데, 이렇게 만들면 콘솔에서는 안만들어지지 않냐? 아무튼.
두개를 각자 따로 만들고 위에 저거로 연결 한다는 모양임
echo """
global:
scrape_interval: 15s
evaluation_interval: 15s

Working with AWS service integrations for HTTP APIs
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets:
- 0.0.0.0:9090

amazon.com
https://docs.aws.amazon.com › latest › developerguide
A first-class integration connects an HTTP API route to an AWS service API. When a client invokes a route that's backed by a first-class integration, API ...
- job_name: 'node_exporter'
static_configs:
- targets:
- "10.1.0.239:9100"
- "10.1.0.212:9100"
- "10.1.0.175:9100"
- "10.1.0.149:9100"
- "10.1.0.82:9100"
- "10.1.0.104:9100"
""" | tee /home/ubuntu/prometheus.yml

docker restart prometheus

9. grafana 연결하기
10. dash board import

제 블로그를 참고해주신다면 감사하겠습니다.(그냥 들어가서 datasource만 추가해주면 됩니다.)
https://cherry-blossome-in-march.tistory.com/5

아아~ asg를 보니까 기존 로드 밸런서에 연결 항목에
로드 밸런서 대상 그룹에서 선택 이라고 있네
여기에 target group의 arn이 들어가면 연결을 해주는 구조네


발생한 에러 핸들링 1.

security group이 vpc에 링크되어야 하나봄
지금까지는 default에 넣어서 그런지 지정 안해줘도 들어가 졌는데
=> 이젠 해야 되나 봄

security group에 vpc id를 넣어주면 끝임
vpc_id = aws_vpc.main.id

제대로 만들어지고 서버도 배포 완료됨
서브넷도 정상적으로 만들어지고, nat도.

신기했던점. 진짜 콘솔이랑 100퍼센트 똑같구나
resource "aws_lb_listener_rule" "asg"
#이부분이 aws 강의에서 rule edit에 들어가서 연필모양 눌러서
#규칙 변경하고, 리디렉션 하고 route53 호스팅 영역 관리할때 봤던 부분임



step 2-2

2번째, 3번째 티어 위치에 같은 소프트웨어 똑같이 배포

현재 pub-sub-a,c 만 씀
일단 연결을 생각하지 말고
pri-sub-app-a,c pri-sub-db-a,c 도 똑같이 인프라 만들어
=> web was db 소프트웨어는 띄울 수 있으려나?...
=> web, was는 될거 같아.
=> db가 문제임 클러스터링 할 줄 몰라서
=> 누가 만들어 놓은 오픈소스 하나 없나? 가져다가 올리기만 하고 싶은데?
=> 검색 조금 해보니까 쿠버네티스를 쓰는 경우에도 DB를 스케일링 해야 될 필요가 있네

docker hub, github를 좀 찾아보자

일단 인프라 먼저

step 2-3
web, was, db를 각각 연결
=> 근데 db는 클러스터링은 생각하지 말자고
어짜피 쓸줄도 모르니까.

근데 잠깐, db도 asg를 붙여줘야 되나?
흠...
보통 rds 써버리니까. 이건 고려 안해도 되는 거 아닌가?
db는 인스턴스 그냥 1개만 올릴까?

app tier 에는 alb가 아니라

nlb를 붙여줘야 하는 듯

https://medium.com/awesome-cloud/aws-difference-between-application-load-balancer-and-network-load-balancer-cb8b6cd296a4


https://no-easy-dev.tistory.com/entry/AWS-ALB%EC%99%80-NLB-%EC%B0%A8%EC%9D%B4%EC%A0%90



=> alb를 못쓸건 없음
=> 문제는 alb 보다 nlb가 빠름
=> alb는 l7 단을 지원해서 http 통신이 가능하지만 비교적 느리고
=> nlb는 l4 까지만 지원해서 http 헤더를 못읽는 대신 비교적 빠르다.

was, db는 http 통신을 할 필요가 없어서 nlb가 더 어울린다.



Error: : health_check.matcher is not supported for target_groups with TCP protocol

nlb는 http 안씀 => tcp로 health check해야 되는데
안되는 버그가 있는 듯

https://github.com/hashicorp/terraform-provider-aws/issues/8305

깃허브 issue에서 제일 아래에 matcher와 path를 일부러
빈 String으로 둬라 라는 말대로 한번 해보겠음.

생성 -> pub instance 하나 들어가서 확인해봐야 함.

Error: creating ELBv2 network Load Balancer (terraform-app-tier-alb): InvalidConfigurationRequest: A load balancer cannot be attached to multiple subnets in the same Availability Zone

멍청해서 private subnet에 az를 안넣었음
=> 안넣어도 돌아간다는걸 깨달았네 ㄷㄷ;;


│ Error: creating ELBv2 Listener (arn:aws:elasticloadbalancing:us-east-1:222170749288:loadbalancer/net/terraform-app-tier-alb/787b0e543abb8cf3): InvalidLoadBalancerAction: The action type 'fixed-response' is not valid with network load balancer

그냥 default_action 자체를 안넣어주면 될듯

│ Error: Insufficient default_action blocks │ │ on load_balancer_pri_app.tf line 10, in resource "aws_lb_listener" "app_tier_lb_listener_8080": │ 10: resource "aws_lb_listener" "app_tier_lb_listener_8080" { │ │ At least 1 "default_action" blocks are required.

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener

보니까 그냥 forward로 보내기 가 있네

redirection까지 있어서 원하면 강의에서 들은거 100퍼센트 다 구현할 수 있을듯...


nlb는 listener rule이 없다는 에러 떠서 주석 처리 하고 실행중


우여곡절 끝에 생성은 됐는데

들어가서 private ip로 curl 8080 을 날리면 날아가는데

elb dns name으로 날리면 안날라감(반응 없음)

보니까 lb target group에 health check 할 인스턴스가 하나도 없음

pri app asg에 pub-tg가 들어가 있었음

이제 target group은 healthy 뜸.

근데 여전히 curl은 안됨

반응이 없는게 전형적인 네트워크가 연결이 안됐을때의 반응인데

https://passwd.tistory.com/entry/Redmine-on-AWS-NLB-%EC%83%9D%EC%84%B1


이 사람 손으로 web - was를 nlb로 연결하는 작업함
=> internal을 쓰더라고?
=> 그리고 나도 손으로 만들어보려다가 facing internet을 했는데
너 igw 연결 안되어 있잖아 warning 뜸

아마 인터넷 통해서 통신 하려고 해서 안되는 거 아닐까?(추측)

테라폼 쓰다보니까 확실히 알겠다.
=> 그냥 modify 하는게 아니라
=> 배포전략에 따라서 생성 -> 연결 -> 삭제 의 순으로 수정을 해야 돼네
=> 수정 그냥 시켰더니 다른 곳에 연결되어있습니다 에러 같은게 발생하기도 하고
=> 100퍼센트 성공을 보장하지는 않네


성공했다~~~~

오늘도 억까를 이겨내고 성공했다아아아아~~~~

여세를 몰아서 db까지 생성만 딱 하고 오늘 마무리 하자

DB도 만들고 있는데 느끼는게

포트이름을 잘못쓴다던지 <- 이런 이름 잘못쓰는 휴먼 폴트가 엄청많이 일어난다.
44 changes: 44 additions & 0 deletions db_auto_scale.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
resource "aws_launch_configuration" "db_lc" {
image_id = "ami-007855ac798b5175e"
instance_type = "t2.micro"
security_groups = [aws_security_group.db_sg.id]
key_name = "DevOps_Study"

user_data = data.template_file.db_user_data.rendered
/*
<<-EOF
#!/bin/bash
echo "This is DB" > index.html
nohup busybox httpd -f -p ${var.mysql_port}
EOF
*/
lifecycle {
create_before_destroy = true
}
}

data "template_file" "db_user_data" {
template = file("db_user_data.sh")

vars = {
mysql_port = var.mysql_port
node_exporter_port = var.node_exporter_port
}
}

resource "aws_autoscaling_group" "db_asg" {
launch_configuration = aws_launch_configuration.db_lc.name
vpc_zone_identifier = [aws_subnet.private_subnet_db_a.id,
aws_subnet.private_subnet_db_c.id]
target_group_arns = [aws_lb_target_group.db_lb_tg.arn]

min_size = 2
max_size = 10

tag {
key = "Name"
value = "terraform-db-nlb-asg"
propagate_at_launch = true
}
}

File renamed without changes.
22 changes: 22 additions & 0 deletions db_user_data.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash
echo "This is DB" > index.html
nohup busybox httpd -f -p ${mysql_port} &

apt update
apt install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -

add-apt-repository --yes "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

apt update

apt install -y docker-ce docker-ce-cli containerd.io

systemctl start docker

docker run \
-itd \
-p ${node_exporter_port}:${node_exporter_port} \
--name node_exporter \
prom/node-exporter
Loading

0 comments on commit fa43abc

Please sign in to comment.