AWS Cloud School 13기 110일차
2026-06-09
Today
- ✅ dev 인프라 apply 완료 확인 → Backend
deploy-dev job 작성·머지 — dev 환경 terraform apply 완료 확인 후 Backend/.github/workflows/deploy.yml에 Job 4(deploy-dev) 추가(needs: push-image, if: ref_name==feat, dev-app taskdef render → dev-app-service/dev-cluster 배포 + wait-for-stability + Slack). 커밋 c8291aa → PR #37 템플릿대로 작성 → 머지. Backend prod·dev 양환경 자동배포 가동
- ✅ IAM 설계서 최신화 — dev apply로 실제 생성된 IAM 역할 파악(신규 5개) 반영. §1 네이밍 컨벤션, §2.2 ECS 역할(생성완료), §2.3 scheduler 역할, §2.4 향상된 모니터링(Enhanced Monitoring) 역할 정리. 📍 문서 영역 헤더 추가
- ✅ ADR 2건 작성 — ADR-013(Terraform CI/CD 전략 — 보류, ECS→EKS 모더나이제이션 시 재개) · ADR-014(dev 야간종료 스케줄러 — EventBridge Scheduler→Lambda→ECS). 인덱스 갱신
- ✅ 설계서 전수조사 + 📍영역 헤더 일괄 부여 — 모니터링·보안·WAF·CICD·아키텍처 등 전 설계서에 "문서 영역" 헤더로 스코프 분리(CI/CD 문서는 CI/CD만, 모니터링은 분리). stale 값 정정(autoscaling·branch protection·Multi-AZ 등)
- ✅ DMS 마이그레이션 실시간 모니터링 구축 — CloudWatch 대시보드
farmily-dms-migration(적재활동·사용스토리지 게이지·연결지연·relay전송·bastion CPU·DMS 로그 위젯). 위젯별 역할 표 + Metric Math 게이지(21474836480 - FreeStorageSpace). 모니터링 설계서 §11에 반영
- ✅ DMS Full Load 성공 + 트러블슈팅 문서화 — 초기 반복 FAILED(소스
dms_user 인증 / publication 권한 / 타겟 logical_replication 미설정) 로그 분석·해결 → Full Load 100%(24테이블)·CDC(REPLICATION) 진입, prod-rds ~1.45GB 적재, WriteIOPS 피크 321(gp2 버스트). 트러블슈팅 노트 작성
- ✅ 블로그 2편 — 모니터링 1편(DMS Migration Project + CloudWatch 보조 관측, gp2 IOPS 실측, 지표 용어 풀이) · CICD 7편(dev 자동배포·야간종료). velog 발행 블록·이미지 placeholder 포함
- ✅ DMS 아키텍처 다이어그램(
Farmily-DMS-Architecture.drawio, 바탕화면) — 온프렘 PostgreSQL(540만행) → Tailscale(mesh VPN) → bastion relay → DMS Migration Project → prod-rds → CloudWatch. AWS 공식 아이콘 + PostgreSQL·Tailscale 로고 base64 임베드
- ✅ 채용공고 매핑 + 멘토 질문 정리 — 이 프로젝트에서 얻을 직무 역량(IAM·CI/CD·모니터링·SRE)을 채용공고 요구와 연결. AWS 직원 멘토에게 물을 질문 리스트
- ✅ 스케줄러 부하 모니터링 설계(
SCHEDULER_SCALE_ISSUES.pdf 대응) — 모니터링 설계서 §3.1에 "운영 배치 스케줄러 부하 모니터링" 소절 신설. 앱 배치 3건 위험 → 인프라 관측 신호 매핑 + EventBridge OOM 규칙(비용0) + 중복발화 가시화
Notes
모니터링 — PDF 위험 3건 대응 요약
- ① FCM 18시 루프 →
rds-connections-high(기존 재활용) / ② 크레딧 리셋 OOM → ecs-memory-high(추세) + EventBridge OOM 이벤트(신규·비용0) / ③ 정기결제 → 로그 메트릭 필터(앱 협조)
- 공통 중복발화 → 발화시각
RunningTaskCount 대시보드 오버레이
Learned
- DMS는 클래식 vs 신형(Migration Project)으로 조회 API가 다르다 — 신형은
describe-migration-projects·describe-data-migrations. 클래식 API(describe-replication-tasks)로 보면 빈 결과라 "DMS 안 쓰나?" 착각하기 쉽다(실제로 그렇게 헤맸음). 도구의 변형(버전)을 먼저 확인해야 함
- gp2 스토리지는 IOPS가 먼저 천장을 친다 — 20GB gp2 = baseline ~60 IOPS(3 IOPS/GB) + 버스트 3000 크레딧. 대량 적재 시 버스트 소진되면 WriteIOPS 천장·WriteLatency 급등 → gp3(baseline 3000) 전환 분기점. 마이그레이션 = 용량 산정 기회
- WriteIOPS(횟수) ≠ WriteThroughput(데이터양) — 작은 행을 여러 번 쓰면 IOPS는 높은데 Throughput은 낮을 수 있다. gp2 한계가 IOPS 기준이라 둘을 같이 본다
- OOM은 메트릭 알람이 아니라 EventBridge 이벤트로 잡는 게 정확 — OOM은 "임계 초과 추세"가 아니라 이미 죽은 사건. 메트릭 알람(평균%)은 task가 죽으면 메트릭이 끊겨 놓치지만,
ECS Task State Change+stoppedReason *OutOfMemory* 이벤트는 죽음 자체를 포착. Container Insights 없이 비용 0으로 가능
- Container Insights 의존 메트릭의 함정 —
RunningTaskCount·EphemeralStorageUtilized는 ECS/ContainerInsights 네임스페이스라 Insights를 켜야 나온다. 꺼져 있으면 알람을 만들어도 INSUFFICIENT_DATA로 침묵. 서비스 다운은 ALB HealthyHostCount(기본 AWS/ApplicationELB)로 대체 감지 가능
@Scheduled는 다중 인스턴스에서 인스턴스 수만큼 발화 — Fargate가 scale-out되면 각 태스크가 독립적으로 배치를 실행 → 결제 같은 건 이중 실행. 해결 = 분산 락(ShedLock). 인프라 측에서는 "발화 시각의 태스크 수"를 모니터링
Container Insights가 뭔가 — ECS/EKS의 "컨테이너 레벨" 관측을 자동 수집하는 CloudWatch 기능. 기본 AWS/ECS는 서비스 평균 CPU/Mem %만 주지만, Insights는 task·container 단위(MemoryUtilized 절대값MiB, RunningTaskCount, EphemeralStorage, 네트워크)를 준다. Fargate는 에이전트 불필요 — 클러스터 setting 한 줄(containerInsights=enabled)이면 플랫폼이 emit(EC2 ECS는 CloudWatch agent 필요). 비유: 기본=건물 전체 평균 전력, Insights=방마다 계량기
- 켜는 법 = Terraform
setting 블록 한 줄 — aws_ecs_cluster에 setting { name="containerInsights" value="enabled" }. 클러스터 재생성 아닌 in-place 변경. CLI(update-cluster-settings)로도 켜지지만 state drift → 다음 apply가 도로 끔. 반드시 코드로
- 코드에
setting이 없으면 기본 disabled — 실제 modules/ecs/main.tf는 name만 있어 Container Insights 기본 꺼짐. 실측(describe-clusters)과 코드가 일치하면 drift 없음. "끄려고 끈 게 아니라 명시 안 해서 기본값"
- 안 켜는 게 합리적일 때가 있다(FinOps) — Insights는 커스텀 메트릭 과금 + 클러스터 코드 수정(소유권 조율). prod 1~8 task 소규모 + per-task 정밀이 아직 불필요하면,
HealthyHostCount 근사 + EventBridge OOM(비용0)으로 우회하고 EKS 전환 때 켜는 게 비용 합리적. "안 켠 이유"를 설명할 수 있는 게 곧 판단력
- 앱 위험을 인프라 신호로 "번역"하는 게 모니터링의 본질 — 앱 코드를 못 고쳐도, FCM 대량루프 → RDS 커넥션 급증, 크레딧 리셋 OOM → ECS Memory% + OOM 이벤트, 결제 중복 → 로그 카운트, 중복발화 → HealthyHost 수로 관측 가능. 위험을 메트릭/이벤트/로그 3종으로 분해하는 사고
- 태스크 수는
ALB HealthyHostCount로 근사 가능 — RunningTaskCount(Insights 의존)가 없어도 정상 타겟 수 = 떠 있는 태스크 수에 근사. 기본 AWS/ApplicationELB 네임스페이스라 Insights 불필요
- CloudWatch 대시보드는 "매일 N시 자동 세로선"을 못 그린다 — 발화 시각 표시가 안 되므로 Timezone=Local + 1일 뷰로 두고 그 시각 스파이크를 눈으로 본다. 자동 세로선·자유 배치가 필요하면 Grafana 승격(멘토 우선순위). 단 비용·운영부담 → 부하테스트 멀티소스 단계까지는 CloudWatch로 충분
- RDS 메트릭은
Per-Database Metrics 경로로 들어가야 dimension이 붙는다 — 메트릭을 그냥 검색해 넣으면 DBInstanceIdentifier가 안 붙어 빈 그래프. RDS → Per-Database Metrics → prod-rds 경로로 선택(DMS 대시보드에서 겪은 함정과 동일)
Prompt(회고)
- 클래식 DMS API(
describe-replication-tasks)가 비어 있는 것만 보고 "DMS 안 쓴다"고 단정했다가, "Migration project farmily-migration 이건 뭐야"라고 짚어줘서 신형 Migration Project임을 알았다. 빈 결과 = 미사용이 아니라 다른 API로 봐야 하는 경우일 수 있다. 도구는 버전·변형을 먼저 확인.
- prod task가 평소 1개라 중복발화(Defect B)가 "안 보이는데", 이걸 "위험 없음"으로 넘기지 않은 게 맞았다. "지금 안 보임 ≠ 위험 없음" — Auto Scaling이 도는 순간 발현한다. 실측 1대에 안심하지 말고 scale-out 시나리오를 가정해 모니터링을 설계.
- 모니터링 설계 시 "새 알람을 잔뜩 만들자"가 아니라 기존 알람(rds-connections·ecs-memory)으로 이미 덮이는 부분을 먼저 빼고, 진짜 신규(OOM 이벤트 1개 + 중복발화 가시화)만 남겼다. 중복 알람은 노이즈만 늘린다.
- 옆에서 VMware에서 ECS 상으로 DMS를 통해 마이그레이션을 진행하는 상황을 옆에서 같이 도와주면서 느낀점이 있다. 마이그레이션이라는 작업 자체가 쉽지 않고 같은 PostgreSQL -> PostgreSQL로 옮기는 작업인데도 이렇게 설정할께 많고 어려웠다. 이기종이었다면 AWS SCT를 쓰면서 더 오래걸리고 어려웠을꺼 같다는 생각이 계속 작업을 도와주면서 느꼈다.