- Slack은 장기 실행 EC2를 계속 수정하던 기존 방식에서 불변 AMI 기반 교체 배포로 전환해, 컨테이너로 옮기기 어려운 워크로드에도 현대적인 배포 방식을 적용함
- 공통 기반 이미지인 slack-zero 위에 서비스별 이미지를 쌓고, 무거운 구성은 이미지 베이킹에서 처리하며 환경별 비밀정보와 메타데이터만 부팅 시 적용함
- 배포 오케스트레이터 Gondola는 AMI와 버전이 지정된 Chef 아티팩트를 하나의 배포 단위로 관리하고, 지표 기반 단계적 배포·중단·자동 롤백을 수행함
- Peekaboo는 전체 EC2 인벤토리를 거의 실시간으로 제공하고, The Reaper는 오염되거나 수명이 지난 인스턴스를 속도 제한과 일시정지 장치 아래 교체함
- 단기 실행 서비스에는 효과적이지만 데이터 노드, GitHub Enterprise, Atlassian JIRA처럼 빠르게 교체할 수 없는 장기 실행 인스턴스에는 별도의 패치 방식과 배포 실행기가 필요함
지속적으로 수정하는 EC2 모델의 한계
- Slack은 기존 단일 Chef 스택을 복원력 있는 다중 스택 구조로 바꾸고, 버전이 지정된 cookbook 배포와 안전한 승격 절차를 도입해 수만 대의 EC2 인스턴스에 대한 신뢰성과 운영 통제력을 높였음
- 관련 과정은 Advancing Our Chef Infrastructure에서 확인할 수 있음
- 이후 분할된 프로덕션 환경, 신호 기반 Chef 실행, 개선된 롤아웃 방식을 도입해 팀이 cookbook을 다시 작성하지 않고도 장애의 영향 범위를 크게 줄였음
- Safety Without Disruption 단계에서는 레거시 플랫폼을 안정적으로 유지하면서 향후 구조를 계획할 여유를 확보함
- 그러나 장기 실행 인스턴스를 계속 업데이트하는 모델은 서비스 단위 배포가 어렵고 인프라 드리프트를 피할 수 없으며, 여러 계층의 변경을 조율할수록 복잡해졌음
- 컨테이너가 일부 워크로드의 문제를 해결했지만 모든 시스템을 쉽게 이전할 수는 없어, 불변성·단계적 배포·자동 안전장치를 EC2에 직접 적용할 플랫폼이 필요했음
Shipyard가 제공하는 EC2 운영 모델
- Shipyard는 인프라를 계속 수정할 인스턴스가 아니라 배포 가능한 아티팩트로 취급하는 Slack의 차세대 EC2 플랫폼임
- 서비스 단위 배포 기능을 빌드·오케스트레이션 시스템과 결합해, 애플리케이션 배포 플랫폼과 같은 수준의 안전성과 예측 가능성을 EC2 업데이트에 적용함
-
여러 아키텍처와 운영체제 지원
- AMD64와 ARM 기반 Graviton을 비롯한 여러 CPU 아키텍처를 지원하며 Ubuntu, RHEL, Amazon Linux를 사용할 수 있음
- 팀은 별도 플랫폼 구현 없이 비용·성능·호환성에 따라 인스턴스와 운영체제를 선택할 수 있음
- 특히 컨테이너로 이전하기 어려운 인프라 구성요소, Kubernetes 워커 노드, egress 네트워크 스택에 적합함
-
지표 기반의 안전한 배포
- 각 서비스는 Gondola와 통합돼 지표 기반 자동 안전 검사를 포함한 단계적 롤아웃을 실행함
- 서비스 상태 신호에 따라 배포를 자동 중단하거나 이전의 정상 버전으로 자동 롤백할 수 있음
-
빠르고 예측 가능한 프로비저닝
- 컨테이너와 유사한 계층형 이미지 구조를 사용해 공통 골든 기반 이미지 위에 서비스별 이미지를 구축함
- 실행 시 수행할 작업을 줄여 여러 리전에서 인스턴스가 빠르고 일관되게 가동됨
-
단순화된 구성 관리
- 과거에는 예약된 Chef 작업이 구성을 주기적으로 검사하고 다시 적용해 수동 변경이나 예상 밖의 변경을 원하는 상태로 되돌렸음
- Shipyard에서는 이미지 베이킹과 초기 프로비저닝처럼 명확한 생명주기 단계에서만 구성을 적용함
- 구성 관리 도구는 전체 시스템을 계속 수정하기보다 주로 서비스를 배포하는 데 활용됨
- 이에 따라 백그라운드 부하와 의도하지 않은 덮어쓰기가 줄고, 인스턴스가 시간에 따라 계속 변하지 않아 동작을 추론하기 쉬워짐
-
수명이 제한된 인스턴스
- 각 인스턴스에 제한된 수명을 부여하고 정기적으로 자동 교체함
- 잠재적 취약점이 문제를 일으킬 수 있는 시간을 줄이고, 팀이 실행 중인 인스턴스를 수정하는 대신 교체하도록 유도함
Peekaboo 인벤토리와 전체 플릿 가시성
- Peekaboo는 Chef Server 대신 클라우드 이벤트와 인스턴스 메타데이터를 이용해 EC2 플릿 상태를 거의 실시간으로 보여주는 인벤토리 시스템임
- Shipyard 외부에서 배포된 인스턴스도 추적해 전체 플릿을 한곳에서 확인할 수 있음
- AWS EventBridge, OpenSearch, Lambda로 구축됐으며 다음 인터페이스를 제공함
- 플릿 탐색용 UI
- 시스템 통합용 API
- 빠른 명령줄 확인을 위한 CLI
- EC2 정보를 중앙화해 환경 전반의 원격 측정과 관리 지점을 단일화함
slack-zero 골든 기반 이미지
- slack-zero는 Compute Platform Team이 만들고 보안·모니터링 팀과 공동 관리하는 공통 머신 이미지임
- 모든 서비스가 상속하는 표준화되고 신뢰할 수 있는 기반이며, 서비스 팀은 그 위에서 자체 런타임 환경을 구성함
- 이미지에는 다음 요소가 포함됨
- 운영체제 기준선과 보안 강화 설정
- 네트워킹과 서비스 디스커버리 구성
- 모니터링 및 보안 에이전트
- 공통 도구와 기반 시스템 구성
- 기반 이미지는 불변이면서 일시적인 대상으로 취급됨
- 보안 패치, 모니터링 업데이트, 네트워킹 개선이 필요하면 새 slack-zero 이미지를 만듦
- 하위 서비스 이미지는 새 기반 위에서 다시 빌드해 수정 사항을 상속함
-
AWS Image Builder를 선택한 이유
- slack-zero는 이전의 Packer 대신 AWS Image Builder로 구축함
- 생명주기 정책이 오래된 AMI를 자동 정리해 저장 비용을 줄임
- 새 이미지가 생성될 때 계정별 최신 AMI를 가리키는 AWS Systems Manager(SSM) 파라미터를 갱신하며, 서비스 파이프라인은 이를 읽어 최신 기반을 사용함
- 이미지 베이킹이 성공하면 EventBridge와 Lambda가 서비스 소유자 계정의 하위 파이프라인을 자동으로 시작함
- AMI를 게시하기 전 임시 인스턴스에서 검증 테스트를 실행해 프로덕션 롤아웃 위험을 줄임
서비스 이미지의 베이킹과 프로비저닝
- 각 서비스 팀은 slack-zero를 기반으로 자체 AMI를 만들며, 공통 플랫폼 구성요소를 상속하면서 런타임 환경을 통제함
- 서비스 이미지 파이프라인은 다음 항목을 정의함
- 설치할 소프트웨어
- 서비스 구성 방식
- 해당 서비스의 인스턴스 초기화 절차
- 대부분의 구성을 이미지에 포함해 실행 속도와 일관성을 높이고 구성 드리프트를 최소화함
-
두 단계의 역할 분리
- 베이킹 단계에서는 패키지와 환경 간에 공통인 구성을 설치해, 인스턴스가 실행 전부터 대부분 준비된 정상 상태를 갖추도록 함
- 프로비저닝 단계에서는 부팅 시 비밀정보, 리전별 구성, 배포 메타데이터처럼 환경에 종속된 설정만 적용함
- 일반적으로 구성 파일 배치, 비밀정보 조회, 서비스 시작만 수행함
- 패키지 설치 같은 무거운 작업을 베이킹으로 옮겨 인스턴스가 수 분이 아닌 수 초 안에 가동될 수 있음
- 빠른 시작은 확장 이벤트, 순차 배포, 자동 인스턴스 교체에 중요하며 최소 프로비저닝은 런타임 적응 과정에서 발생할 드리프트를 억제함
AMI 교체 중심의 플릿 업데이트
- 변경 사항은 새 AMI를 만든 뒤 배포 파이프라인으로 롤아웃하며, 기존 인스턴스를 패치하지 않고 통제된 교체로 플릿을 갱신함
- Auto Scaling Group(ASG)은 AWS Instance Refresh, Kubernetes 워커 플릿은 Karpenter를 사용함
- 특별한 배포 요구가 있는 서비스는 별도 실행기를 추가할 수 있으며, Gondola가 서로 다른 패턴을 일관된 배포 경험으로 통합함
-
긴급 수정 경로
- 긴급 상황에서는 실행 중인 인스턴스에 제한적인 구성 변경을 적용할 수 있지만, 이후 정상 배포 파이프라인을 통해 해당 인스턴스를 교체해야 함
- AWS Systems Manager의 사전 정의 문서로 선택한 Chef recipe를 실행해 긴급 수정을 적용함
- 시스템이 안정되면 인스턴스를 순환시켜 의도한 불변 상태로 복귀함
Gondola의 단계적 배포
- 고객 파이프라인은 서비스와 운영 요구에 맞춘 여러 단계로 구성할 수 있음
- 각 Gondola 단계는 ASG, Kubernetes 클러스터, EC2 인스턴스 그룹 같은 하나의 배포 단위를 나타냄
- Egress Team은 각 가용 영역에 카나리와 프로덕션 ASG를 따로 두고, 업데이트가 순차적으로 흐르도록 단계를 배치함
- Gondola는 각 단계를 갱신하면서 주요 지표를 감시하고, 문제가 발견되면 자동 롤백해 장애 확산을 막음
-
배포 아티팩트와 실행기
- Gondola가 만드는 배포 패키지는 두 부분으로 구성됨
- 플릿에 배포할 AMI
- Git 커밋과 연결된 버전 지정 recipe를 담은 Chef 아티팩트
- 두 요소를 하나의 배포 단위로 취급하며, 각 단계는 서비스가 정의한 실행기를 통해 롤아웃함
- ASG 배포에서는 실행기가 새 AMI와 구성으로 시작 템플릿을 갱신함
- Chef 코드는 Amazon S3에 패키징됨
- 새 인스턴스의 내장 부트스트래퍼가 올바른 아티팩트를 가져와 관련 recipe를 실행함
- 구성 메타데이터를 이용해 해당 역할에 맞는 설정만 적용함
- Kubernetes 워커 플릿에서는 실행기가 Karpenter에 사용할 AMI와 동일한 구성 메타데이터를 전달하며, 노드도 같은 방식으로 부트스트랩됨
- 특수 배포용 실행기를 추가해도 AMI, 버전 지정 구성 아티팩트, 메타데이터 기반 부트스트랩 방식은 그대로 유지됨
- Gondola가 만드는 배포 패키지는 두 부분으로 구성됨
플랫폼 팀과 서비스 팀의 책임 분담
- Compute·Security·Monitoring 팀은 기반 계층의 전역 인프라 구성요소, 보안 패치, 필수 설정을 관리함
- 서비스 팀은 그 기반 위에 자체 소프트웨어와 서비스별 설정을 추가한 AMI를 구축함
- Compute 팀이 보안 패치, 모니터링 에이전트, 네트워킹 변경을 배포하면 서비스 팀은 갱신된 기반 이미지를 자체 AMI에 반영해야 함
- 이 공유 책임 모델은 서비스별 자율성을 유지하면서 플릿의 일관성·보안·신뢰성을 맞춤
완전한 불변성이 아닌 비밀정보 예외
- Shipyard 인스턴스의 패키지와 구성은 대부분 베이킹 시 고정되지만 비밀정보는 예외임
- 각 인스턴스의 Consul Template 서비스가 플릿을 교체하지 않고 Vault의 새 비밀정보를 배포함
- 자격증명이나 인증서는 동적으로 갱신할 수 있으므로 Shipyard는 핵심 시스템과 서비스 계층만 고정된 반불변 인프라임
- 안정성과 예측 가능성을 유지하면서 중요한 런타임 비밀정보를 필요할 때 갱신할 수 있음
The Reaper의 교체 정책
- The Reaper는 두 종류의 입력으로 교체 대상을 결정함
- 보안 도구나 AWS EC2 이벤트 등 외부 시스템이 인스턴스가 원하는 상태를 벗어났다고 보내는 오염 신호
- 허용된 최대 수명보다 오래 실행됐는지 확인하는 정기 검사
- 어느 조건이든 충족하면 서비스 정책에 따라 인스턴스 교체를 예약함
- 수동 원격 접속은 긴급 상황을 위해 허용되지만, 프로덕션급 노드에 직접 접속하면 신호가 발생해 해당 인스턴스가 향후 교체 대상으로 표시됨
- Peekaboo와 연동해 플릿 전체의 인스턴스 나이를 추적하며, 최대 수명에 도달한 노드는 같은 정상 종료·교체 절차를 따름
- 향후에는 소프트웨어 업데이트나 구성 드리프트처럼 의미 있는 변경만 교체를 일으키고, 읽기 전용 또는 저위험 작업은 불필요한 순환을 만들지 않도록 문맥 인식 기능을 추가할 계획임
-
교체 속도와 비상 통제
- 내장 속도 제한으로 한 번에 교체할 수 있는 인스턴스 수를 서비스·리전·가용 영역별로 정해 갑작스러운 용량 영향을 막음
- S3에 제어 객체를 배치하는 전역 일시정지 장치인 “big red button”으로 장애나 위험이 큰 기간에 모든 Reaper 활동을 중단할 수 있음
- CLI에서 속도 제한 관리, 구성 확인, 전역 일시정지 활성화와 해제를 수행함
- 심층 조사가 필요한 break-glass 상황에서는 수명이 짧은 SSH 인증서 같은 통제된 접근 방식을 사용할 수 있음
Ship Quick을 이용한 실제 인프라 테스트
- Ship Quick은 플랫폼 팀과 서비스 소유자가 pull request를 병합하기 전에 실제 인프라에서 현실적인 베이킹·프로비저닝 테스트를 실행하는 개발자 워크플로임
- 개발자는 cookbook 저장소에서 CLI 명령을 실행하고 YAML 파일로 테스트 사례를 정의함
- Ship Quick은 다음 순서로 처리함
- cookbook을 패키징해 S3에 업로드함
- 워크플로 메시지를 큐로 전송함
- Longshoremen이 관리하는 워커 인스턴스가 작업을 가져옴
- 워커가 Auto Scaling Group에서 분리돼 Chef 워크플로를 실행함
- 로그를 CLI로 스트리밍한 뒤 종료되며, 개발자가 디버깅을 위해 유지하도록 선택할 수도 있음
-
기반 계층별 워커 플릿
- 부트스트랩 구조 때문에 두 개의 별도 워커 플릿을 운영함
- 기본 Ubuntu 플릿은 slack-zero가 자기 자신 위에서 빌드될 수 없으므로 깨끗한 Ubuntu AMI에서 기반 이미지를 베이킹하고 테스트함
- slack-zero 플릿은 사전 베이킹된 slack-zero에 의존하는 서비스 팀 cookbook을 테스트함
- 프로덕션과 같은 기반에서 프로비저닝을 검증함
- 최신 이미지로 계속 갱신돼 현재 프로덕션 환경을 반영함
- 두 플릿 모두 수요에 따라 자동 확장됨
- 자체 AWS 계정에서 이미지를 만드는 팀은 전용 워커 플릿을 구성하고 Ship Quick 작업을 해당 플릿으로 보내 격리를 유지할 수 있음
장기 실행 워크로드로의 확장
- Shipyard는 현재 단기 실행 서비스에서 효과적으로 작동하며, 레거시 EC2 플랫폼의 팀을 계속 온보딩하고 있음
- 다음 과제는 빠르게 순환시킬 수 없는 장기 실행 인스턴스임
- Slack 데이터 노드
- GitHub Enterprise 같은 싱글턴 서비스
- Atlassian JIRA 같은 서드파티 비즈니스 기술 인스턴스
- 이런 워크로드에는 안전한 패치·업데이트 방식과 The Reaper가 올바르게 처리할 수 있는 생명주기 정책이 필요함
- 서비스 팀과 협력해 Gondola용 장기 실행 워크로드 실행기를 개발하고 있으며, 채택 범위가 커지면서 도구·개발자 워크플로·배포 경험을 계속 개선할 계획임
- 향후 Shipyard API, 이미지 파이프라인, 개발자 워크플로, 인벤토리 시스템의 구성요소와 플랫폼 확장 과정에서 발생한 문제를 별도로 다룰 예정임