Helm Chart 실전 가이드: 차트 구조

Kubernetes 매니페스트를 직접 관리하다 보면, 환경마다 달라지는 설정값을 복사-붙여넣기하게 되고, 수십 개의 YAML 파일이 산재하면서 배포가 점점 고통스러워집니다. Helm은 이 문제를 ‘차트’라는 패키지 단위로 해결하는 Kubernetes 패키지 매니저입니다.

이 글에서는 Helm 차트의 구조를 뜯어보고, values.yaml로 환경별 설정을 분리하며, 템플릿 함수·조건·반복으로 유연한 매니페스트를 만드는 방법, 그리고 운영에서 반드시 알아야 할 릴리스 관리와 롤백 패턴까지 정리합니다.

1. Helm이 해결하는 문제

Kubernetes 리소스를 kubectl apply로 직접 관리할 때 겪는 대표적 문제 세 가지입니다.

문제 kubectl apply Helm
환경별 설정 분기 파일 복사 or kustomize overlay values 파일 오버라이드 한 줄
배포 이력·롤백 수동 추적, 이전 버전 YAML 보관 필요 릴리스 리비전 자동 기록, helm rollback 한 줄
재사용·공유 팀마다 YAML 복사 차트 레포지토리로 버전 관리·배포

2. 차트 디렉터리 구조

helm create로 생성되는 기본 구조입니다. 각 파일의 역할을 명확히 이해해야 커스터마이징이 가능합니다.

my-app/
├── Chart.yaml          # 차트 메타데이터 (이름, 버전, appVersion)
├── values.yaml         # 기본 설정값 (사용자가 오버라이드)
├── charts/             # 의존 차트 (subchart)
├── templates/          # Go 템플릿 기반 K8s 매니페스트
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── hpa.yaml
│   ├── _helpers.tpl    # 공통 템플릿 함수 정의
│   ├── NOTES.txt       # 설치 후 출력 메시지
│   └── tests/
│       └── test-connection.yaml
└── .helmignore         # 패키징 제외 파일

Chart.yaml에서 version은 차트 자체의 버전이고, appVersion은 차트가 배포하는 애플리케이션의 버전입니다. 이 둘을 혼동하면 릴리스 추적이 엉킵니다.

3. values.yaml과 환경별 오버라이드

values.yaml은 차트의 기본 설정입니다. 환경별로 다른 설정은 별도 파일로 분리해 -f 플래그로 오버라이드합니다.

# values.yaml (기본값)
replicaCount: 1
image:
  repository: my-app
  tag: "1.0.0"
  pullPolicy: IfNotPresent

resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 500m
    memory: 256Mi

ingress:
  enabled: false
  host: ""
# values-production.yaml
replicaCount: 3
image:
  tag: "1.2.5"

resources:
  requests:
    cpu: 500m
    memory: 512Mi
  limits:
    cpu: "2"
    memory: 1Gi

ingress:
  enabled: true
  host: app.example.com
# 개발
helm install my-app ./my-app

# 프로덕션
helm install my-app ./my-app -f values-production.yaml

# 단일 값 오버라이드
helm install my-app ./my-app --set replicaCount=5

우선순위: --set > -f 마지막 파일 > -f 첫 파일 > values.yaml 순입니다. CI/CD에서 이미지 태그만 동적으로 바꿀 때 --set image.tag=$CI_COMMIT_SHA를 쓰면 됩니다.

4. 템플릿 함수·조건·반복 실전 패턴

Helm 템플릿은 Go template 기반입니다. 자주 쓰는 패턴 세 가지를 정리합니다.

조건부 리소스 생성

{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: {{ include "my-app.fullname" . }}
spec:
  rules:
    - host: {{ .Values.ingress.host }}
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: {{ include "my-app.fullname" . }}
                port:
                  number: 80
{{- end }}

반복으로 다중 환경변수 주입

# values.yaml
env:
  NODE_ENV: production
  LOG_LEVEL: info
  DB_HOST: mysql.default.svc

# deployment.yaml
env:
{{- range $key, $value := .Values.env }}
  - name: {{ $key }}
    value: {{ $value | quote }}
{{- end }}

_helpers.tpl 공통 함수

{{/* templates/_helpers.tpl */}}

{{- define "my-app.fullname" -}}
{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" }}
{{- end }}

{{- define "my-app.labels" -}}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version }}
{{- end }}

