한 줄 정의
클라우드 시대 인프라는 “하드웨어는 신뢰할 수 없고 모든 것은 변한다”는 전제 위에서, 어떤 구성 요소든 코드로 언제든 다시 만들 수 있게 하여 품질과 신뢰성을 확보하는 다섯 가지 원칙을 따릅니다.
쉽게 말하면
이 장 전체를 관통하는 비유가 ‘반려동물이 아닌 가축(cattle, not pets)’ 입니다. 반려동물은 한 마리 한 마리 이름을 지어 주고, 아프면 정성껏 간호하며, 잃으면 대체할 수 없습니다. 반면 목장의 가축은 모든 개체를 같은 방식으로 기르고, 문제가 생긴 개체는 붙잡고 고치는 대신 무리 전체를 유지하는 쪽으로 대응합니다.
구시대 서버는 반려동물이었습니다. 클라우드 시대 서버는 가축이어야 합니다. 서버 하나에 이름을 붙이고 손으로 어루만지는(수작업 변경) 순간 그 서버는 다시 만들 수 없는 특별한 존재가 되고, 반대로 어떤 개체든 똑같이 다시 만들 수 있게 해 두면 고장·교체·확장이 더 이상 두려운 일이 아니게 됩니다.
왜 중요한가?
클라우드는 컴퓨팅 리소스를 물리 하드웨어에서 분리했습니다. 서버·하드디스크·라우터는 이제 몇 층 몇 번째 랙의 물리 장비가 아니라, 우리가 만들고 복제하고 변경하고 파괴하는 가상의 구조물 입니다.
그런데 구시대의 사고방식(안정적인 하드웨어, 고정된 서버)을 그대로 가져오면 동적 인프라의 장점을 누리기는커녕 스노우플레이크와 구성 드리프트라는 함정에 빠집니다.
이 다섯 원칙은 세 가지 핵심 실행 방법(모든 것을 코드로 정의, 지속적 테스트·딜리버리, 작고 간단한 빌드)을 왜 사용해야 하는지 에 대한 근거입니다.
핵심 내용
원칙 1 — 시스템을 신뢰할 수 없다고 가정한다
퍼블릭 클라우드 규모(수십만 대)에서는 아무리 안정성 높은 하드웨어를 써도 오류가 발생합니다. 게다가 대부분의 클라우드 벤더는 저렴하지만 신뢰성이 떨어지는 하드웨어를 사용하고, 고장이 나면 감지해서 교체하는 방식으로 운영합니다.
장애가 아니더라도 업그레이드·패치·규모 변경·부하 재분배·장애 원인 분석을 위해 시스템 일부를 의도적으로 오프라인으로 만들어야 할 때가 있습니다. 정적 인프라에서 이것은 곧 시스템 중단이고, 오늘날 많은 기업에게 시스템 중단은 비즈니스 중단과 같은 의미입니다.
따라서 인프라를 안정적인 기반으로 보지 말고, 인프라 리소스가 변경될 때 시스템을 중단하지 않아도 되는 서비스를 설계해야 합니다.
원칙 2 — 모든 것은 재생산 가능하다
시스템 구성 요소를 노력하지 않고 안정적으로 언제든 다시 만들 수 있으면 복구 가능한(recoverable) 시스템입니다. ‘노력하지 않고(effortlessly)’ 는 다시 만드는 방법에 대해 어떤 결정도 새로 내릴 필요가 없다는 뜻입니다. 설정·소프트웨어 버전·의존 관계를 코드로 정의해 두면 재생산은 단순한 ‘예/아니오’ 결정이 됩니다.
재생산성은 복구를 쉽게 할 뿐 아니라 다음을 가능하게 합니다.
-
프로덕션과 일치하는 테스트 환경 구성
-
가용성 확보를 위한 리전 간 시스템 복제
-
높은 부하에 대응하는 온디맨드 인스턴스 추가
-
고객에게 전용 인스턴스를 딜리버리하기 위한 시스템 복제
단, 데이터·콘텐츠·로그처럼 사전에 정의할 수 없는 것은 구별해서 백업·복원 같은 복제 전략의 일부로 함께 다뤄야 합니다.
위험: 스노우플레이크 시스템
스노우플레이크(snowflake) 는 다시 빌드하기 어려운 시스템 인스턴스나 시스템의 일부분입니다. 핵심 특징은 팀원들이 그 구성을 완벽하게 이해하지 못한다는 점입니다.
스노우플레이크는 의도적으로 만드는 것이 아니라 자연적으로 생깁니다.
-
새 도구를 배우며 실수한 첫 결과물에 다른 팀원이 의존하기 시작하면, 배운 내용을 반영해 다시 만들 시간이 없어집니다.
-
한 인스턴스에만 적용한 변경(한 시스템에만 나타나는 문제의 해결, 테스트 환경에서만 시작하고 끝난 업그레이드)이 쌓입니다.
시스템을 안전하게 변경하거나 업그레이드할 자신이 없다면 그것이 스노우플레이크라는 신호입니다. 개선할 가치가 없다면 유지할 가치도 없습니다. 교체하는 가장 좋은 방법은 시스템을 복제할 수 있는 코드를 작성하고, 준비될 때까지 신규 시스템을 병렬로 실행하는 것입니다.
원칙 3 — 사라질 수 있는 것으로 만든다
동적 인프라에 ‘대처’할 수 있는 시스템은 레벨 1입니다. 다음 레벨은 시스템 자체가 동적인 것으로, 구성 요소의 추가·삭제·시작·정지·변경·이전을 안전하게 할 수 있어야 합니다. ‘반려동물이 아닌 가축’ 표현이 말하는 처분 가능성(disposability) 이 바로 이 원칙이며, 운영 유연성·가용성·확장성을 확보하고 변경을 단순화하며 위험을 줄입니다.
클라우드 네이티브 소프트웨어 의 주요 아이디어가 이것입니다. 클라우드가 물리 하드웨어인 인프라 리소스(컴퓨팅·네트워킹·스토리지)를 추상화하듯, 클라우드 네이티브 소프트웨어는 애플리케이션 기능을 인프라에서 완전히 분리합니다.
사라진 파일 서버 사건
새로 온 개발자가 팀과 공유할 파일을 호스팅하려고 개발 환경 가상 서버에 수작업으로 HTTP 서버를 띄웠는데, 며칠 뒤 그 가상 서버가 리빌드되면서 통째로 사라졌습니다. 그는 웹 서버를 Chef 코드에 추가하고 파일은 SAN 스토리지에 보관하는 것으로 해결했고, 팀은 오히려 안정적인 파일 공유 서비스를 갖게 되었습니다. 금방 사라질 수 있는(ephemeral) 인프라에 익숙해지는 데는 시간이 걸립니다.
원칙 4 — 다양성을 최소화한다
관리 작업량은 구성 요소의 수 뿐 아니라 구성 요소 종류의 수 에 따라 증가합니다. 완전히 다른 종류의 서버 5대보다 같은 종류의 서버 100대를 관리하는 것이 더 쉽습니다. 재생산성 원칙과 상호 보완적입니다 — 단순한 구조의 컴포넌트를 정의하고 동일한 인스턴스를 많이 생성하면 이해·변경·수리가 쉬워집니다.
시스템에 있을 수 있는 변형은 다음과 같습니다.
| 변형 | 치르는 비용 |
|---|---|
| 다양한 OS·런타임·데이터베이스 | 팀원에게 다양한 기술과 지식 요구 |
| 같은 소프트웨어의 여러 버전 운영 | 버전마다 맞는 설정과 도구 필요 |
| 서버마다 다른 패키지 버전 | 명령어가 일관되게 실행되지 않고, 오래된 버전은 보안 취약점·버그 위험 |
이 원칙이 작동하려면 변경 내용을 컴포넌트의 모든 인스턴스에 적용해야 합니다. 그렇지 않으면 구성 드리프트가 발생합니다.
구성 드리프트
구성 드리프트(configuration drift) 는 한때 동일했던 시스템에 시간이 지나면서 변화(변형)가 생기는 현상입니다. 수작업 변경뿐 아니라, 자동화 도구를 쓰더라도 일부 인스턴스에만 임시 변경을 적용하면 발생하며, 일관된 자동화를 유지하기 어렵게 만듭니다.
가상의 팀 ShopSpinner(고객이 온라인 스토어를 구성·운영하도록 돕는 회사)의 여정이 전형적인 드리프트 시나리오입니다.
-
상점마다 스크립트를 실행해 애플리케이션 서버를 생성하고, 변경이 필요할 때마다 수동 스크립트를 조금씩 수정합니다.
-
트래픽이 훨씬 많은 고객사 Water Works의 서버만 성능 최적화를 적용합니다. 팀이 바빴고 다른 고객사에는 필요 없다고 판단해 다른 시스템에는 적용하지 않습니다.
-
서버 구성 자동화 도구 ServerMaker를 도입해 전 고객사로 확대합니다. 그런데 코드에 Water Works의 최적화 설정이 빠져 있어 자동화가 오히려 개선사항을 삭제해 버립니다. 팀이 실수를 발견할 때까지 Water Works 서버는 매우 느려집니다.
-
코드에 파라미터 를 도입해 고객사마다 리소스 수준만 다르게 설정합니다. 모든 고객사에 동일한 코드를 적용하면서 고객사별 최적화를 양립시킵니다.
자동화에 대한 죽음의 소용돌이
자동화 도구를 가진 팀은 많지만 자동 스케줄로 무인 실행하는 팀은 드뭅니다(DevOpsDays에서 손들기를 시키면 대부분 전자에만 손을 듭니다). 자동화를 선택적으로만 쓰면 다음 악순환에 빠집니다.
graph LR A["자동화 도구 없이<br/>수작업으로 변경한다"] --> B["서버 간에<br/>일관성이 없어진다"] B --> C["자동화를 실행하면 문제가<br/>생길 것 같아 두렵다"] C --> A
탈출하는 가장 효과적인 방법은 두려움에 맞서는 것입니다. 하나의 서버 그룹에서 시작해 인프라 코드를 적용·재적용할 수 있는지 확인한 뒤, 시간 단위로 코드를 계속 적용하는 데몬 프로세스를 예약합니다. 그리고 다음 서버 그룹으로 확대해 모든 서버가 지속적으로 업데이트될 때까지 반복합니다. 좋은 모니터링과 자동화된 테스트가 이 자신감을 뒷받침하고, 드리프트를 빨리 발견해 즉시 수정하게 합니다.
원칙 5 — 어떤 프로세스라도 반복 가능한지 확인한다
재생산 원칙의 연장으로, 인프라에서 처리하는 모든 작업은 반복할 수 있어야 합니다.
함정은 ‘일회성 작업’입니다. 하드 드라이브 파티션 분할 한 번을 위해 스크립트를 작성·테스트하는 것은 fdisk 한 번 실행보다 손이 많이 가므로 수동을 택하기 쉽습니다. 그런데 다른 팀원도 같은 결론으로 수작업을 택하면 — 한 명은 /var를 80GB ext3로, 다른 한 명은 100GB xfs로 — 스스로 구성 드리프트를 만들면서 자동화가 어려운 상황으로 걸어 들어가는 것입니다.
효과적인 인프라 팀은 강한 스크립팅 문화를 가집니다. 스크립트로 작성할 수 있다면 그렇게 하고, 어렵다면 작업을 단순화하거나 조각내서라도 스크립트로 만듭니다. 작업을 스크립트로 쪼개는 과정 자체가 작업을 더 간단하고 깨끗하고 안정적으로 만듭니다.
플로리안 젤마이어(Florian Sellmayr)
문서화할 가치가 있다면 자동화할 가치가 있다.
내 생각
-
“개선할 가치가 없다면 유지할 가치도 없다”는 스노우플레이크 판별 기준으로 바로 쓸 수 있습니다. 어떤 서버나 환경을 변경하기가 두렵다면 이미 스노우플레이크라는 신호이고, 방치가 아니라 코드화·병렬 교체 대상 목록에 올려야 합니다.
-
드리프트의 해법은 ‘복사본 분기’가 아니라 ‘파라미터화’입니다. Water Works 사례처럼 고객·환경별 차이를 코드 사본이나 수작업으로 관리하면 자동화가 개선사항을 지워버립니다. Terraform variables, Helm values처럼 같은 코드에 값만 달리 주입하는 구조가 원칙 2(재생산)와 원칙 4(다양성 최소화)를 동시에 지키는 방법입니다.
-
죽음의 소용돌이 탈출법은 오늘날의 GitOps와 같은 처방입니다. 사람이 가끔 코드를 적용하는 것이 아니라 데몬(파이프라인, ArgoCD 등)이 코드를 지속적으로 적용·동기화하게 만들어, 코드와 실제 상태의 불일치가 쌓일 틈 자체를 없애는 접근입니다.
관련 개념
- Ch01 코드형 인프라란 — 이 원칙들이 근거가 되어 주는 세 가지 핵심 실행 방법