본문 바로가기

개발

Helm Hook으로 쿠버네티스 배포 순서 문제 해결하기

반응형

안녕하세요! 오늘은 제가 현업에서 문제를 해결하면서 알게 된 Helm Hook이라는 친구를 소개해볼까 해요 :)

😱 문제 상황

실제 현업에서 이런 난감한 상황을 겪어보신 적 있으신가요?

  • 나: 오케이~ 새 버전 배포 고고!
  • 쿠버네티스: (서버 먼저 띄우면서) 엥? DB 스키마가 없는데요?
  • 나: 헐... 마이그레이션이 먼저 돌았어야 했는데...
  • 쿠버네티스: 그럼 롤백할까요~?
  • 나: ㅠㅠㅠㅠㅠ

너무 무서운 순간이죠? 이런 상황은 실제로 프로덕션 환경에서 자주 발생할 수 있는 매우 위험한 시나리오예요. 하지만 이런 상황을 Helm Hook을 사용하면 쉽게 해결할 수 있어요!

Helm Hook이란?

Helm Hook은 쿠버네티스 리소스의 라이프사이클을 제어하는 특별한 '어노테이션'이에요. 쉽게 말하면 "이 리소스는 이때 실행해 줘!"라고 명령하는 거예요.

Hook의 종류

  • helm.sh/hook: pre-install : 설치 전에 실행해줘 (예: DB 초기화, 필수 시크릿 생성)
  • helm.sh/hook: post-install : 설치 끝나고 실행해줘 (예: 헬스체크, 알림 발송)
  • helm.sh/hook: pre-upgrade : 업그레이드 전에 실행해줘 (예: DB 마이그레이션, 설정 백업)
  • helm.sh/hook: post-upgrade : 업그레이드 끝나고 실행해줘 (예: 캐시 초기화, 시스템 점검)
  • helm.sh/hook: pre-delete : 삭제하기 전에 실행해줘 (예: 데이터 백업, 연관 리소스 정리)
  • helm.sh/hook: post-delete : 삭제하고 나서 실행해줘 (예: 리소스 정리, 알림 발송)

예를 들어, 아래와 같이 DB 마이그레이션 Job을 설정하면 Helm 차트 업그레이드 시 마이그레이션 태스크를 먼저 실행할 수 있어요.

apiVersion: batch/v1
kind: Job
metadata:
  name: db-migration
  annotations:
    helm.sh/hook: pre-install,pre-upgrade
    helm.sh/hook-delete-policy: hook-succeeded,before-hook-creation
spec:
  template:
    spec:
      containers:
      - name: migration
        image: app-migration:v1
        command: ["./migrate.sh"]
      restartPolicy: Never

Hook Weight는 뭐야?

같은 Hook 타이밍 내에서도 순서가 필요할 때가 있어요. 예를들어, 마이그레이션 잡을 실행하기 전에 ConfigMap을 먼저 업데이트해야 하는 경우가 있어요.

이때 helm.sh/hook-weight 어노테이션을 사용해요.

  • 작은 숫자가 먼저 실행돼요. (음수 가능)
  • 반드시 문자열로 작성해줘야 해요.
  • 같은 weight는 동시 실행될 수 있어요.
  • weight를 지정하지 않으면 0으로 간주돼요.

즉, helm.sh/hook-weight: "-5", helm.sh/hook-weight: "0"와 같이 작성해주시면 돼요. 여기서는 -5가 0보다 작기 때문에 훅이 먼저 실행돼요.

Delete Policy도 중요해요!

Delete Policy는 Hook이 실행된 후 리소스를 어떻게 처리할지 결정해요. 세 가지 옵션이 있어요.

  1. helm.sh/before-hook-creation
    • 새로운 Hook을 생성하기 전에 이전 버전을 삭제
    • 기본값이며 가장 많이 사용되는 옵션
    • ConfigMap, Secret 같은 지속적으로 필요한 리소스에 적합
  2. helm.sh/hook-succeeded: Hook이 성공하면 삭제
    • Hook이 성공적으로 완료되면 리소스를 삭제
    • Job이나 일회성 작업에 적합
    • 시스템을 깔끔하게 유지하는데 도움
  3. helm.sh/hook-failed: Hook이 실패하면 삭제
    • Hook이 실패하면 리소스를 삭제
    • 디버깅을 위해 성공한 Job은 유지하고 싶을 때 사용
    • 실패한 케이스만 정리하고 싶을 때 유용

여러 정책을 콤마로 구분해서 동시에 적용할 수 있어요:

annotations:
  helm.sh/hook-delete-policy: hook-succeeded,before-hook-creation

ConfigMap이랑 Migration Job에 다른 정책을 쓰는 이유가 있어요:

  • ConfigMap: 새 버전 만들기 전에 이전 버전만 삭제하면 돼요
  • Migration Job: 성공하면 삭제해서 깔끔하게 정리하고 싶어요

💡 예시 살펴보기

그럼 위의 내용을 반영한 예시를 살펴볼게요.

  1. 설정 준비 (weight: -5)
apiVersion: v1
kind: ConfigMap
metadata:
  annotations:
    helm.sh/hook: pre-install,pre-upgrade
    helm.sh/hook-weight: "-5"
    helm.sh/hook-delete-policy: before-hook-creation
  1. DB 마이그레이션 (weight: -4)
apiVersion: batch/v1
kind: Job
metadata:
  annotations:
    helm.sh/hook: pre-install,pre-upgrade
    helm.sh/hook-weight: "-4"
    helm.sh/hook-delete-policy: hook-succeeded,before-hook-creation
  1. 메인 애플리케이션 (Hook 없음)

Hook 없는 일반 리소스는 모든 Hook이 성공적으로 완료된 후에 배포돼요. 이렇게 하면 안전하게 순서대로 배포할 수 있답니다!

📝 정리하면

  1. Hook으로 실행 타이밍을 정확하게 제어
  2. Weight로 같은 Hook 내에서 세밀한 순서 조정
  3. Delete Policy로 리소스의 생명주기를 관리
  4. 이 모든 것을 조합해서 안전하고 예측 가능한 배포 파이프라인 구축!

이렇게 Helm Hook을 잘 활용하면, 처음에 보았던 것과 같은 난감한 상황을 예방할 수 있어요. 배포 순서를 완벽하게 제어해서 안정적인 운영을 할 수 있답니다! 여기까지 긴 글 읽어주셔서 감사합니다! 😊

반응형