Repository navigation
Infrastructure Case Studies
운영 엔지니어 관점에서 설명하기 좋은 사례를 문제 -> 설계 -> 검증 순서로 모았습니다.
문제. 인프라 도구가 DB를 만들어도 관제 시스템 등록이 사람의 후속 작업이면 누락과 입력 오류가 생깁니다.
설계. 모든 환경의 종점을 멱등 PUT /api/instances로 통일했습니다. Kubernetes는 CloudNativePG의 app Secret을 등록 Job이 읽고, VM은 Ansible이 최소 권한 계정을 만든 뒤 등록하며, Terraform은 RDS endpoint를 등록 입력으로 연결합니다.
검증. kind에서 Cluster CR -> Pod·Service·PVC·Secret -> Job -> PostgreSQL 16.4 health up을 완주했습니다. Ansible은 두 번째 실행이 changed=0, Terraform은 OpenTofu와 AWS provider schema validate까지 확인했습니다.
판단. 실제 AWS apply는 과금과 자격증명이 필요해 실행하지 않았으며, K8s·Ansible E2E와 같은 수준으로 표현하지 않습니다.
문제. 전역 ShedLock 하나를 사용하면 앱 노드를 늘려도 한 노드만 수집해 수평 확장이 되지 않습니다.
설계. instanceId % shardCount로 대상을 나누고 샤드마다 분산 잠금을 획득하게 했습니다. 한 노드만 남으면 모든 샤드를 획득하므로 별도 리밸런서 없이 페일오버합니다. 세션과 로그인 실패 횟수는 메타 DB에 저장해 노드 이동에도 유지합니다.
검증. 같은 메타 DB를 보는 앱 A·B와 샤드 4개를 실행했습니다. A 종료 후 다음 틱에 B가 네 샤드를 모두 인수했고, 같은 세션 쿠키로 재로그인 없이 GET /api/me가 성공했습니다.
트레이드오프. 샤드 수 변경은 모든 노드에 동시에 적용해야 합니다. 누적 카운터 차분 구조라 담당 노드가 바뀌어도 수집 데이터는 이어집니다.
문제. 최대 볼륨 테이블은 5개 대상만으로 하루 약 72만 행이 쌓일 수 있습니다. 200만 행 벌크 DELETE는 1,879.9 ms가 걸리고 VACUUM 뒤에도 테이블이 404 MB로 남았습니다.
설계. 월별 RANGE 파티션과 DEFAULT 안전망을 만들고, 다음 달 파티션을 미리 생성합니다. 월 전체가 보존 기한을 지나면 DELETE 대신 파티션을 DROP합니다. 경계 월만 파티션 프루닝을 이용해 DELETE합니다.
검증. 같은 200만 행의 만료 파티션 DROP은 12.8 ms로 147배 빨랐고 블로트가 남지 않았습니다. 하루 범위 EXPLAIN은 해당 월 파티션 하나만 스캔했습니다.
보호 장치. 이름 규약 밖의 자식과 DEFAULT 파티션은 자동 삭제하지 않으며, H2나 전환 전 스키마에서는 기존 DELETE로 폴백합니다.
문제. 수집을 끈 대상에도 minimumIdle=1과 SLO 폴러 때문에 커넥션 하나가 계속 남았습니다. 대상이 수백 대면 관제 시스템이 서비스용 연결 슬롯을 상시 점유합니다.
설계. minimumIdle=0, 수집 주기보다 긴 idle timeout 하한, 장기 미사용 풀 LRU 제거를 적용했습니다. 격리 대상은 SLO 폴러도 건너뛰며 그 기간의 가용성을 DOWN으로 만들지 않습니다.
검증. 격리 전 활성 연결 1개, 격리와 유휴 풀 정리 뒤 0개, 격리 해제 뒤 다음 수집 틱에서 풀 재생성과 수집 재개를 확인했습니다.
문제. 암호화 저장을 해도 정적 DB 비밀번호가 유출되면 사람이 회전할 때까지 유효합니다.
설계. vault:database/creds/<role> 형식의 대상은 접속 시 Vault database secrets engine에서 수명 있는 계정을 받습니다. 리스 80% 시점에 선제 갱신하고 계정 변경을 감지하면 커넥션 풀을 교체합니다. 허용 경로는 database credentials mount로 제한합니다.
검증. Vault dev와 PostgreSQL을 연결해 TTL 2분 계정으로 등록부터 health까지 수행했습니다. 선제 갱신 뒤 새 계정과 풀이 사용되고 이전 계정이 DB에서 사라지는 것을 확인했습니다.
한계. 이 경로는 JDBC 풀에 적용됩니다. 외부 백업 CLI는 별도의 제한된 백업 계정을 사용합니다.
문제. 역할별 UI 테스트는 환경변수가 없으면 건너뛰도록 되어 있어, 설정 실수 시 테스트 단계가 초록이어도 브라우저 검증은 0건일 수 있습니다.
설계. CI에서 Playwright Chromium을 설치하고 E2E 플래그를 켠 뒤, JUnit XML의 skipped="0"을 다시 검사합니다. 실패하면 HTML 테스트 리포트를 artifact로 올립니다.
검증. 권한별 화면을 실제 브라우저로 눌러 안내 레이아웃과 UTC 표시 결함을 발견했고 같은 흐름을 CI에 고정했습니다.
| 사례 | VERIFICATION 절 |
|---|---|
| Kubernetes·Ansible·Terraform | 43~45 |
| 컨테이너와 GHCR 릴리스 | 52 |
| 수집 샤딩과 페일오버 | 80 |
| 파티셔닝 | 81 |
| 커넥션 온디맨드 | 82 |
| Vault 동적 계정 | 89 |
| 역할별 브라우저 E2E | 136~137 |
DBTower 저장소 · 문서 안내 · 이슈