Ssoon

Helm : 5.2 - 템플릿 간 문장 재사용 본문

CICD Study [1기]

Helm : 5.2 - 템플릿 간 문장 재사용

구구달스 2025. 10. 19. 14:20

 

🧩 Helm 템플릿 간에 Statement 재사용하기 (Reusing Statements Between Templates)

Helm Chart를 사용하다 보면 여러 YAML 템플릿 파일(template) 사이에서 동일한 코드 조각을 반복해서 사용하는 경우가 많습니다.
예를 들어 DeploymentService 템플릿 모두에서 selector 필드에 동일한 label을 정의해야 할 때가 있습니다.
이때, 한 곳만 수정해도 전체 템플릿에 반영되도록 _helpers.tpl 파일을 활용할 수 있습니다.


⚙️ 문제 상황 (Problem)

  • 간단한 애플리케이션을 Helm으로 Kubernetes에 배포했다고 가정해 봅시다.
    이 애플리케이션은 다음 두 개의 템플릿으로 구성되어 있습니다.
    • Deployment
    •  
  • 두 파일 모두 app.kubernetes.io/name이라는 label을 동일하게 사용하고 있습니다.
    • Deployment
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/pacman$ cat templates/deployment.yaml
...
spec:
  replicas: {{ .Values.replicaCount }}     # replicaCount 속성을 넣을 자리 placeholder
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ .Chart.Name}}
  template:
    metadata:
      labels:
        app.kubernetes.io/name: {{ .Chart.Name}}
...
  • Service
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/pacman$ cat templates/service.yaml
...
spec:
...
  selector:
    app.kubernetes.io/name: {{ .Chart.Name }}
  • 여기서 만약 selector에 새로운 label을 추가해야 한다면, Deployment와 Service 두 파일 모두를 수정해야 합니다.
    즉, 동일한 부분을 여러 곳에서 중복 관리해야 하는 비효율이 발생합니다.

💡 “Helm은 _helpers.tpl 파일을 사용하여 중복되는 템플릿 로직을 재사용할 수 있습니다.”


🧱 해결 방법 (Solution)

  • Helm은 templates/ 디렉토리 안에 _helpers.tpl 파일을 정의할 수 있도록 지원합니다.
    이 파일에 재사용 가능한 statement(템플릿 조각) 을 만들어 두면,다른 템플릿 파일에서 include 문법으로 불러와 사용할 수 있습니다.

🧩 Step 1. _helpers.tpl 파일 생성

templates/_helpers.tpl 파일을 생성하고, 아래 내용을 작성합니다.

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/pacman$ cat << EOF > templates/_helpers.tpl
{{- define "pacman.selectorLabels" -}}   # stetement 이름을 정의
app.kubernetes.io/name: {{ .Chart.Name}} # 해당 stetement 가 하는 일을 정의
{{- end }}
EOF
  • define : statement(함수) 이름을 정의합니다.
  • "pacman.selectorLabels" : statement의 이름으로, 나중에 include로 호출할 때 사용됩니다.
  • 내부의 코드는 실제로 재사용할 로직을 작성합니다.

💡 "pacman.selectorLabels"는 일종의 함수 이름이며, include를 통해 다른 템플릿에서 호출할 수 있습니다.


🧩 Step 2. 다른 템플릿에서 include 사용하기

  • 이제 기존 템플릿(deployment.yaml, service.yaml)의 중복된 부분을 아래와 같이 변경합니다.
    • deployment.yaml
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/pacman$ cat templates/deployment.yaml
...
spec:
  replicas: {{ .Values.replicaCount }}     # replicaCount 속성을 넣을 자리 placeholder
  selector:
    matchLabels:
      #app.kubernetes.io/name: {{ .Chart.Name}}
      {{- include "pacman.selectorLabels" . | nindent 6 }}   #📌 pacman.selectorLabels를 호출한 결과를 6만큼 들여쓰기하여 주입
  template:
    metadata:
      labels:
        #app.kubernetes.io/name: {{ .Chart.Name}}
        {{- include "pacman.selectorLabels" . | nindent 8 }} #📌 pacman.selectorLabels를 호출한 결과를 8만큼 들여쓰기하여 주입
...
  • service.yaml
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/pacman$ cat templates/service.yaml
...
  selector:
    #app.kubernetes.io/name: {{ .Chart.Name }}
    {{- include "pacman.selectorLabels" . | nindent 6 }}
  • include "pacman.selectorLabels" . : _helpers.tpl의 statement를 호출합니다.
  • | nindent N : 들여쓰기를 정렬하기 위해 사용합니다 (N은 공백 수).

💡 “include 키워드로 _helpers.tpl의 statement를 불러오고, nindent로 올바른 YAML 포맷을 유지합니다.”


