DevOps/Kubernetes

Kubernetes Job을 Helm Hook 으로 반복적으로 실행하기

Ethan Kang 2021. 12. 19. 00:35
반응형

Kubernetes Job을 Helm Hook 으로 반복적으로 실행하기

들어가며

Kubernetes 환경에서 일회성 프로그램을 실행하거나 정기적으로 정해진 시간에 프로그램을 실행해야 할 때가 있습니다. 특히 데이터베이스 마이그레이션과 같은 작업은 특정 시점에 한 번만 실행되어야 하는 경우가 많습니다. 이런 상황에서 Kubernetes Job 리소스가 유용하게 활용됩니다.

Kubernetes Job의 이해

Kubernetes Job은 일회성 작업을 실행하는 데 적합한 리소스입니다. 지정된 수의 Pod가 성공적으로 종료될 때까지 Pod를 실행하는 것을 보장합니다. 이는 다음과 같은 경우에 유용합니다:

  • 데이터베이스 마이그레이션
  • 배치 처리 작업
  • 초기화 스크립트 실행
  • 백업 및 복원 작업

그러나 Kubernetes Job에는 한 가지 중요한 제한사항이 있습니다. 동일한 Job을 재실행하려면 기존 Job 리소스를 삭제하고 재설치해야 합니다. 이는 다음 명령어로 수행됩니다:

kubectl delete job <job-name>
kubectl apply -f job.yaml

이 방식은 작동하지만, 단일 명령어로 작업을 실행하는 더 효율적인 방법이 있을까요? 여기서 Helm Hook이 등장합니다.

Helm Hook 소개

Helm 공식 문서에 따르면:

Helm provides a hook mechanism to allow chart developers to intervene at certain points in a release's life cycle.

간단히 말해, Helm Hook은 Helm 차트의 릴리스 라이프사이클 특정 시점에 개입하여 작업을 실행할 수 있는 메커니즘입니다. Hook을 사용하면 설치, 업그레이드, 삭제 등의 이벤트 전후에 특정 작업을 실행할 수 있습니다.

Helm Hook의 주요 유형

Helm은 다양한 훅 유형을 제공합니다:

  • pre-install: 차트가 설치되기 전에 실행
  • post-install: 차트가 설치된 후 실행
  • pre-delete: 차트가 삭제되기 전에 실행
  • post-delete: 차트가 삭제된 후 실행
  • pre-upgrade: 차트가 업그레이드되기 전에 실행
  • post-upgrade: 차트가 업그레이드된 후 실행
  • pre-rollback: 차트가 롤백되기 전에 실행
  • post-rollback: 차트가 롤백된 후 실행
  • test: 테스트 실행 시 실행

Helm Hook 예제 코드 분석

다음은 Helm Hook을 사용한 Kubernetes Job의 예시입니다:

apiVersion: batch/v1
kind: Job
metadata:
  name: "{{ .Release.Name }}"
  labels:
    helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
  annotations:
    # 이 줄이 리소스를 훅으로 정의합니다. 이 줄이 없으면 Job이 릴리스의 일부로 간주됩니다.
    "helm.sh/hook": post-install
    "helm.sh/hook-weight": "-5"
    "helm.sh/hook-delete-policy": hook-succeeded
spec:
  template:
    metadata:
      name: "{{ .Release.Name }}"
      labels:
        app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
        app.kubernetes.io/instance: {{ .Release.Name | quote }}
        helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    spec:
      restartPolicy: Never
      containers:
      - name: post-install-job
        image: "alpine:3.3"
        command: ["/bin/sleep","{{ default "10" .Values.sleepyTime }}"]

주요 주석(annotations) 설명

  • helm.sh/hook: post-install: 이 Job이 차트 설치 직후에 실행되도록 지정합니다.
  • helm.sh/hook-weight: "-5": 훅의 실행 순서를 결정합니다. 낮은 숫자가 먼저 실행됩니다.
  • helm.sh/hook-delete-policy: hook-succeeded: 훅이 성공적으로 완료된 후 자동으로 삭제되도록 지정합니다.

Helm Hook을 활용한 데이터베이스 마이그레이션

데이터베이스 마이그레이션은 Helm Hook의 대표적인 활용 사례입니다. 애플리케이션이 업그레이드될 때 스키마 변경이 필요한 경우, pre-upgrade 훅을 사용하여 마이그레이션을 실행할 수 있습니다:

apiVersion: batch/v1
kind: Job
metadata:
  name: "{{ .Release.Name }}-db-migration"
  annotations:
    "helm.sh/hook": pre-upgrade
    "helm.sh/hook-weight": "0"
    "helm.sh/hook-delete-policy": hook-succeeded
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: db-migration
        image: "{{ .Values.migration.image }}"
        command: ["./migrate"]
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: {{ .Release.Name }}-db-credentials
              key: url

Helm Hook 사용의 모범 사례

  1. 적절한 훅 유형 선택: 작업의 성격에 맞는 훅 유형을 선택하세요. 데이터베이스 마이그레이션은 일반적으로 pre-upgradepost-install에 적합합니다.
  2. weight 설정: 여러 훅이 있을 경우 hook-weight를 사용하여 실행 순서를 명확히 하세요.
  3. 삭제 정책 설정: hook-delete-policy를 사용하여 훅 리소스의 수명주기를 관리하세요:
    • hook-succeeded: 성공 시 삭제
    • hook-failed: 실패 시 삭제
    • before-hook-creation: 새 훅이 생성되기 전에 삭제
  4. 오류 처리: 훅이 실패할 경우 적절한 대응 방법을 계획하세요. 롤백 전략을 고려하는 것이 좋습니다.

결론

Kubernetes Job은 일회성 작업을 실행하는 데 유용하지만, 재실행을 위해서는 삭제와 재설치가 필요합니다. Helm Hook은 이러한 제한을 극복하고 릴리스 라이프사이클의 특정 시점에 작업을 자동으로 실행할 수 있게 해줍니다.

특히 데이터베이스 마이그레이션과 같은 작업에서 Helm Hook은 배포 프로세스를 자동화하고 일관성을 유지하는 강력한 도구입니다. 적절한 훅 유형, 가중치, 삭제 정책을 설정하여 Kubernetes 기반 애플리케이션의 라이프사이클 관리를 더욱 효율적으로 수행할 수 있습니다.

반응형