CI/CD 스터디 07: 배포 전략, Environment, Rollback
CI/CD의 CD 영역에서 environment, approval, rolling/blue-green/canary 전략, Kubernetes rollout, GitOps, rollback 기록을 정리합니다.
CD는 빌드 산출물을 운영에 복사하는 일이 아니라, 변경을 어느 환경에 어떤 속도로 풀고 실패하면 어디로 되돌릴지 정하는 운영 절차입니다.
배포 컴포넌트
- environment: dev, staging, production처럼 배포 대상과 승인 정책이 묶인 단위입니다.
- deployment job: artifact 또는 image를 특정 환경에 반영하는 job입니다.
- approval gate: 운영 배포 전 사람 또는 정책이 확인하는 지점입니다.
- strategy: rolling, blue/green, canary, recreate 같은 traffic 전환 방식입니다.
- rollback: 실패 시 이전 정상 버전으로 되돌리는 절차입니다.
- deployment record: 누가, 무엇을, 어디에, 언제 배포했는지 남기는 기록입니다.
전략 비교
| 전략 | 장점 | 주의점 |
|---|---|---|
| rolling | 대부분의 Kubernetes Deployment 기본 흐름에 잘 맞습니다. | 새 버전과 이전 버전이 동시에 떠도 호환되어야 합니다. |
| blue/green | 전체 전환과 즉시 롤백이 명확합니다. | 두 환경을 유지할 리소스와 데이터 호환성이 필요합니다. |
| canary | 일부 트래픽으로 위험을 작게 검증합니다. | 트래픽 라우팅과 관측성이 충분해야 합니다. |
| recreate | 단순합니다. | 중단 시간이 생기므로 운영 서비스에는 신중해야 합니다. |
Kubernetes Rolling Update
Kubernetes Deployment는 rolling update와 rollout history/undo를 기본적으로 지원합니다. 중요한 것은 readiness probe가 정확해야 한다는 점입니다. 준비되지 않은 pod를 정상으로 판단하면 rolling update도 안전하지 않습니다.
kubectl -n app get deploy,rs,pod
kubectl -n app set image deployment/app app=registry.example.com/team/app:v1.4.0
kubectl -n app rollout status deployment/app --timeout=180s
kubectl -n app rollout history deployment/app
# 실패 시 이전 revision으로 되돌리기
kubectl -n app rollout undo deployment/app
kubectl -n app rollout status deployment/app --timeout=180sGitHub Actions environment gate
environment를 job에 연결하면 staging/production별 secret, 승인, branch restriction을 분리할 수 있습니다. production job은 main 또는 release tag에서만 실행되게 하는 것이 기본입니다.
jobs:
deploy-production:
runs-on: ubuntu-latest
needs: [ build ]
if: startsWith(github.ref, 'refs/tags/v')
environment: production
steps:
- uses: actions/checkout@v4
- run: ./scripts/deploy-production.shGitOps 방식
GitOps에서는 CI job이 운영 클러스터에 직접 명령을 보내지 않고, 배포 매니페스트 repository에 image tag 또는 digest 변경 commit을 남깁니다. Argo CD 같은 CD 도구는 Git의 desired state와 클러스터 live state 차이를 감지하고 sync합니다.
# CI가 app repo에서 image를 만든 뒤 GitOps repo의 image digest를 갱신하는 흐름 예시
git clone git@example.com:platform/app-manifests.git
cd app-manifests
kustomize edit set image app=registry.example.com/team/app@sha256:IMAGE_DIGEST_PLACEHOLDER
git add .
git commit -m "deploy app sha256:IMAGE_DIGEST_PLACEHOLDER"
git push origin mainRollback을 미리 작성해야 하는 이유
운영 장애가 난 뒤 rollback 명령을 찾으면 이미 늦습니다. 배포 job마다 rollback 조건과 명령이 같이 있어야 합니다.
배포 전 기록
- application: app
- source commit: <git-sha>
- image digest: sha256:<digest>
- target environment: production
- migration included: yes/no
- rollback command: kubectl -n app rollout undo deployment/app
- data rollback needed: yes/no
- validation command: curl -fsS https://service.example.com/health실무 체크리스트
- 배포 job과 build job의 권한을 분리합니다.
- staging 배포와 production 배포는 같은 artifact를 사용합니다. production에서 다시 빌드하지 않습니다.
- DB migration이 있으면 app rollback과 data rollback 가능 여부를 별도로 판단합니다.
- 배포 성공 조건은 job 종료가 아니라 health check와 핵심 smoke test 통과입니다.
- GitOps 자동 sync는 편하지만 prune/self-heal 정책은 운영 위험을 이해한 뒤 켭니다.