왜 멀티클라우드 배포가 어려운가
AWS와 GCP에 동시에 서비스를 배포하는 조직이 늘면서, 클라우드마다 다른 배포 도구와 CLI를 사용하는 문제가 커진다. EKS는 kubectl과 자체 IAM, GKE는 별도 인증, 여기에 각 팀의 셸 스크립트가 얽히면 배포 이력 추적과 롤백이 사실상 불가능해진다. 특히 카나리 검증이나 수동 승인 같은 절차를 각 클라우드마다 따로 구현하면 릴리스마다 사람이 개입해야 하고, 실수는 프로덕션 장애로 직결된다.
Spinnaker는 이 문제를 배포 대상(cloud provider)을 추상화하는 방식으로 푼다. 파이프라인 정의는 한 벌만 유지하고, 배포 스테이지에서 어떤 계정(account)을 쓰느냐만 바꿔서 여러 클라우드에 같은 흐름을 태울 수 있다.
핵심 개념: Account와 Provider
Spinnaker에서 배포 대상은 provider(kubernetes, aws, gcp 등)와 그 안의 account로 표현된다. 하나의 Spinnaker 인스턴스에 EKS 클러스터와 GKE 클러스터를 각각 account로 등록하면, 파이프라인은 이 account 이름만으로 배포 위치를 결정한다. 아래는 halyard로 두 개의 쿠버네티스 account를 등록하는 예시다.
hal config provider kubernetes enable
hal config provider kubernetes account add eks-prod \
--provider-version v2 \
--context arn:aws:eks:ap-northeast-2:1234:cluster/prod \
--kubeconfig-file ~/.kube/eks-config
hal config provider kubernetes account add gke-prod \
--provider-version v2 \
--context gke_myproj_asia-northeast3_prod \
--kubeconfig-file ~/.kube/gke-config
hal deploy apply
이렇게 등록하면 두 클러스터가 서로 다른 인증 체계를 쓰더라도 Spinnaker 내부에서는 eks-prod, gke-prod라는 이름으로 동일하게 취급된다.
파이프라인 스테이지 설계
멀티클라우드 배포의 기본 전략은 두 가지다. 두 클라우드에 동시에 배포하는 fan-out 방식과, 한쪽을 먼저 검증한 뒤 다음으로 넘기는 순차 방식이다. 장애 격리와 점진적 롤아웃 관점에서는 순차 배포에 수동 승인을 끼우는 편이 안전하다.
| 전략 | 장점 | 주의점 |
|---|---|---|
| 동시(fan-out) | 배포 시간 단축 | 양쪽 동시 장애 위험 |
| 순차 + 승인 | 단계별 검증, 격리 | 전체 소요 시간 증가 |
아래는 EKS에 먼저 배포하고, 수동 승인 후 GKE에 배포하는 파이프라인 스테이지 정의(JSON 일부)다. refId와 requisiteStageRefIds로 실행 순서를 잡는다.
{
"stages": [
{
"refId": "1",
"type": "deployManifest",
"account": "eks-prod",
"moniker": { "app": "api" },
"manifestArtifactId": "api-manifest"
},
{
"refId": "2",
"type": "manualJudgment",
"requisiteStageRefIds": ["1"],
"instructions": "EKS 헬스체크 확인 후 승인",
"judgmentInputs": [{ "value": "proceed" }]
},
{
"refId": "3",
"type": "deployManifest",
"account": "gke-prod",
"requisiteStageRefIds": ["2"],
"manifestArtifactId": "api-manifest"
}
]
}
매니페스트는 한 벌로 유지한다
클라우드별로 매니페스트를 복제하면 곧 두 파일이 어긋난다. 동일한 매니페스트 아티팩트를 두 account에 재사용하고, 클러스터별 차이(스토리지 클래스, LoadBalancer 어노테이션 등)는 Kustomize overlay나 파이프라인 파라미터로 주입하는 방식이 유지보수에 유리하다. 이미지 태그 같은 값은 ${trigger.tag} 형태의 SpEL 표현식으로 트리거에서 넘겨받는다.
카나리와 자동 롤백
Spinnaker의 Kayenta를 붙이면 두 버전의 메트릭을 통계적으로 비교해 배포 성공 여부를 자동 판정할 수 있다. 다만 멀티클라우드에서는 메트릭 소스(CloudWatch vs Cloud Monitoring)가 다르므로, 카나리 판정 기준을 클라우드별로 분리해 두어야 한다. 자동 롤백은 deployManifest 실패 시 이전 ReplicaSet으로 되돌리도록 스테이지 실패 정책을 설정한다.
운영 시 주의점
첫째, account별 IAM/서비스 계정 권한을 최소로 제한한다. Spinnaker가 두 클라우드에 접근하는 만큼 자격 증명이 유출되면 피해 범위가 넓다. 둘째, kubeconfig 토큰 만료를 모니터링해야 한다. EKS 토큰은 단기 만료되므로 IAM 인증 방식 설정을 검토한다. 셋째, 파이프라인 정의는 반드시 코드로 관리(spin CLI나 Terraform)해 UI 수동 변경을 막는다. 손으로 고친 파이프라인은 재현이 안 되고, 결국 처음의 배포 파편화 문제로 돌아간다.