configuration-management

4 개의 포스트

Code Orange: Fail Small is complete. The result is a stronger Cloudflare network (새 탭에서 열림)

Cloudflare는 2025년 말 발생했던 두 차례의 대규모 장애를 계기로 추진한 인프라 회복 탄력성 강화 프로젝트인 'Code Orange: Fail Small'을 성공적으로 마무리했습니다. 이번 프로젝트를 통해 설정 변경의 안정성을 확보하고, 장애 발생 시 영향을 최소화하며, 비상 상황에서의 대응 체계를 전면 개편했습니다. 결과적으로 Cloudflare 네트워크는 잠재적인 문제를 조기에 감지하고 격리함으로써 전 세계 사용자에게 더욱 신뢰할 수 있는 서비스를 제공할 수 있게 되었습니다. ### 안전한 설정 변경을 위한 Snapstone 도입 설정 변경이 네트워크 전체에 즉각적으로 반영되어 발생하던 대규모 장애를 방지하기 위해 새로운 배포 매커니즘을 구축했습니다. * **Snapstone 시스템 개발**: 설정을 패키지화하여 단계적으로 배포하고, 실시간 상태 모니터링을 통해 문제가 감지되면 자동으로 롤백하는 통합 관리 도구를 도입했습니다. * **점진적 배포의 표준화**: 과거에는 팀별로 달랐던 배포 방식을 Snapstone으로 통일하여, 데이터 파일이나 글로벌 제어 플래그 등 모든 유형의 설정 변경에 '상태 기반 점진적 배포(Health-mediated deployment)'를 적용합니다. * **리스크 관리 자동화**: 위험한 설정 패턴이 발견되면 이를 Snapstone 관리 대상으로 즉시 편입시켜, 별도의 추가 작업 없이도 안전한 배포 사이클을 보장받을 수 있습니다. ### 장애 영향력 최소화 및 서비스 세분화 장애가 발생하더라도 서비스 전체가 중단되지 않도록 시스템의 구조적 유연성을 높였습니다. * **Fail Open 및 Fail Stale 구현**: 최신 설정을 읽지 못할 경우 마지막으로 정상 작동했던 설정을 사용(Fail Stale)하거나, 일부 기능을 제한하더라도 트래픽 흐름은 유지(Fail Open)하도록 프로그래밍 모델을 개선했습니다. * **고객 코호트별 세분화**: 서비스 실행 환경을 여러 독립적인 세그먼트로 나누어, 무료 사용자 그룹에 먼저 업데이트를 적용하고 점진적으로 확대하는 방식을 도입했습니다. * **폭발 반경(Blast Radius) 제한**: 특정 서비스(예: Workers 런타임)에서 문제가 발생하더라도 전체 네트워크가 아닌 소수의 특정 세그먼트에만 영향이 국한되도록 설계하여 대규모 장애로 확산되는 것을 차단합니다. ### 비상 접근 권한(Break Glass) 및 사고 관리 체계 개편 인프라 장애로 인해 관리 도구 자체가 마비되는 '자기 의존성' 문제를 해결하기 위해 비상 대응 절차를 강화했습니다. * **백업 인증 경로 확보**: 핵심 Zero Trust 보안 툴이 작동하지 않는 극한 상황에서도 시스템에 접근할 수 있도록 18개 주요 서비스에 대한 별도의 비상 인증 경로와 스크립트를 마련했습니다. * **실전 중심의 대응 훈련**: 200명 이상의 엔지니어가 참여하는 대규모 드릴(Drill)을 통해 비상 상황에서의 대응 속도와 숙련도를 높였습니다. * **고객 소통 강화**: 내부 모니터링 데이터가 외부 공지 시스템으로 신속하고 명확하게 전달될 수 있도록 소통 프로세스를 개선하여 장애 시 고객의 불확실성을 해소합니다. Cloudflare의 이번 개선 작업은 단순한 기술적 수정을 넘어, '작게 실패(Fail Small)'함으로써 더 큰 가용성을 보장하는 구조적 변화를 의미합니다. 사용자는 이제 더욱 견고해진 인프라 위에서 예상치 못한 설정 오류나 시스템 장애로부터 보호받으며 서비스를 이용할 수 있습니다.

