cloud-init

1 개의 포스트

slack3분 읽기큐레이션 요약

셰프 인프라 개선: 방해받지 않는 안전

Slack은 Chef Policyfiles로 전환하는 대신, 기존 cookbook과 role을 유지하면서 EC2 프로비저닝 구조를 개선하는 방식을 선택했다. 단일 프로덕션 환경을 `prod-1`부터 `prod-6`까지 분리하고, 카나리와 단계적 릴리스 트레인을 도입해 잘못된 변경의 영향 범위를 줄였다. 그 결과 대규모 확장이나 배포 중에도 문제를 조기에 발견하고 안전하게 롤백·수정할 수 있는 경로를 마련했다. ## Policyfiles 대신 기존 구조 개선 - Policyfiles를 도입하면 roles와 environments를 대체하고 여러 팀의 cookbook을 수정해야 했다. - 장기적으로는 안전성이 높아질 수 있지만, 단기적으로는 수십 개 팀의 대규모 작업과 새로운 변경 위험이 발생했다. - Slack은 기존 cookbook과 role을 변경하지 않고 EC2 프레임워크를 보강하는 방향을 택했다. ## 단일 프로덕션 환경의 위험 - 기존에는 모든 인스턴스가 하나의 `production` Chef environment를 공유했다. - 인스턴스별 cron 작업을 가용 영역(AZ)마다 분산해 Chef 실행 시점을 staggered 방식으로 조정했다. - 이 방식은 잘못된 변경이 전체 노드에 동시에 적용되는 것을 막아 주었지만, 새로 생성된 노드는 즉시 최신 변경을 가져갔다. - 따라서 대규모 scale-out 중 잘못된 cookbook 버전이 수십~수백 개의 새 노드에 한꺼번에 적용될 수 있었다. ## `prod-1`~`prod-6` 환경 분리 - 단일 production environment를 다음과 같이 6개 bucket으로 나눴다. - `prod-1` - `prod-2` - `prod-3` - `prod-4` - `prod-5` - `prod-6` - 서비스 팀은 계속 인스턴스를 “prod”로 실행하지만, 실제 Chef environment는 인스턴스의 AZ에 따라 결정된다. - 노드가 여러 환경에 균등하게 분산되므로 하나의 변경이 전체 프로덕션에 미치는 blast radius가 줄어든다. - 각 environment를 독립적으로 업데이트할 수 있어 특정 AZ 그룹만 대상으로 변경을 검증할 수 있다. ## Poptart Bootstrap의 역할 - Slack의 기본 AMI에는 부팅 시 실행되는 `Poptart Bootstrap` 도구가 포함되어 있다. - 주요 역할은 다음과 같다. - Chef node object 생성 - 필요한 DNS 레코드 설정 - 부팅 성공·실패 결과를 Slack 채널에 알림 - 환경 분리를 위해 노드의 AZ ID를 검사하고 해당 노드를 `prod-1`~`prod-6` 중 하나에 자동 배정하도록 확장했다. - 서비스 팀이 별도의 프로비저닝 방식을 학습하거나 cookbook을 수정하지 않아도 인프라 구조 변경을 적용할 수 있었다. ## 카나리 환경 `prod-1` - `prod-1`은 카나리 프로덕션 환경으로 사용된다. - 새 cookbook 변경이 있으면 매시간 최신 버전을 배포한다. - sandbox와 dev를 거친 변경을 실제 프로덕션 환경에서 작은 규모로 먼저 실행한다. - 모든 production 환경을 통과한 뒤에야 테스트하는 방식보다, 변경이 도입된 시점과 장애 발생 시점의 거리가 짧아 원인 추적이 쉽다. - 누적된 대규모 변경이 아니라 비교적 작은 단위의 artifact를 검증할 수 있다. ## `prod-2`~`prod-6`의 릴리스 트레인 - `prod-2`부터 `prod-6`까지는 순차적인 release train 방식으로 업데이트된다. - 새 버전을 `prod-2`에 배포하기 전, 기존 버전이 `prod-2`에서 `prod-6`까지 성공적으로 진행됐는지 확인한다. - 각 환경의 배포가 완료되어야 다음 단계가 진행되므로 회귀 문제가 전체 프로덕션으로 확산되는 것을 방지한다. - 여러 production environment가 항상 일정한 버전 순서를 유지하도록 설계되어 있다. ## 시간 기반 배포 흐름 - 매시 정각에 최신 cookbook 변경을 sandbox에 반영한다. - 이후 Kubernetes CronJob이 dev 환경으로 변경을 진행한다. - 매시 30분부터 production rollout이 시작된다. - 예를 들어 artifact A가 생성되면: - 정각: sandbox와 dev가 A로 업데이트 - 30분: `prod-1`이 A를 받아 카나리 테스트 - 이후: `prod-2`부터 `prod-6`까지 단계적으로 A를 적용 - 그 사이 새 변경으로 artifact B, C가 생성되더라도 기존 릴리스 트레인의 진행 상태를 고려해 순차적으로 배포한다. 실용적으로는 기존 배포 시스템을 전면 교체하기보다, 환경 분리·카나리·단계적 rollout처럼 변경의 영향 범위를 줄이는 장치를 먼저 도입하는 것이 효과적이다. 특히 대규모 인프라에서는 새 노드가 어떤 버전을 자동으로 받는지와, 실패한 변경이 어디까지 확산될 수 있는지를 별도로 통제해야 한다.

원문 읽기(새 탭에서 열림)