헬름 사용법

차트 생성 명령

  • helm create 차트명
  • 차트명 디렉토리가 생성되며 그 아래에 기본 템플릿이 만들어짐
$ helm create helm1
Creating helm1
$ tree helm1       
helm1
├── Chart.yaml
├── charts
├── templates
   ├── _helpers.tpl
   ├── deployment.yaml
   ├── hpa.yaml
   ├── httproute.yaml
   ├── ingress.yaml
   ├── NOTES.txt
   ├── service.yaml
   ├── serviceaccount.yaml
   └── tests
       └── test-connection.yaml
└── values.yaml

4 directories, 11 files

챠트 구조

  • Chart.yaml: 차트 파일
  • values.yaml: 디폴트 값 저장 파일
  • charts: 종속성 차트 파일이 저장되는 디렉토리
  • templates: 차트에 속하는 리소스에 대한 쿠버네티스 매니페스트가 저장되는 디렉토리

Chart.yaml 파일

  • 챠트 정의 파일
    • 필수 항목
      • apiVersion: 차트 API 버전
      • name: 차트 이름
      • version: 차트 버전
    • 옵션 항목
      • appVersion: 애플리케이션 버전
      • type: application 또는 library
apiVersion: v2
name: anvil
version: 0.1.0
description: A Helm chart for Kubernetes
appVersion: "1.16.0"

템플릿

  • templates 디렉토리 아래의 .yaml 파일과 .tpl 파일
  • 리소스 매니페스트 파일을 만들기 위한 템플릿
  • 이 템플릿에 values.yaml 파일의 값을 렌더링하여 리소스 매니페스트 파일을 생성