You’ve Got (Too Much) Mail: Behind the Scenes of the 3/25/26 Voice Outage (새 탭에서 열림)

2024년 3월 25일, Discord는 일상적인 인프라 설정 변경 중 발생한 실수로 인해 세션 관리 서버의 17%가 동시에 종료되는 대규모 장애를 겪었습니다. 이 사건은 실시간 서비스의 핵심인 세션 시스템의 붕괴가 어떻게 하위 시스템으로 전이되어 음성 및 영상 통화 라우팅 기능을 마비시키는지 보여주는 전형적인 연쇄 장애(Cascading Failure) 사례였습니다. Discord 엔지니어링 팀은 이번 장애를 통해 분산 시스템에서 갑작스러운 부하가 유발하는 병목 현상을 정밀 분석하고, 시스템의 복원력을 높이기 위한 인프라 개선의 계기로 삼았습니다. ### 설정 오류로 인한 세션 관리 서버의 대량 종료 * **장애 발생:** PDT 기준 3월 25일 12:13부터 약 3시간 동안 서비스 성능 저하가 지속되었으며, 사용자들은 통화 연결 시 "Awaiting Endpoint" 메시지와 함께 연결 실패를 경험했습니다. * **근본 원인:** 인프라 설정 업데이트 과정에서 발생한 구성 오류로 인해, Discord 실시간 인프라의 핵심인 세션 관리 서버 중 17%가 일시에 셧다운되었습니다. * **세션의 중요성:** Discord의 세션은 모든 연결된 장치와 서버 간의 상태를 유지하는 '심장 박동'과 같으며, 앱 내에서 사용자가 보고 듣는 거의 모든 활동을 조율하는 필수 구성 요소입니다. ### 하위 시스템으로 전이된 연쇄 장애의 메커니즘 * **병목 현상의 전이:** 대규모 세션 손실은 단순한 서버 중단에 그치지 않고, 하위 시스템인 음성/영상 통화 라우팅 서비스로 막대한 부하를 전달했습니다. * **라우팅 서비스 마비:** 전 세계 사용자들을 적절한 통화 서버로 연결해주는 서비스가 갑작스러운 재연결 요청과 상태 복구 부하를 견디지 못하고 과부하 상태에 빠졌습니다. * **분산 시스템의 취약성:** 분산 환경에서 발생하는 급격한 부하(Sudden load)는 기존의 알려진 병목 지점뿐만 아니라 예상치 못한 새로운 지점의 결함을 찾아내며 시스템 전반을 타격합니다. ### 장애 분석을 통한 시스템 복원력 강화 * **심층 분석:** 사고 이후 팀은 시스템이 연쇄적인 부하 상황에서 왜 제대로 대응하지 못했는지 분석하고, 분산 시스템의 한계를 시험하는 계기로 활용했습니다. * **인프라 레벨업:** 겉보기에 사소한 설정 변경이 여러 단계 떨어진 서비스에까지 영향을 미칠 수 있음을 인지하고, 이를 방어하기 위한 인프라 고도화 작업을 진행 중입니다. * **경험의 자산화:** 장애 상황에서의 실제 데이터를 바탕으로 병목 현상을 해결함으로써, 향후 유사한 대규모 부하 발생 시에도 시스템이 견딜 수 있는 내성을 확보했습니다. 분산 시스템을 운영하는 엔지니어라면 사소한 설정 변경이 가져올 수 있는 연쇄 효과를 항상 경계해야 합니다. 갑작스러운 대량 부하 상황에서도 핵심 기능이 유지될 수 있도록 시스템 간의 격리를 강화하고, 장애 발생 시 부하를 제어할 수 있는 서킷 브레이커나 속도 제한(Rate Limiting) 같은 방어 기제를 인프라 전반에 걸쳐 점검하는 것이 중요합니다.