🧩 Step 3. Helm Chart 렌더링 테스트

  • 이제 템플릿이 잘 동작하는지 확인하기 위해 Helm Chart를 로컬에서 렌더링해봅니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/pacman$ helm template .
...
  selector:
    #app.kubernetes.io/name: pacman
      # stetement 이름을 정의
      app.kubernetes.io/name: pacman #📌 해당 stetement 가 하는 일을 정의
---
# Source: pacman/templates/deployment.yaml
...
spec:
  replicas: 1     # replicaCount 속성을 넣을 자리 placeholder
  selector:
    matchLabels:
      #app.kubernetes.io/name: pacman
      # stetement 이름을 정의
      app.kubernetes.io/name: pacman # 해당 stetement 가 하는 일을 정의   #📌 pacman.selectorLabels를 호출한 결과를 6만큼 들여쓰기하여 주입
  template:
    metadata:
      labels:
        #app.kubernetes.io/name: pacman
        # stetement 이름을 정의
        app.kubernetes.io/name: pacman # 해당 stetement 가 하는 일을 정의 #📌 pacman.selectorLabels를 호출한 결과를 8만큼 들여쓰기하여 주입
...

 

💡 “이제 selector가 _helpers.tpl의 정의를 통해 자동으로 일관되게 반영됩니다.”


🧩 Step 4. Selector 수정 시 단 한 곳만 변경

  • 이제 selector에 새로운 label을 추가해야 할 때는 Deployment나 Service 파일이 아닌 _helpers.tpl 파일만 수정하면 됩니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/pacman$ cat << EOF > templates/_helpers.tpl
{{- define "pacman.selectorLabels" -}}
app.kubernetes.io/name: {{ .Chart.Name}}
app.kubernetes.io/version: {{ .Chart.AppVersion}}
{{- end }}
EOF
  • 이제 다시 렌더링을 수행합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/pacman$ helm template .
...
  selector:
    #app.kubernetes.io/name: pacman
      app.kubernetes.io/name: pacman
      app.kubernetes.io/version: 1.0.0	#📌
---
...
metadata:
  name: pacman            # Chart.yaml 파일에 설정된 이름을 가져와 설정
  labels:
    app.kubernetes.io/name: pacman     # Chart.yaml 파일에 appVersion 여부에 따라 버전을 설정
    app.kubernetes.io/version: "1.0.0"     # appVersion 값을 가져와 지정하고 따움표 처리
spec:
  replicas: 1     # replicaCount 속성을 넣을 자리 placeholder
  selector:
    matchLabels:
      #app.kubernetes.io/name: pacman
      app.kubernetes.io/name: pacman
      app.kubernetes.io/version: 1.0.0   #📌 pacman.selectorLabels를 호출한 결과를 6만큼 들여쓰기하여 주입
  template:
    metadata:
      labels:
        #app.kubernetes.io/name: pacman
        app.kubernetes.io/name: pacman
        app.kubernetes.io/version: 1.0.0 #📌 pacman.selectorLabels를 호출한 결과를 8만큼 들여쓰기하여 주입
...

 

💡 “하나의 파일만 수정해도 모든 템플릿에 자동 반영됩니다. 유지보수성과 일관성이 크게 향상됩니다.”


📘 Figure

파일명 역할 설명

_helpers.tpl 재사용 가능한 statement 정의 중복되는 템플릿 코드를 한 곳에 모아 관리
deployment.yaml Pod 배포 템플릿 selector와 label에 include 적용
service.yaml Service 템플릿 selector에 include 적용

💬 Discussion

  • Helm에서는 일반적으로 _helpers.tpl 파일을 사용해 statement를 정의합니다.
  • 하지만 꼭 이름이 _helpers.tpl일 필요는 없습니다.
  • _(언더스코어)로 시작하는 모든 파일은 Helm이 자동으로 읽어 statement 정의를 인식합니다.

💡 “Helm은 _helpers.tpl뿐만 아니라 _로 시작하는 모든 파일의 함수를 인식합니다.”


📌 핵심 요약

  • 중복된 템플릿 로직은 _helpers.tpl에 정의해 재사용할 수 있습니다.
  • define 키워드로 statement를 정의하고, include로 호출합니다.
  • nindent를 사용하면 YAML 들여쓰기가 자동으로 맞춰집니다.
  • label이나 selector 수정 시, 오직 _helpers.tpl만 수정하면 전체에 반영됩니다.
  • _helpers.tpl 이외에도 _로 시작하는 파일이면 Helm이 모두 읽습니다.

✅ “Helm 템플릿에서 반복되는 부분은 _helpers.tpl로 추출해 일관성과 유지보수성을 높이세요.”

 
Comments