_helpers.tpl에 정의한 함수는 모든 템플릿에서 {{ include "my-app.fullname" . }}로 호출합니다. 레이블, 이름, 셀렉터를 일관되게 유지하는 핵심입니다.

5. 릴리스 관리: install·upgrade·rollback

Helm은 배포마다 릴리스 리비전을 자동으로 기록합니다. 문제가 생기면 한 줄로 이전 버전으로 돌아갈 수 있습니다.

# 최초 설치
helm install my-app ./my-app -f values-production.yaml

# 업그레이드 (리비전 +1)
helm upgrade my-app ./my-app -f values-production.yaml --set image.tag=1.3.0

# 리비전 이력 확인
helm history my-app

# 이전 리비전으로 롤백
helm rollback my-app 2

# 설치 or 업그레이드 (없으면 설치, 있으면 업그레이드)
helm upgrade --install my-app ./my-app -f values-production.yaml
명령 동작 실무 팁
helm install 릴리스가 없을 때만 성공 CI/CD에서는 upgrade –install 선호
helm upgrade 기존 릴리스 업데이트 –atomic 플래그로 실패 시 자동 롤백
helm rollback 지정 리비전으로 복원 롤백도 새 리비전으로 기록됨
helm uninstall 릴리스 + 리소스 전체 삭제 –keep-history로 이력만 보존 가능

6. 배포 전 검증: lint·template·dry-run

차트를 클러스터에 적용하기 전에 반드시 검증 단계를 거쳐야 합니다.

# 문법 검증
helm lint ./my-app

# 렌더링된 매니페스트 확인 (클러스터 미접속)
helm template my-app ./my-app -f values-production.yaml

# dry-run: 서버 측 검증 포함 (클러스터 접속 필요)
helm install my-app ./my-app --dry-run --debug

# diff 플러그인: 변경사항 미리 보기
helm diff upgrade my-app ./my-app -f values-production.yaml

helm template은 클러스터 없이 로컬에서 최종 YAML을 출력합니다. CI 파이프라인 초기 단계에서 이 명령으로 렌더링 에러를 잡으면, 실제 배포에서 실패할 확률을 크게 줄일 수 있습니다.

7. 실전에서 자주 하는 실수 5가지

  1. Chart.yaml version을 올리지 않고 배포 — 캐시된 이전 차트가 적용되어 변경이 반영되지 않습니다. 차트를 수정하면 반드시 version을 올리세요.
  2. values.yaml에 시크릿 평문 포함 — Git에 커밋되면 유출됩니다. helm-secrets 플러그인이나 External Secrets Operator를 쓰세요.
  3. –set으로 복잡한 값 전달 — 리스트나 중첩 객체를 –set으로 쓰면 이스케이프 지옥이 됩니다. -f 파일을 쓰는 것이 안전합니다.
  4. _helpers.tpl 미사용 — 이름·레이블·셀렉터를 템플릿마다 직접 쓰면 불일치가 발생합니다. 반드시 공통 함수로 추출하세요.
  5. helm upgrade 시 –atomic 미사용 — 배포 실패 시 리소스가 반쯤 업데이트된 상태로 남습니다. --atomic을 붙이면 실패 시 자동 롤백됩니다.

마무리

Helm은 Kubernetes 배포를 패키지화하고, 환경별 설정 분리와 릴리스 이력 관리를 체계적으로 만들어주는 도구입니다. values 오버라이드, 템플릿 조건/반복, lint·template 검증, 그리고 –atomic 롤백까지 조합하면 안정적인 배포 파이프라인을 구축할 수 있습니다.

Kubernetes 운영을 더 깊이 다루고 싶다면, Kubernetes Taints & Tolerations 심화 가이드GitHub Actions CI/CD 파이프라인 설계 가이드도 참고해보세요.

Helm 차트 템플릿 보일러플레이트가 필요하신가요?
이 글에서 다룬 values 분리, _helpers.tpl, healthcheck probe, HPA를 포함한 프로덕션용 Helm 차트 스타터 템플릿을 준비했습니다. 아래 댓글로 “템플릿”이라고 남겨주시면 보내드립니다.

📥 관련 무료 이북

쿠버네티스 입문 가이드 — 실전 가이드 무료 제공

무료로 받기 →

위로 스크롤
WordPress Appliance - Powered by TurnKey Linux