.tpl 파일

  • .tpl 파일에서는 .yaml 파일내에서 사용할 블럭(named template)을 정의
  • 블럭(named template)
    • { define "블럭명" } 문장으로 시작
    • { end } 문장으로 종료
  • .tpl 파일의 이름은 관례상 _(밑줄)기호로 시작
  • _helper.tpl 파일
    • 자동 생성
    • 다음과 같은 6개 블럭 정의
      • 차트명.fullname
        • 모든 리소스의 이름으로 사용됨
      • 차트명.selectorLabels
        • delplyment, service 등 포드 선택이 필요한 리소스에 사용
        • app.kubernetes.io/name: 차트명.name 값 사용
        • app.kubernetes.io/instance: helm install 명령시 인수로 주어지는 릴리스 이름 사용
      • 차트명.labels
        • 모든 리소스에 공통 라벨로 사용
        • helm.sh/chart: 차트명.chart 값 사용
        • app.kubernetes.io/version: Chart.yaml 파일에서 appVersion 값을 지정한 경우 이 값
        • app.kubernetes.io/managed-by: Helm 이라는 문자열로 고정
      • 차트명.name
        • app.kubernetes.io/name 라벨 값으로 사용
      • 차트명.chart
        • helm.sh/chart 라벨 값으로 사용
      • 차트명.serviceAccountName
{{/*
Expand the name of the chart.
*/}}
{{- define "helm1.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "helm1.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "helm1.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "helm1.labels" -}}
helm.sh/chart: {{ include "helm1.chart" . }}
{{ include "helm1.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "helm1.selectorLabels" -}}
app.kubernetes.io/name: {{ include "helm1.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Create the name of the service account to use
*/}}
{{- define "helm1.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "helm1.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

.yaml 파일

  • 쿠버네티스 리소스를 정의하는 템플릿 파일
  • 미리 정의된 값이 { } 안에 렌더링 됨
  • 두 가지 렌더링 방식
    • { 키_경로 }: 키의 값을 렌더링
      • { .Chart.키_경로 }: Chart.yaml 파일의 값을 렌더링
      • { .Values.키_경로 }: values.yaml 파일의 값을 렌더링
      • { .Release.키_경로 }: helm install 명령 실행시 인수 값들을 렌더링
        • { .Release.Service }: helm을 사용하는 경우 Helm이라는 값
        • { .Release.Name }: 릴리스 이름
        • { .Release.Namespace }: 네임스페이스 이름
    • { include 블럭_이름 컨텍스트 }: .tpl 파일에서 정의된 블럭(named template)을 렌더링
      • 컨텍스트: 템플릿의 블럭 템플릿이 받을 값의 범위
        • .: 현재 사용하고 있는 컨텍스트를 블럭 템플릿에 넘김
        • $: 루트 컨텍스트를 블럭 템플릿에 넘김

공백 처리

  • .tpl 파일에서 블럭을 정의하거나 .yaml 파일에서 렌더링할 때 공백을 처리하는 방법
    • { ... } : 앞뒤 공백/개행을 그대로
    • {- ... } : 앞쪽 공백/개행을 제거
    • { ... -} : 뒤쪽 공백/개행을 제거
    • {- ... -} : 앞뒤 모두 공백/개행을 제거
  • .tpl 파일에서
    • define 문은 반드시 앞뒤 공백을 제거하고 end 문은 반드시 앞 공백을 제거해야 함

      {{- define "XXX" --}}
      
      {{- end }}
  • .yaml 템플릿 파일에서
    • include 사용시
      • 한 줄에 속성 이름과 값을 쓰고 값에만 렌더링이 되는 경우에는 `{{ include … }}`` 사용
      • 하위 노드를 포함한 노드 전체가 렌더링되는 경우에는 `{{- include … | nindent N }}`` 사용

차트 렌더링 명령

  • helm template 차트명 차트디렉토리 명령으로 생성되는 리소스 매니페스트를 미리 볼 수 있음
helm template helm1 .
---
# Source: helm1/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: helm1
  labels:
    helm.sh/chart: helm1-0.1.0
    app.kubernetes.io/name: helm1
    app.kubernetes.io/instance: helm1
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
automountServiceAccountToken: true
---
# Source: helm1/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: helm1
  labels:
    helm.sh/chart: helm1-0.1.0
    app.kubernetes.io/name: helm1
    app.kubernetes.io/instance: helm1
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: helm1
    app.kubernetes.io/instance: helm1
---
# Source: helm1/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: helm1
  labels:
    helm.sh/chart: helm1-0.1.0
    app.kubernetes.io/name: helm1
    app.kubernetes.io/instance: helm1
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: helm1
      app.kubernetes.io/instance: helm1
  template:
    metadata:
      labels:
        helm.sh/chart: helm1-0.1.0
        app.kubernetes.io/name: helm1
        app.kubernetes.io/instance: helm1
        app.kubernetes.io/version: "1.16.0"
        app.kubernetes.io/managed-by: Helm
    spec:
      serviceAccountName: helm1
      containers:
        - name: helm1
          image: "nginx:1.16.0"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
---
# Source: helm1/templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
  name: "helm1-test-connection"
  labels:
    helm.sh/chart: helm1-0.1.0
    app.kubernetes.io/name: helm1
    app.kubernetes.io/instance: helm1
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
  annotations:
    "helm.sh/hook": test
spec:
  containers:
    - name: wget
      image: busybox
      command: ['wget']
      args: ['helm1:80']
  restartPolicy: Never

앱 설치 명령

  • helm 차트로 만들어진 앱을 쿠버네티스에 설치하려면 helm install 명령을 사용한다.
  • helm install 릴리스_이름 챠트_디렉토리
  • 릴리스 이름은 차트 이름과 달라도 된다.
  • 차트 이름은 app.kubernetes.io/name 라벨에
  • 릴리스 이름은 app.kubernetes.io/instance 라벨에
$ ls 
helm1

$ helm install helm1a helm1
NAME: helm1a
LAST DEPLOYED: Mon Jun  1 14:58:14 2026
NAMESPACE: default
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=helm1,app.kubernetes.io/instance=helm1a" -o jsonpath="{.items[0].metadata.name}")
  export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT

$ kubectl get sa,svc,deploy,pod  -l app.kubernetes.io/name=helm1
NAME                    SECRETS   AGE
serviceaccount/helm1a   0         14m

NAME             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/helm1a   ClusterIP   10.43.85.177   <none>        80/TCP    14m

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/helm1a   1/1     1            1           14m

NAME                          READY   STATUS    RESTARTS   AGE
pod/helm1a-6777c58455-mgcc8   1/1     Running   0          14m

$ ubectl get sa,svc,deploy,pod  -l app.kubernetes.io/instance=helm1a
NAME                    SECRETS   AGE
serviceaccount/helm1a   0         144m

NAME             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/helm1a   ClusterIP   10.43.85.177   <none>        80/TCP    144m

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/helm1a   1/1     1            1           144m

NAME                          READY   STATUS    RESTARTS   AGE
pod/helm1a-6777c58455-mgcc8   1/1     Running   0          144m

앱 삭제 명령

  • helm 차트로 만들어지고 쿠버네티스에 설치된 앱을 쿠버네티스에서 삭제하려면 helm uninstall 명령을 사용한다.
  • helm install 앱_릴리스_이름