ASG는 IP가 바뀐다 — ec2_sd 태그 발견 + Launch Template로 백엔드 관측
백엔드는 Auto Scaling Group이라 인스턴스가 교체되며 IP가 계속 바뀐다. GPU 박스처럼 IP를 박아 긁을 수 없어서, Prometheus의 EC2 서비스 디스커버리(
ec2_sd)로 태그를 보고 자동 발견하게 하고, exporter는 Launch Template의 user-data에 구워 새 인스턴스마다 자동으로 뜨게 했다.
이 글은 QA 관측 스택 구축기의 ⑤ 백엔드 ASG 관측 조각을 자세히 푼 것이다. 계정 번호 자리는 <계정ID>로 적는다.
문제 — ASG는 IP가 (그리고 ASG 이름도) 바뀐다
GPU 관측에선 GPU가 단일 고정 박스라 targets: ['10.76.16.28:9400']처럼 IP를 직접 적었다. 백엔드는 다르다.
- 백엔드는 CodeDeploy 블루그린 ASG다. 배포하면 새 인스턴스 세트(green)를 띄워 트래픽을 옮기고 옛 세트를 내린다 → 인스턴스가 통째로 교체되고 IP가 바뀐다
- 블루그린은 배포마다 ASG 자체도 새로 생긴다(이름이
CodeDeploy_...d-XXXX로 바뀜)
→ static IP는 교체 때마다 깨진다. 태그로 발견해야 한다.
flowchart LR
P["Prometheus<br/>ec2_sd (tag:Name=myton-qa-backend-asg)"] -->|"EC2 DescribeInstances"| API["EC2 API"]
API -->|"태그 매칭 인스턴스의 '현재 IP'"| P
P -->|":9100 / :8001 긁기"| BE["백엔드 인스턴스<br/>(교체되면 새 IP로 자동 갱신)"]
exporter는 Launch Template의 user-data에 (AMI에 굽지 않고)
백엔드 인스턴스는 user-data 스크립트가 부팅 때 ECR에서 앱을, Docker Hub에서 로그 에이전트(Alloy)를 받아 docker run으로 띄우는 구조였다. 그래서 exporter도 그 user-data에 docker run 몇 줄 추가하면, ASG가 새로 띄우는 모든 인스턴스가 부팅 시 자동으로 exporter를 갖는다(AMI를 다시 구울 필요 없음).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
echo "[metrics] node_exporter(9100) + cadvisor(8001)"
docker rm -f node-exporter 2>/dev/null || true
docker run -d --name node-exporter --restart unless-stopped \
--net=host --pid=host \
-v /:/host:ro,rslave \
prom/node-exporter:latest \
--path.rootfs=/host || true
docker rm -f cadvisor 2>/dev/null || true
docker run -d --name cadvisor --restart unless-stopped \
--privileged --device /dev/kmsg \
-p 8001:8080 \
-v /:/rootfs:ro -v /var/run:/var/run:ro -v /sys:/sys:ro \
-v /var/lib/docker/:/var/lib/docker:ro -v /dev/disk/:/dev/disk:ro \
gcr.io/cadvisor/cadvisor:latest || true
세 가지가 포인트였다.
- cAdvisor는 호스트
8001로 매핑(-p 8001:8080) — 백엔드 앱이 이미 호스트8080을 쓰고 있어 그대로 두면 포트 충돌로 cAdvisor가 안 뜬다 || true로 격리 — 이 스크립트 맨 위엔set -euo pipefail이 있어 명령 하나만 실패해도 부팅 전체가 중단된다. exporter(관측)가 깨졌다고 앱 부팅까지 실패하면 안 되므로, exporter 줄만|| true로 감싸 실패를 흡수했다- 배치는 앱 뒤·로그 에이전트 앞 — 관측이 앱보다 먼저 실행돼 앱을 막는 일이 없게
set -e환경에선 “실패해도 되는” 보조 작업은|| true로 감싼다. 관측이 서비스를 죽이면 안 된다는 원칙의 구현이다. (만약 exporter가 안 떠도 Prometheus가 그 타겟을 DOWN으로 잡아 알려주니, 조용히 사라지는 것도 아니다)
ec2_sd로 태그 발견 — 필요한 3가지
① Prometheus ec2_sd 잡
static_configs 대신 ec2_sd_configs로, 태그로 필터한다. 포트가 둘(9100·8001)이라 잡도 둘.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- job_name: backend-node
ec2_sd_configs:
- region: ap-northeast-2
port: 9100
filters:
- name: tag:Name
values: [myton-qa-backend-asg] # 이 태그를 가진 인스턴스만
relabel_configs:
- source_labels: [__meta_ec2_instance_state]
regex: running
action: keep # 종료/중지 인스턴스는 제외
- source_labels: [__meta_ec2_instance_id]
target_label: instance_id # 어느 박스인지 라벨로
- job_name: backend-cadvisor
ec2_sd_configs:
- region: ap-northeast-2
port: 8001
filters:
- name: tag:Name
values: [myton-qa-backend-asg]
relabel_configs:
- source_labels: [__meta_ec2_instance_state]
regex: running
action: keep
② IAM — mon 박스에 ec2:DescribeInstances
ec2_sd는 Prometheus가 EC2 API를 호출해 태그로 인스턴스를 찾는 방식이다. 그 호출 권한이 Prometheus가 도는 mon 박스의 역할에 있어야 한다(자격증명은 IMDS로 가져옴).
1
2
3
{ "Effect": "Allow",
"Action": ["ec2:DescribeInstances", "ec2:DescribeAvailabilityZones"],
"Resource": "*" }
Describe*는 리소스 레벨 제한을 지원하지 않아 Resource: "*"가 강제된다(읽기전용 목록 조회).
③ 백엔드 SG 인바운드
백엔드 SG에 9100·8001을 mon SG에서 오는 것만 허용(IP가 아니라 SG 참조 → 인스턴스 교체에도 유지).
1
2
3
4
5
aws ec2 authorize-security-group-ingress --region ap-northeast-2 \
--group-id <백엔드 SG> \
--ip-permissions \
'IpProtocol=tcp,FromPort=9100,ToPort=9100,UserIdGroupPairs=[{GroupId=<mon SG>}]' \
'IpProtocol=tcp,FromPort=8001,ToPort=8001,UserIdGroupPairs=[{GroupId=<mon SG>}]'
롤아웃 + 자동 복구 검증
user-data를 고친 새 LT 버전을 만들고, ASG가 $Default를 쓰므로 LT default를 새 버전으로 바꾼 뒤 instance refresh로 교체했다(Launch before terminating이라 무중단). 새 인스턴스가 부팅하며 user-data를 돌려 exporter가 떴고 —
백엔드가 1860에 뜬 모습 — 교체로 인스턴스 IP가 10.76.16.118 → 10.76.16.248로 바뀌었는데도, ec2_sd가 태그로 새 인스턴스를 재발견해 타겟이 끊기지 않았다. Uptime이 짧은 걸로 방금 교체된 새 인스턴스임을 알 수 있다.
이게 ec2_sd를 쓴 핵심 이유다. static IP였다면 교체마다
prometheus.yml을 수동으로 고쳐야 했을 것을, 태그 기반 발견이라 설정 변경 0으로 자동 복구된다. 블루그린이 ASG를 새로 만들어 이름이 바뀌어도, 태그만 유지되면 발견이 안 깨진다(그래서 ASG 이름이 아니라 태그로 필터).
남는 것
- 앞으로 CodeDeploy 블루그린 배포가 ASG를 새로 만들어도, LT user-data에 exporter가 구워져 있고 ec2_sd가 태그로 발견하므로 관측은 자동으로 따라온다 — 사람이 손댈 게 없다.
