LabHub

CI/CD 파이프라인 · 아티팩트와 승격 · 이론

개발에서 되던 게 운영에서 안 되는 진짜 이유

LabHub 에서 이어서 보기

한 줄 요약

환경마다 다시 빌드하면 환경마다 다른 것이 나옵니다. 한 번 빌드한
아티팩트를 그대로 승격시키는 것이 이 문제의 유일한 근본 해결입니다.

왜 이게 필요했나

파이프라인이 이렇게 생긴 곳이 아주 많습니다.

dev 브랜치  → 빌드 → dev 배포stage 브랜치 → 빌드 → stage 배포main 브랜치  → 빌드 → prod 배포

세 번 빌드합니다. 소스가 같으니 결과도 같을 거라고 생각하지만, 그렇지
않습니다. 빌드 사이에 이런 것들이 달라집니다.

그래서 dev 에서 통과한 테스트가 prod 이미지에서는 의미가 없습니다.
테스트한 것과 배포한 것이 다른 물건이기 때문입니다.

빌드는 한 번, 승격은 여러 번

소스 커밋 → 빌드 1회 → 아티팩트(불변) ─┬→ dev 배포 → 테스트                                      ├→ stage 배포 → 검증                                      └→ prod 배포

핵심은 아티팩트가 불변이라는 것입니다. dev 에서 검증한 그 바이트가
prod 로 갑니다. 그러면 "환경 때문에 다르다" 는 변수가 사라지고, 남는
차이는 설정과 데이터뿐입니다 — 그건 우리가 통제할 수 있습니다.

승격은 재빌드가 아니라 참조를 바꾸는 일입니다.

# gitops/prod/kustomization.yamlimages:  - name: registry/backend    newTag: v0820-1500      # ← 이 한 줄을 고치는 커밋이 배포다

LabHub 자체가 이 방식으로 돕니다. 이미지를 한 번 굽고, dev 오버레이의
태그를 올려 검증하고, 통과하면 prod 오버레이의 같은 태그로 올립니다.
배포 기록이 곧 git 로그입니다.

설정은 아티팩트 밖에 둔다

같은 아티팩트를 여러 환경에 쓰려면 환경별로 달라지는 것을 밖으로 빼야
합니다.

| 항목 | 이미지 안 | 이미지 밖 |
| --- | --- | --- |
| 애플리케이션 코드 | ✅ | |
| 런타임·라이브러리 | ✅ | |
| DB 주소, 외부 API URL | | ✅ 환경변수/ConfigMap |
| 자격증명 | | ✅ Secret |
| 로그 레벨, 기능 플래그 | | ✅ 설정 |

이미지 안에 application-prod.yml 을 굽는 순간 그 이미지는 prod 전용이
되고, 승격 모델이 깨집니다.

무엇으로 식별하는가

아티팩트에는 되짚을 수 있는 이름이 필요합니다.

latest 는 승격 모델에서 쓰면 안 됩니다. 어느 시점의 latest 인지 알 수
없어서 롤백할 대상을 특정하지 못합니다.

게이트는 승격 사이에 놓는다

빌드 → [단위 테스트] → dev → [통합 테스트] → stage → [수동 승인] → prod

각 화살표 앞의 대괄호가 게이트입니다. 게이트는 통과/차단을 종료코드로
말해야 합니다. 로그에 "실패" 라고 찍고 exit 0 을 반환하면 파이프라인은
그냥 지나갑니다 — 실제로 흔한 버그입니다.

롤백은 승격의 역방향이다

승격이 태그를 올리는 커밋이면, 롤백은 이전 태그로 되돌리는 커밋입니다.
재빌드도, 긴급 패치도 필요 없습니다. 이전 아티팩트는 레지스트리에 그대로
있으니까요.

이게 가능하려면 아티팩트를 지우지 말아야 합니다. 보존 정책을 짤 때
"최근 N개" 만 남기면 그보다 오래된 버전으로는 못 돌아갑니다.

현장에서 만나는 모습

다음 확인에서 볼 것

이어지는 퀴즈에서는 빌드와 승격의 차이, 불변 다이제스트, 외부 설정과 보존
정책이 롤백 가능성에 미치는 영향을 판단합니다. 앞 실습에서 만든 아티팩트와
환경별 참조를 근거로 재빌드 없는 승격 조건을 확인해 보세요.