수천 개의 API/BATCH 서버를 하나의 설정 체계로 관리하기 (새 탭에서 열림)

토스페이먼츠는 수천 개의 API 서버와 배치 설정을 관리하기 위해 설정을 단순한 텍스트가 아닌 '진화하는 코드'로 정의하여 운영합니다. 복사-붙여넣기식의 중복 설정을 제거하기 위해 오버레이 아키텍처와 템플릿 패턴을 도입했으며, 이를 통해 오타나 설정 오류로 인한 대규모 정산 장애 리스크를 원천 차단합니다. 결과적으로 인프라 설정을 테스트 가능한 영역으로 끌어올려 대규모 하이브리드 클라우드 환경에서도 높은 안정성과 유연성을 확보했습니다. ### 실시간 API 서버: 오버레이와 템플릿의 결합 * **오버레이 아키텍처:** 설정을 `global`, `cluster`, `phase`, `application` 순서의 계층형 구조로 설계하여 하위 계층이 상위 계층의 기본값을 덮어쓰도록 구성했습니다. 이를 통해 공통 설정은 한 번만 정의하고 각 환경에 필요한 차이점만 관리할 수 있습니다. * **템플릿 패턴 도입:** YAML의 단순 오버레이만으로는 해결하기 어려운 긴 문자열(예: JVM 옵션) 내의 특정 값만 수정하기 위해 `{{MAX_HEAP}}`과 같은 변수 치환 방식을 사용합니다. * **동적 설정 주입:** 설정 파일 내부에 파이썬 스크립트를 삽입하여 랜덤 포트 생성이나 외부 API 호출을 통한 동적 값 할당이 가능하며, 클러스터 이름에 따른 조건부 로직을 적용해 복잡한 환경 변수 요구사항을 해결합니다. ### 배치 서버: DSL과 GitOps를 통한 단순화 * **Jenkins 기반의 단순화:** 대규모 정산 데이터를 다루는 배치 환경일수록 단순함이 강력하다는 원칙 아래, Jenkins를 활용하면서도 수동 조작의 단점을 보완하는 방향을 택했습니다. * **Groovy DSL 활용:** Jenkins의 웹 UI를 통한 수동 설정을 배제하고, Groovy 기반의 자체 DSL(Domain Specific Language)을 구축하여 수천 개의 배치 Job을 코드 형태로 관리합니다. * **GitOps 체계:** 모든 배치 설정을 코드 저장소에서 관리하고 CI/CD 파이프라인과 통합함으로써, 개발자가 직접 Jenkins에 접속하지 않고도 표준화된 환경에서 배치 작업을 배포할 수 있도록 개선했습니다. ### 인프라의 코드화와 검증 자동화 * **테스트 가능한 설정:** 설정값에 대한 오타나 논리적 오류를 방지하기 위해 설정 코드에 대한 유닛 테스트를 수행합니다. 이를 통해 수천 개의 설정 중 단 하나의 오타가 치명적인 금융 장애로 이어지는 것을 사전에 방지합니다. * **유연한 확장성:** 고정된 설정 체계에 안주하지 않고, 인프라의 변화와 개발자의 요구사항에 맞춰 설정 인프라 자체가 계속해서 진화할 수 있는 구조를 지향합니다. 단순히 설정 파일을 잘 작성하는 것에 그치지 않고, 인프라 설정을 애플리케이션 코드와 동일한 수준의 설계와 테스트를 거쳐 관리하는 것이 대규모 시스템의 안정성을 보장하는 핵심입니다. 초기에 다소 복잡해 보일 수 있는 오버레이나 DSL 도입은 장기적으로 중복을 제거하고 휴먼 에러를 막는 가장 확실한 투자입니다.

데이터독에서의 Consul (새 탭에서 열림)

