앞에서 Kustomize가 base + overlay 구조로 “공통 매니페스트 재사용 + 환경별 차이만 덮어쓰기”를 해결했다면, Helm은 같은 문제를 템플릿(Go template) + values 방식으로 풉니다. 둘 다 “환경별(dev/stage/prod)로 replicas, 이미지 태그, 리소스 제한 등을 다르게 배포”하는 데 쓰이지만, 접근 방식과 트레이드오프가 꽤 다릅니다.
Helm이 해결하는 문제(=Kustomize와 동일한 출발점)
- Kubernetes 매니페스트를 환경별로 조금씩 다르게 배포해야 한다
- 그런데 환경별로 디렉터리 복붙해서 YAML을 관리하면 리소스가 늘수록 유지보수가 깨진다
- 그래서 “공통은 재사용하고, 환경별로 바뀌는 값만” 관리하고 싶다
Helm의 핵심 방식: 템플릿(Go template) + values.yaml
Helm 차트(chart)는 크게 두 덩어리로 생각하면 됩니다.
- templates/
- 쿠버네티스 리소스 YAML처럼 보이지만, 중간중간 변수/로직이 들어간 Go 템플릿
- values.yaml (및 env별 values 파일)
- 템플릿에 들어갈 변수 값들의 모음 (환경별로 파일을 나눠서 관리)
예시: Deployment 템플릿에서 replicas를 변수로
templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}
spec:
containers:
- name: nginx
image: "nginx:{{ .Values.image.tag }}"
ports:
- containerPort: 80
여기서 중요한 포인트는:
{{ ... }}가 Helm(Go template) 문법이고.Values.replicaCount,.Values.image.tag같은 값이 values 파일에서 주입된다는 것
values.yaml로 변수 값 제공
values.yaml
replicaCount: 1
image:
tag: "1.27.3"
환경마다 replicaCount나 image.tag를 다르게 하고 싶다면, 환경별 values 파일을 별도로 둡니다.
전형적인 Helm 프로젝트 구조(환경별 values)
예를 들어 아래처럼 구성합니다.
mychart/
Chart.yaml
templates/
deployment.yaml
service.yaml
values.yaml # 기본값(디폴트)
environments/
values.dev.yaml
values.staging.yaml
values.prod.yaml
values.yaml: 공통/기본값values.<env>.yaml: 환경별로 덮어쓸 값들
예시: env별 values 파일
environments/values.dev.yaml
replicaCount: 1
image:
tag: "1.27.3-dev"
environments/values.staging.yaml
replicaCount: 2
image:
tag: "1.27.3-rc"
environments/values.prod.yaml
replicaCount: 5
image:
tag: "1.27.3"
배포 워크플로우(명령어 예시)
1) 렌더링 결과를 먼저 보고 싶을 때(매우 권장)
Helm 템플릿은 “렌더링 전에는 완전한 YAML이 아님”이 핵심 리스크라서, 배포 전에 렌더링 결과를 확인하는 습관이 좋습니다.
helm template myapp ./mychart -f environments/values.staging.yaml
또는 네임스페이스/릴리즈명까지 포함해서:
helm template myapp ./mychart \
--namespace staging \
-f environments/values.staging.yaml
2) 설치(install)
helm install myapp ./mychart \
--namespace staging --create-namespace \
-f environments/values.staging.yaml
3) 업그레이드(upgrade)
helm upgrade myapp ./mychart \
--namespace staging \
-f environments/values.staging.yaml
보통은 설치/업그레이드를 한 번에:
helm upgrade --install myapp ./mychart \
--namespace staging --create-namespace \
-f environments/values.staging.yaml
4) 릴리즈 이력/롤백(Helm이 “패키지 매니저”인 이유)
Helm은 단순히 템플릿 렌더링 도구가 아니라 릴리즈 단위로 설치/업그레이드/히스토리/롤백을 제공합니다.
helm list -n staging
helm history myapp -n staging
helm rollback myapp 2 -n staging
이 “릴리즈 관리” 성격은 Kustomize에는 없는 Helm의 강점입니다.
Helm의 장점(=Kustomize 대비 “기능이 더 많음”)
Helm은 템플릿 엔진을 갖고 있어서 다음이 가능합니다.
- 조건부 리소스 생성 (
if,else) - 반복문 (
range) - 함수/필터(문자열 가공 등)
- 훅(Hooks)로 특정 타이밍에 Job 실행(예: 마이그레이션)
예: 프로덕션에서만 HPA를 만들고 싶다면
{{- if .Values.hpa.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
...
{{- end }}
이런 “로직”은 Kustomize보다 Helm이 훨씬 강합니다.
Helm의 단점(=기능이 많은 만큼 복잡해짐)
1) 템플릿은 렌더링 전엔 “순수 YAML”이 아니다
{{ }}가 들어간 파일은 kubectl이 바로 이해하는 YAML이 아니고, 사람이 읽기에도 “실제 결과가 무엇인지” 머릿속에서 렌더링해야 합니다.
그래서 운영에서는 다음 습관이 중요합니다.
helm template로 결과를 먼저 확인helm lint로 기본 검증
helm lint ./mychart
2) 차트가 커질수록 가독성이 급격히 떨어질 수 있다
변수/조건/반복이 많아지면:
- “어떤 값이 필수인지”
- “어떤 조합에서 어떤 리소스가 생성되는지”
- “특정 환경에서 실제로 뭘 배포하는지”
파악이 어려워집니다.
실무에서는 보통 다음으로 완화합니다.
- 템플릿 로직 최소화(가능하면 values로 해결)
_helpers.tpl에 공통 로직/이름 규칙 모으기values.yaml에 주석/문서화 철저히values.schema.json로 값 스키마 검증(규모가 커지면 특히 유효)
Kustomize vs Helm: 선택 기준을 딱 잘라보면
Kustomize가 더 유리한 경우
- “기본 YAML이 그대로” 남아 있길 원한다 (가독성/리뷰 우선)
- 환경별 차이가 patch로 충분하다 (replicas, image tag, labels, namespace 등)
- 템플릿 언어/로직 없이 단순한 구조를 선호한다
- kubectl 기반 워크플로우를 유지하고 싶다
Helm이 더 유리한 경우
- 리소스 생성이 환경/옵션에 따라 크게 달라지고 조건부/반복이 필요하다
- 릴리즈 단위의 설치/업그레이드/히스토리/롤백 같은 패키지 매니저 기능이 중요하다
- 외부에 배포 가능한 “차트 패키지” 형태로 재사용/공유하고 싶다
- 복잡한 앱 스택(여러 컴포넌트)을 하나의 배포 단위로 관리하고 싶다
실무 팁: “둘 중 하나만”이 정답은 아니다
많은 팀이 실제로는 다음처럼 섞어서 씁니다.
- Helm으로 벤더 차트 설치 (ingress-nginx, cert-manager, metrics-server 같은 것들)
- 애플리케이션은 Kustomize로 overlay 관리
또는 - 애플리케이션도 Helm로 관리하되, 환경별 values를 엄격히 분리하고 렌더링 결과를 CI에서 검증
중요한 건 도구가 아니라, “환경별 드리프트(불일치)를 어떻게 막고, 변경을 어떻게 안전하게 리뷰/배포하느냐”입니다.
'CKA' 카테고리의 다른 글
| kustomize - kustomization.yaml (0) | 2026.01.08 |
|---|---|
| Kustomize - Install/Setup Kustomize (0) | 2026.01.08 |
| Kustomize (0) | 2026.01.08 |
| Helm - 정리 (1) | 2026.01.07 |
| Helm - Lifecycle Management(Upgrade/Rollback) (0) | 2026.01.07 |