LabHub

Helm 배포와 롤백 시나리오 · 릴리스와 리비전 · 이론

릴리스는 시크릿 하나다

LabHub 에서 이어서 보기

한 줄 요약

Helm 릴리스는 마법이 아니라 네임스페이스 안의 시크릿 한 줄이다. 그 사실을 알면 롤백이 무엇을 되돌리는지, 왜 어떤 것은 못 되돌리는지가 전부 설명된다.

왜 이게 필요했나

helm rollback 을 눌렀는데 데이터베이스 마이그레이션이 되돌아오지 않아 서비스가 깨진 경험은 흔하다. 반대로 "롤백했는데 아무것도 안 바뀌었다" 는 신고도 흔하다. 둘 다 같은 오해에서 나온다 — 롤백이 시간을 되감는다고 생각하는 것.

Helm 이 하는 일은 훨씬 단순하다. helm install 을 하면 렌더링된 매니페스트 전체를 gzip 으로 눌러 시크릿에 저장한다. 이름은 sh.helm.release.v1.<릴리스>.v<리비전> 이다. helm upgrade 를 하면 새 리비전 시크릿을 하나 더 만든다. helm rollback 3리비전 3의 시크릿을 꺼내 그 매니페스트를 다시 apply 하는 것이다.

그래서 규칙이 따라 나온다. 매니페스트에 적혀 있던 것은 되돌아온다. 매니페스트 바깥에서 벌어진 일 — 마이그레이션이 바꾼 데이터, Job 이 만든 파일, 외부 API 에 보낸 요청 — 은 되돌아오지 않는다.

어떻게 동작하나

직접 확인할 수 있다.

kubectl get secret -l owner=helmkubectl get secret sh.helm.release.v1.demo.v1 -o jsonpath='{.data.release}' \  | base64 -d | base64 -d | gzip -d | head -40

두 번 base64 를 푸는 것이 이상해 보이지만 맞다. 쿠버네티스가 시크릿 값을 한 번 인코딩하고, Helm 이 그 안에서 또 한 번 인코딩해 두었다.

helm history 는 이 시크릿들의 목록이다. 리비전마다 상태가 있다.

| 상태 | 뜻 |
|---|---|
| deployed | 지금 살아 있는 리비전. 항상 하나뿐이다 |
| superseded | 예전에 배포됐다가 다음 리비전에 자리를 내준 것 |
| failed | 적용에 실패한 리비전 |
| pending-upgrade | 업그레이드를 시작했는데 끝나지 않은 것. 여기 갇히면 다음 배포가 막힌다 |

흔한 착각

롤백은 리비전 번호를 되돌리지 않는다. helm rollback demo 1 을 하면 리비전 1로 돌아가는 게 아니라, 리비전 1의 내용으로 새 리비전 3 을 만든다. history 를 보면 3번 줄에 Rollback to 1 이라고 적혀 있다. 이건 감사 기록을 지우지 않기 위한 설계다 — 무슨 일이 있었는지가 히스토리에 남아야 한다.

보관 개수에 제한이 있다. 기본값은 10개다(--history-max). 오래된 리비전은 지워지므로 "6개월 전으로 롤백" 은 대개 불가능하다. 되돌릴 수 있는 창은 생각보다 좁다.

실무에서 진짜 중요한 것

릴리스가 시크릿이라는 건 크기 제한이 있다는 뜻이기도 하다. etcd 의 객체 한도는 1MiB 다. 차트가 커지면(특히 CRD 를 잔뜩 담으면) 릴리스 시크릿이 그 한도에 부딪혀 업그레이드가 실패한다. 그때 나오는 오류 메시지는 원인을 전혀 알려 주지 않으므로, 이 구조를 아는 것이 곧 해결 속도다.