Helm Hook은 릴리스 생명주기의 특정 시점에 실행되는 Kubernetes 리소스입니다. 일반적인 차트 리소스와 달리 Hook은 특정 이벤트(설치, 업그레이드, 삭제 등)에서만 실행됩니다.
| Hook 타입 | 실행 시점 | 사용 예시 |
|---|---|---|
pre-install | 설치 전 | 사전 조건 확인, 네임스페이스 생성 |
post-install | 설치 후 | 초기 데이터 설정, 알림 |
pre-upgrade | 업그레이드 전 | 백업, 데이터 마이그레이션 |
post-upgrade | 업그레이드 후 | 캐시 정리, 상태 확인 |
pre-delete | 삭제 전 | 백업, 정리 작업 |
post-delete | 삭제 후 | 리소스 정리, 알림 |
pre-rollback | 롤백 전 | 상태 저장 |
post-rollback | 롤백 후 | 상태 복구 |
| Hook 타입 | 실행 방법 | 사용 예시 |
|---|---|---|
test | helm test | 배포 검증, 헬스 체크 |
metadata:
annotations:
"helm.sh/hook": "pre-install"
"helm.sh/hook-weight": "0"
"helm.sh/hook-delete-policy": "before-hook-creation"
실행 순서를 제어합니다 (낮은 값이 먼저 실행).
# 첫 번째 실행
"helm.sh/hook-weight": "-10"
# 두 번째 실행
"helm.sh/hook-weight": "0"
# 세 번째 실행
"helm.sh/hook-weight": "10"
Hook 실행 후 정리 정책을 설정합니다.
| 정책 | 설명 |
|---|---|
before-hook-creation | 새 Hook 생성 전 이전 Hook 삭제 |
hook-succeeded | Hook 성공 시 삭제 |
hook-failed | Hook 실패 시 삭제 |
# 여러 정책 조합 가능
"helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded"
pre-install Hook 실행post-install Hook 실행pre-upgrade Hook 실행post-upgrade Hook 실행# templates/hooks/db-migration.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: "{{ .Release.Name }}-db-migration"
annotations:
"helm.sh/hook": pre-upgrade
"helm.sh/hook-weight": "-5"
"helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded"
spec:
template:
spec:
containers:
- name: migration
image: "{{ .Values.migration.image }}"
env:
- name: DB_URL
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-db-secret"
key: url
command:
- sh
- -c
- |
echo "Starting database migration..."
migrate -path /migrations -database $DB_URL up
echo "Migration completed successfully"
restartPolicy: Never
backoffLimit: 3
# templates/hooks/config-validation.yaml
apiVersion: v1
kind: Pod
metadata:
name: "{{ .Release.Name }}-config-validation"
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-weight": "-10"
"helm.sh/hook-delete-policy": "hook-succeeded"
spec:
containers:
- name: validator
image: busybox
command:
- sh
- -c
- |
echo "Validating configuration..."
# 필수 값 확인
{{- if not .Values.database.host }}
echo "ERROR: database.host is required"
exit 1
{{- end }}
{{- if not .Values.database.port }}
echo "ERROR: database.port is required"
exit 1
{{- end }}
echo "Configuration validation passed"
restartPolicy: Never
# templates/hooks/backup.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: "{{ .Release.Name }}-backup-{{ now | unixEpoch }}"
annotations:
"helm.sh/hook": pre-upgrade
"helm.sh/hook-weight": "-1"
"helm.sh/hook-delete-policy": "hook-succeeded"
spec:
template:
spec:
containers:
- name: backup
image: postgres:13
env:
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-db-secret"
key: password
command:
- sh
- -c
- |
echo "Creating backup..."
pg_dump -h {{ .Values.database.host }} \
-U {{ .Values.database.user }} \
-d {{ .Values.database.name }} \
> /backup/backup-$(date +%Y%m%d-%H%M%S).sql
echo "Backup created successfully"
volumeMounts:
- name: backup-storage
mountPath: /backup
volumes:
- name: backup-storage
persistentVolumeClaim:
claimName: "{{ .Release.Name }}-backup-pvc"
restartPolicy: Never
# templates/tests/api-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: "{{ .Release.Name }}-api-test"
annotations:
"helm.sh/hook": test
"helm.sh/hook-delete-policy": "before-hook-creation"
spec:
containers:
- name: test
image: curlimages/curl:latest
command:
- sh
- -c
- |
echo "Testing API endpoints..."
# 헬스 체크
curl -f http://{{ .Release.Name }}-service:{{ .Values.service.port }}/health || exit 1
# API 응답 테스트
response=$(curl -s http://{{ .Release.Name }}-service:{{ .Values.service.port }}/api/v1/status)
echo "API Response: $response"
if echo "$response" | grep -q "healthy"; then
echo "API test passed"
else
echo "API test failed"
exit 1
fi
restartPolicy: Never
# templates/hooks/slack-notification.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: "{{ .Release.Name }}-slack-notification"
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "10"
"helm.sh/hook-delete-policy": "hook-succeeded"
spec:
template:
spec:
containers:
- name: notify
image: curlimages/curl:latest
env:
- name: SLACK_WEBHOOK
valueFrom:
secretKeyRef:
name: slack-webhook
key: url
command:
- sh
- -c
- |
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"🚀 {{ .Release.Name }} 배포 완료! (버전: {{ .Chart.Version }})\"}" \
$SLACK_WEBHOOK
restartPolicy: Never
command:
- sh
- -c
- |
set -e # 에러 시 즉시 종료
echo "Starting hook execution..."
# 실패 가능한 작업
if ! some_command; then
echo "ERROR: Command failed"
exit 1
fi
echo "Hook completed successfully"
spec:
template:
spec:
containers:
- name: hook
image: busybox
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
spec:
activeDeadlineSeconds: 300 # 5분 타임아웃
template:
spec:
containers:
- name: hook
image: busybox
{{- if .Values.migration.enabled }}
apiVersion: batch/v1
kind: Job
metadata:
name: "{{ .Release.Name }}-migration"
annotations:
"helm.sh/hook": pre-upgrade
# ... 나머지 설정
{{- end }}
spec:
template:
spec:
serviceAccountName: "{{ .Release.Name }}-hook-sa"
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
containers:
- name: hook
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
# Hook 상태 확인
kubectl get jobs -l "app.kubernetes.io/managed-by=Helm"
# Hook 로그 확인
kubectl logs job/myrelease-migration-hook
# Hook 이벤트 확인
kubectl describe job myrelease-migration-hook
# 현재 Hook 상태 확인
helm status myrelease
# 실패한 Hook 삭제 후 재시도
kubectl delete job myrelease-failed-hook
helm upgrade myrelease ./chart
# 수동으로 Hook 정리
kubectl delete jobs -l "helm.sh/hook"
kubectl delete pods -l "helm.sh/hook"
# weight 값 조정
"helm.sh/hook-weight": "-10" # 더 일찍 실행
"helm.sh/hook-weight": "10" # 더 늦게 실행
# 템플릿 렌더링 확인
helm template myrelease ./chart --show-only templates/hooks/
# 드라이런으로 검증
helm install myrelease ./chart --dry-run --debug
# Hook 실행 중 로그 모니터링
kubectl logs -f job/myrelease-hook-job
{{- if and .Values.database.migrate (eq .Values.environment "production") }}
# 프로덕션 환경에서만 마이그레이션 실행
{{- end }}
# 1단계: 백업
"helm.sh/hook-weight": "-10"
# 2단계: 마이그레이션
"helm.sh/hook-weight": "-5"
# 3단계: 검증
"helm.sh/hook-weight": "0"
# 롤백 시 이전 상태 복구
{{- if .Values.rollback.enabled }}
apiVersion: batch/v1
kind: Job
metadata:
annotations:
"helm.sh/hook": pre-rollback
# ... 복구 로직
{{- end }}
Helm Hook은 복잡한 애플리케이션 배포에서 필수적인 기능입니다. 적절한 Hook 사용을 통해 안전하고 신뢰할 수 있는 배포 파이프라인을 구축할 수 있습니다.