-
[Helm] 토픽 - Chart Hooks와 Chart Test공부/쿠버네티스&헬름 2025. 3. 9. 20:33
Chart Hooks
Helm은 차트 개발자가 릴리스의 수명 주기에서 특정 시점에 개입할 수 있도록 훅(hook) 메커니즘을 제공합니다. 훅을 사용하면 다음과 같은 작업을 수행할 수 있습니다.
- 다른 차트가 로드되기 전에 설치 중에 ConfigMap 또는 Secret을 로드
- 새 차트를 설치하기 전에 데이터베이스를 백업하는 Job을 실행하고 업그레이드 후 데이터를 복원하는 두 번째 Job을 실행
- 릴리스를 삭제하기 전에 Job을 실행하여 서비스를 제거하기 전 서비스를 정상적으로 로테이션에서 제거합니다.
hook은 일반 템플릿처럼 작동하지만 Helm이 다르게 활용하도록 하는 특수 어노테이션이 있습니다.
사용 가능한 hook
Annotation Value 설명 pre-install
템플릿이 렌더링된 후, Kubernetes에서 리소스가 생성되기 전에 실행됩니다. post-install
모든 리소스가 Kubernetes에 로드된 후 실행됩니다. pre-delete
Kubernetes에서 리소스가 삭제되기 전에 삭제 요청에서 실행됩니다. post-delete
모든 릴리스 리소스가 삭제된 후 삭제 요청에 대해 실행됩니다. pre-upgrade
템플릿이 렌더링되고 리소스가 업데이트되기 전에 업그레이드 요청에서 실행됩니다. post-upgrade
모든 리소스가 업그레이드된 후 업그레이드 요청에 대해 실행됩니다. pre-rollback
템플릿이 렌더링된 후, 리소스가 롤백되기 전에 롤백 요청에서 실행됩니다. post-rollback
모든 리소스가 수정된 후 롤백 요청 시 실행됩니다. test
Helm 테스트 하위 명령이 호출될 때 실행됩니다(테스트 문서 보기) hook과 release 라이프사이클
Helm 훅은 차트 개발자가 릴리스 수명 주기의 전략적 지점에서 작업을 수행할 수 있는 기회를 제공합니다. 예를 들어,
helm install
의 수명 주기를 살펴보겠습니다. 기본적으로 수명 주기는 다음과 같습니다.기본
helm install
수명 주기- 사용자가
helm install foo
를 실행 - Helm 라이브러리 설치 API가 호출
- 일부 검증 후 라이브러리가
foo
템플릿을 렌더링 - 라이브러리가 결과 리소스를 Kubernetes에 로드
- 라이브러리가 릴리스 객체(및 기타 데이터)를 클라이언트에 반환
- 클라이언트가 종료
Helm은
install
수명 주기에 대해pre-install
과post-install
두 가지 훅을 정의합니다.foo
차트 개발자가 두 훅을 모두 구현하면 수명 주기는 다음과 같이 변경됩니다.훅이 적용된
helm install
수명 주기- 사용자가
helm install foo
를 실행 - Helm 라이브러리 설치 API가 호출
crds/
디렉토리의 CRD가 설치- 일부 검증 후 라이브러리가
foo
템플릿을 렌더링 - 라이브러리가
pre-install
훅을 실행할 준비(훅 리소스를 Kubernetes에 로드) - 라이브러리는 가중치(기본적으로 0 할당), 리소스 종류, 이름 순으로 오름차순으로 훅을 정렬
- 라이브러리는 가장 낮은 가중치의 훅부터 로드(음수에서 양수 순)
- 라이브러리는 훅이 "준비"될 때까지 대기(CRD 제외)
- 라이브러리는 결과 리소스를 Kubernetes에 로드
-wait
플래그가 설정된 경우 라이브러리는 모든 리소스가 준비 상태가 될 때까지 기다리며 준비가 완료될 때까지post-install
훅을 실행하지 않음
- 라이브러리는
post-install
훅을 실행(훅 리소스 로드) - 라이브러리는 훅이 "준비"될 때까지 대기
- 라이브러리가 릴리스 객체(및 기타 데이터)를 클라이언트에 반환
- 클라이언트가 종료
훅이 "준비될 때까지 기다린다"는 것은 훅에 선언된 리소스에 따라 의미가 달라집니다.
Job 또는 Pod 리소스의 경우, Helm은 해당 리소스가 성공적으로 완료될 때까지 기다립니다. 훅이 실패하면 릴리스도 실패하며 이것은 블로킹 작업이므로 Job이 실행되는 동안 Helm 클라이언트는 일시 중지됩니다.
다른 모든 리소스 종류의 경우, Kubernetes가 리소스를 로드됨(추가 또는 업데이트됨)으로 표시하는 즉시 해당 리소스는 "준비"된 것으로 간주됩니다. 하나의 훅에 여러 리소스가 선언된 경우, 리소스는 순차적으로 실행됩니다. 훅 가중치가 있는 경우(아래 참조), 가중치 순서대로 실행됩니다. Helm 3.2.0부터는 동일한 가중치를 가진 훅 리소스는 일반적인 비 훅 리소스와 동일한 순서로 설치됩니다. 그렇지 않으면 순서가 보장되지 않습니다. (Helm 2.3.0 이후에는 알파벳순으로 정렬되지만, 이 동작은 구속력이 있는 것으로 간주되지 않으며 향후 변경될 수 있습니다.) 훅 가중치를 추가하고 가중치가 중요하지 않은 경우
0
으로 설정하는 것이 좋은 방법으로 간주됩니다.Helm 훅 리소스가 해당 릴리스와 함께 관리되지 않음
Helm 훅이 생성하는 리소스는 현재 릴리스의 일부로 추적되거나 관리되지 않습니다. Helm은 훅이 준비 상태에 도달했음을 확인하면 훅 리소스를 그대로 둡니다. 해당 릴리스가 삭제될 때 훅 리소스의 가비지 수집은 향후 Helm 3에 추가될 수 있으므로 삭제해서는 안 되는 모든 훅 리소스에는
helm.sh/resource-policy: keep
어노테이션을 추가해야 합니다.실질적으로 이는 훅에서 리소스를 생성하는 경우
helm uninstall
을 사용하여 리소스를 제거할 수 없다는 것을 의미합니다. 이러한 리소스를 제거하려면 훅 템플릿 파일에 사용자 정의helm.sh/hook-delete-policy
어노테이션을 추가하거나 Job 리소스의 TTL(time to live) 필드를 설정해야 합니다.Hook 쓰기
훅은
metadata
섹션에 특수 어노테이션이 있는 Kubernetes 매니페스트 파일입니다. 템플릿 파일이므로.Values
,.Release
,.Template
을 읽는 것을 포함하여 모든 일반적인 템플릿 기능을 사용할 수 있습니다.예를 들어
templates/post-install-job.yaml
에 저장된 이 템플릿은post-install
에서 실행될 작업을 선언합니다.apiVersion: batch/v1 kind: Job metadata: name: "{{ .Release.Name }}" labels: app.kubernetes.io/managed-by: {{ .Release.Service | quote }} app.kubernetes.io/instance: {{ .Release.Name | quote }} app.kubernetes.io/version: {{ .Chart.AppVersion }} helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" annotations: # This is what defines this resource as a hook. Without this line, the # job is considered part of the release. "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 }}"]
이 템플릿을 훅으로 만드는 것은
"helm.sh/hook": post-install
어노테이션입니다.하나의 리소스가 여러 개의 훅을 구현할 수 있습니다.
"helm.sh/hook": post-install,post-upgrade
마찬가지로, 특정 훅을 구현할 수 있는 다양한 리소스의 수에는 제한이 없습니다. 예를 들어, 시크릿과 configmap을 모두
pre-install
훅으로 선언할 수 있습니다.하위 차트가 훅을 선언하면 해당 훅도 평가됩니다. 최상위 차트가 하위 차트에서 선언된 훅을 비활성화할 수 있는 방법은 없습니다.
결정적인 실행 순서를 만드는 데 도움이 되는 훅의 가중치를 정의할 수 있습니다. 가중치는
"helm.sh/hook-weight": "5"
어노테이션을 사용하여 정의됩니다.훅 가중치는 양수 또는 음수일 수 있지만 문자열로 표현해야 합니다. Helm이 특정 종류의 훅 실행 주기를 시작하면 해당 훅을 오름차순으로 정렬합니다.
훅 삭제 정책
훅 리소스를 삭제할 시기를 결정하는 정책을 정의할 수 있습니다. 훅 삭제 정책은 다음 어노테이션을 사용하여 정의됩니다.
annotations: "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
정의된 어노테이션 값을 하나 이상 선택할 수 있습니다.
Annotation Value 설명 before-hook-creation
새로운 후크가 시작되기 전에 이전 리소스를 삭제합니다(기본값) hook-succeeded
후크가 성공적으로 실행된 후 리소스를 삭제합니다. hook-failed
실행 중에 후크가 실패하면 리소스를 삭제합니다. Chart Test
Helm 차트는 함께 작동하는 여러 Kubernetes 리소스 및 구성 요소를 포함합니다. 차트 작성자는 차트가 설치될 때 예상대로 작동하는지 검증하는 몇 가지 테스트를 작성해야 할 수 있습니다. 이러한 테스트는 차트 사용자가 차트가 수행해야 하는 작업을 이해하는 데도 도움이 됩니다.
Helm 차트의 테스트는
templates/
디렉토리에 있으며 실행할 주어진 명령으로 컨테이너를 지정하는 작업 정의입니다. 테스트가 성공한 것으로 간주되려면 컨테이너가 성공적으로 종료(종료 0)되어야 합니다. 작업 정의에는 Helm 테스트 훅 어노테이션helm.sh/hook: test
가 포함되어야 합니다.Helm v3 이전에는 작업 정의에 다음 Helm 테스트 훅 어노테이션 중 하나가 포함되어야 했습니다:
helm.sh/hook: test-success
또는helm.sh/hook: test-failure
.helm.sh/hook: test-success
는 여전히helm.sh/hook: test
의 이전 버전과의 호환성을 위한 대안으로 허용됩니다.test 예시는 다음과 같습니다.
values.yaml
파일의 구성이 올바르게 삽입되었는지 검증- 사용자 이름과 비밀번호가 올바르게 작동하는지 확인
- 잘못된 사용자 이름과 비밀번호가 작동하지 않는지 확인
- 서비스가 실행 중이고 올바르게 로드 밸런싱되는지 확인
helm test <RELEASE_NAME>
명령을 사용하여 릴리스에서 미리 정의된 테스트를 Helm에서 실행할 수 있습니다. 차트 사용자에게 이는 차트(또는 애플리케이션) 릴리스가 예상대로 작동하는지 확인하는 좋은 방법입니다.사용자는 원하는 만큼의 테스트를 단일 YAML 파일에 정의하거나
templates/
디렉토리에 있는 여러 YAML 파일에 분산할 수 있습니다. 더욱 격리된 환경을 위해 테스트 모음을tests/<chart-name>/templates/tests/
다음과 같은 디렉토리 아래에 중첩할 수 있습니다. test는 Helm 훅이므로,helm.sh/hook-weight
및helm.sh/hook-delete-policy
와 같은 어노테이션을 test 리소스에 사용할 수 있습니다.test 예시
helm create 명령은 자동으로 여러 폴더와 파일을 생성합니다. helm 테스트 기능을 시도하려면 먼저 데모 helm 차트를 만듭니다.
$ helm create demo
이제 데모 헬름 차트에서 다음 구조를 볼 수 있습니다.
demo/ Chart.yaml values.yaml charts/ templates/ templates/tests/test-connection.yaml
demo/templates/tests/test-connection.yaml
시도할 수 있는 테스트가 표시됩니다. helm 테스트 파드 정의는 여기에서 확인할 수 있습니다.apiVersion: v1 kind: Pod metadata: name: "{{ include "demo.fullname" . }}-test-connection" labels: {{- include "demo.labels" . | nindent 4 }} annotations: "helm.sh/hook": test spec: containers: - name: wget image: busybox command: ['wget'] args: ['{{ include "demo.fullname" . }}:{{ .Values.service.port }}'] restartPolicy: Never
어노테이션에
"helm.sh/hook": test
로 인해helm test
명령을 실행하면 위 파드가 실행됩니다.$ helm install demo demo --namespace default $ helm test demo NAME: demo LAST DEPLOYED: Mon Feb 14 20:03:16 2022 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: demo-test-connection Last Started: Mon Feb 14 20:35:19 2022 Last Completed: Mon Feb 14 20:35:23 2022 Phase: Succeeded [...]
레퍼런스