LabHub

CNPE — 클라우드 네이티브 플랫폼 엔지니어 (전문가) · GitOps 와 지속적 배포 · 이론

게이트를 어디에 둘 것인가

LabHub 에서 이어서 보기

한 줄 요약

배포 파이프라인의 게이트는 소스가 아니라 렌더 결과에 걸어야 합니다. 클러스터에 들어가는 것은 파일이 아니라 렌더된 매니페스트이고, 게이트가 보지 않은 것은 막을 수 없기 때문입니다.

왜 렌더 결과인가

kustomize 오버레이 세 개짜리 저장소에서 흔히 이런 게이트를 봅니다.

grep -r "image:.*:latest" .   # latest 태그 금지

이 검사는 base 를 보고 통과합니다. 그런데 실제로 배포되는 것은 오버레이가 이미지를 덮은 결과이고, 그 결과에는 latest 가 들어 있을 수 있습니다. 반대도 성립합니다. base 에 latest 가 있어도 오버레이가 다이제스트로 덮으면 배포되는 것은 안전한데, 게이트는 빨간불을 켭니다.

두 경우 모두 게이트가 자기가 막으려는 대상을 보고 있지 않아서 생깁니다. 그래서 순서는 하나뿐입니다.

kustomize build overlays/prod   →   렌더 결과        ↓스키마 검증 · 정책 검사          →   이 결과를 검사한다        ↓0 이 아닌 종료 코드면 배포 중단

어떻게 동작하나

게이트는 종료 코드로 말해야 합니다

정책 도구를 돌려 놓고 결과를 화면에만 뿌리고 끝내는 파이프라인이 정말 많습니다. 로그에는 빨간 글씨가 있고 파이프라인은 초록불입니다. 게이트의 본체는 검사가 아니라 검사 결과를 종료 코드로 옮기는 것입니다.

if ! kyverno apply policy/require-pinned.yaml --resource "$RENDER"; then  echo "정책 위반으로 배포를 막습니다"; exit 3fi

그리고 게이트를 만들었으면 막아야 할 것을 실제로 넣어 보고 빨간불이 켜지는지 확인해야 합니다. 통과하는 것만 확인한 게이트는 몇 달 동안 아무것도 지키지 않은 채로 초록불을 냅니다.

태그가 아니라 다이제스트

checkout:1.4.0 은 이름이고 checkout@sha256:... 은 내용입니다. 태그는 다시 밀 수 있어서, 어제 검증한 것과 오늘 배포되는 것이 다를 수 있습니다. 다이제스트로 고정하면 "게이트를 통과한 그것" 과 "클러스터에 들어간 그것" 이 같다는 것을 말할 수 있습니다. 감사 추적이 성립하는 최소 조건입니다.

진행형 배포는 멈춤이 본체입니다

카나리를 setWeight: 10setWeight: 100 으로 적어 두면 그건 카나리가 아니라 조금 느린 전면 배포입니다. 가중치 사이에 pause 가 있어야 사람이나 분석이 판단할 자리가 생깁니다. 그리고 카나리만 따로 볼 수 있어야 판단할 근거가 생기므로, canaryServicestableService 를 나눠 둡니다.

블루/그린은 다른 상황을 위한 것입니다. 두 버전이 동시에 같은 데이터를 쓰면 안 되는 서비스, 이를테면 원장(ledger)에는 가중치를 나눌 방법이 없습니다. 이때는 새 버전을 통째로 띄워 두고 미리보기 통로로만 확인한 뒤, 사람이 승격 버튼을 누릅니다. autoPromotionEnabled: false 가 그 "사람이" 에 해당합니다.

현장에서 만나는 모습

한 조직에서 카나리 분석이 계속 통과했는데 장애가 났습니다. 원인은 분석 템플릿 이름을 오타 낸 것이었습니다. Rollout 은 없는 템플릿을 참조하고 있었고, 그 사실은 승격 직전에야 드러났습니다. 그래서 "참조한 템플릿이 실제로 있는가" 는 배포 전에 확인할 항목입니다.

또 하나 자주 보는 것은 Argo CD Application 의 목적지 네임스페이스와 매니페스트가 렌더되는 네임스페이스가 어긋나 있는 경우입니다. 동기화는 성공하고 초록불이 뜨는데 아무 데도 반영되지 않습니다.

다음 실습에서 할 것

base 와 운영 오버레이를 만들고, 렌더 결과에 정책 게이트를 걸고, 그 게이트가 위반을 실제로 막는지 확인한 뒤, 카나리와 블루/그린을 각각 어떤 서비스에 붙일지 정합니다.