포스트

Helm Chart 작성방법 (3)

_helpers.tpl을 활용한 Template 구조화 전략

Helm Chart 작성방법 (3)

Helm Chart의 규모가 커질수록, Template 파일 곳곳에 반복되는 코드와 공통 로직이 늘어나게 된다. 이러한 중복을 줄이고 Chart를 구조적으로 관리하기 위해 Helm은 _helpers.tpl이라는 공용 Template 파일을 제공한다.

_helpers.tpl은 Helm Chart 내에서 사용하는 Go template 조각(template definitions)을 모아두는 파일

  • 파일명은 관례적으로 _helpers.tpl
  • _로 시작하는 이유는 Kubernetes 리소스로 렌더링되지 않기 때문

즉, _helpers.tpl 자체는 YAML 리소스를 생성하지 않는다.

Helm이 _helpers.tpl을 처리하는 방식


Helm은 templates/ 디렉터리 아래의 모든 .yaml, .tpl 파일을 한 번 전부 로드

  • .yaml → 실제 리소스 생성 가능
  • .tpl → define된 template만 메모리에 등록

_helpers.tpl에 정의된 것은:

  • 출력되지 않음
  • include/template으로 호출될 때만 사용

핵심 문법: define


1
2
3
4
5
{{- define "mychart.name" -}}
my-value
{{- end -}}

  • "mychart.name": 템플릿 이름 (문자열)
  • 내부는 일반 Go template 문법
  • define 자체는 아무것도 출력하지 않음

호출 문법: include VS template


include

1
2
3
{{ include "mychart.name" . }}

  • 반환값: 문자열
  • pipe(|) 사용 가능

template

1
2
3
{{ template "mychart.name" . }}

  • 즉시 출력
  • 문자열로 취급되지 않음
  • pipe 사용 불가

include 사용이 표준에 가깝다.

_helpers.tpl 에서의 컨텍스트(.)


.는 호출 시 전달된 컨텍스트

1
2
3
{{ include "mychart.fullname" . }}

helpers 내부에서의 .는:

  • 호출 시 두 번째 인자로 전달한 객체

_helpers.tpl에서 정의하는 것들


이름 관련 함수

1
2
3
4
5
{{- define "mychart.name" -}}
{{ .Chart.Name }}
{{- end -}}

1
2
3
4
5
{{- define "mychart.fullname" -}}
{{ printf "%s-%s" .Release.Name .Chart.Name }}
{{- end -}}

label / selector 생성

1
2
3
4
5
6
{{- define "mychart.labels" -}}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}

호출:

1
2
3
4
labels:
{{ include "mychart.labels" . | indent 2 }}

include 결과는 문자열이므로, 반드시 nindent 같은 들여쓰기 함수와 함께 사용

주의 사항


Scope 관련 주의 점

잘못된 예:

1
2
3
4
5
{{- define "mychart.test" -}}
{{ .Values.foo }}
{{- end -}}

호출:

1
2
3
{{ include "mychart.test" .Values }}

→ helpers 내부에서 .Values 접근 불가 (scope 변경됨)

올바른 예:

1
2
3
{{ include "mychart.text" . }}

들여쓰기 누락

1
2
3
4
labels:
  {{ include "mychart.labels" . }}

❌ YAML Syntax 에러

→ 반드시:

1
2
3
4
labels:
{{ include "mychart.labels" . | nindent 2 }}

Context 잘못 전달

1
2
3
{{ include "mychart.fullname" .Values }}

→ helpers 내부에서 .Chart, .Release 접근 불가

디버깅 방법


렌더링 결과 확인

1
2
3
4
helm template myrel ./mychart \
  --namespace test \
  -f values.yaml \
  --debug
  • --debug: 실패 시 에러 위치/스택 확인 용이

특정 템플릿만 보고 싶을 때

1
2
3
helm template myrel ./mychart -f values.yaml \
  --show-only templates/deployment.yaml \
  --debug

값/컨텍스트 구조 확인: toYaml + nindent

템플릿에 임시로 넣기

1
2
3
4
# DEBUG dot:
# {{ toYaml . | nindent 2 }}

# DEBUG 주석

  • # 이후는 YAML 파서가 무시
  • Kubernetes 리소스에도 아무 영향 없음
  • Helm 템플릿 엔진을 주석 안의 ``도 정상적으로 평가 즉, “Helm은 평가하고, YAML은 무시한다”는 점을 이용한 디버깅 기법

특정 부분만

1
2
3
4
# DEBUG Values.persistence:
# {{ toYaml .Values.persistence | nindent 2 }}

include에 인자 넘겨서 확인: dict 활용

호출 시:

1
2
3
{{ include "mychart.debug" (dict "root" . "val" .Values.persistence) }}

helpers

1
2
3
4
5
6
7
{{- define "mychart.debug" -}}
rootChart: {{ .root.Chart.Name }}
val:
{{- toYaml .val | nindent 2 -}}
{{- end -}}

타입 확인: kindOf, kindIs

1
2
3
4
# DEBUG kind: {{ kindOf .Values.someValue }}
# DEBUG isString: {{ kindIs "string" .Values.someValue }}

lint + debug

1
helm lint ./mychart --strict