Datadog은 지난 18개월간 마이크로서비스 아키텍처의 구성 정보 배포와 서비스 디스커버리를 위해 Consul을 핵심 기술로 활용해 왔습니다. Consul 클러스터의 안정성을 유지하기 위해서는 Raft 합의 알고리즘을 뒷받침할 충분한 CPU 자원 확보와 dnsmasq를 활용한 쿼리 부하 분산이 필수적이며, 모든 변경 사항은 감사 가능한 구조로 관리해야 합니다. **Consul 서버의 CPU 리소스 확보** * Consul 서버는 Raft 프로토콜을 통해 리더를 선출하며, 500ms 동안 리더의 응답이 없으면 새로운 리더 선출 과정(leadership transition)이 시작됩니다. * 빈번한 리더 교체는 시스템 불안정의 신호이므로, 시간당 1회 이상 발생한다면 서버의 CPU 성능을 높여야 합니다. * 에이전트 노드 수에 따른 권장 사양은 300대 기준 m3.large, 500대 기준 c3.xlarge, 800대 기준 c3.2xlarge 수준입니다. **감사 가능한 구성 변경 관리** * Consul의 KV(Key-Value) 스토리지에 데이터를 직접 저장할 경우 변경 이력을 추적하기 어렵다는 위험이 있습니다. * Datadog은 git2consul을 사용하여 Git 저장소의 내용을 Consul에 동기화함으로써, 누가 언제 무엇을 변경했는지에 대한 감사 추적(Audit trail)을 유지합니다. * 이를 통해 클러스터 전체의 구성 변경을 60초 이내에 안전하고 신속하게 수행합니다. **ACL과 Watch를 이용한 부하 및 보안 관리** * ACL(Access Control List) 기능을 활용하여 권한이 있는 프로세스만 데이터를 수정하도록 제한하고, 실수로 인한 데이터 삭제 범위를 국소화해야 합니다. * Consul은 Redis처럼 초당 수십만 건의 읽기/쓰기를 처리하도록 설계되지 않았으므로, 변경 사항을 효율적으로 감지하기 위해 'Watch' 기능을 활용해야 합니다. * 다만 Watch가 예기치 않게 과도하게 실행되는 것을 방지하기 위해 sifter와 같은 도구를 병용하는 것이 좋습니다. **dnsmasq를 통한 DNS 부하 경감** * 서비스 디스커버리를 위해 Consul DNS 인터페이스를 직접 쿼리하면 부하가 집중될 수 있으므로, 각 노드에 dnsmasq를 설치하여 캐시 레이어로 활용해야 합니다. * Consul의 DNS TTL을 짧게(예: 10초) 설정하고, dnsmasq가 먼저 요청을 처리한 뒤 모르는 정보만 Consul에 묻도록 구성합니다. * 매우 높은 트래픽 환경에서는 Consul 데이터를 로컬 호스트 파일로 캐싱하여 dnsmasq에 로드함으로써, Consul 직접 쿼리 수를 초당 400건 수준으로 유지하면서도 전체 DNS 요청은 초당 10만 건 이상 처리할 수 있습니다. **Consul 모니터링 필수 지표** * 리더 선출 상태를 확인하는 `consul.consul.leader.reconcile.count`와 리더 교체 주기를 알 수 있는 `consul.serf.events.consul_new_leader`를 모니터링해야 합니다. * 리더와의 마지막 통신 시간을 나타내는 `consul.raft.leader.lastContact`와 Consul로 직접 들어오는 DNS 쿼리 양도 주요 관찰 대상입니다. * 서버 노드의 CPU와 네트워크 사용량을 실시간으로 추적하여 인프라 병목 현상을 사전에 방지해야 합니다. 성공적인 Consul 운영을 위해서는 단순히 설치하는 것에 그치지 않고, 인프라 규모에 맞는 적절한 CPU 사양 선택과 캐싱 전략을 통한 부하 관리가 선행되어야 합니다. 특히 설정값 관리에 있어서는 git2consul과 ACL을 결합하여 보안과 이력 관리라는 두 마리 토끼를 모두 잡는 방식을 추천합니다.