Helm이란
Helm은 Kubernetes의 패키지 매니저입니다. 여러 Kubernetes 리소스(Deployment, Service, ConfigMap 등)를 하나의 Chart로 묶어 배포, 업그레이드, 롤백을 관리합니다. 환경별 값만 바꾸면 동일한 차트로 dev/staging/production 배포가 가능합니다.
Chart 디렉토리 구조
my-app/
├── Chart.yaml # 차트 메타데이터
├── values.yaml # 기본 설정 값
├── values-prod.yaml # 프로덕션 오버라이드
├── templates/
│ ├── _helpers.tpl # 공통 헬퍼 템플릿
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── configmap.yaml
│ └── secret.yaml
└── charts/ # 의존 차트
Chart.yaml 작성
apiVersion: v2
name: my-app
description: FastAPI 기반 REST API 서비스
type: application
version: 1.2.0 # Chart 버전
appVersion: "3.1.0" # 앱 버전
dependencies:
- name: postgresql
version: "13.x"
repository: https://charts.bitnami.com/bitnami
condition: postgresql.enabled
- name: redis
version: "18.x"
repository: https://charts.bitnami.com/bitnami
condition: redis.enabled
values.yaml 설정
# values.yaml - 기본 설정
replicaCount: 2
image:
repository: registry.example.com/my-app
tag: "3.1.0"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
targetPort: 8000
ingress:
enabled: true
className: nginx
hosts:
- host: api.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: api-tls
hosts:
- api.example.com
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilization: 70
env:
DATABASE_URL: "postgresql://user:pass@db:5432/app"
REDIS_URL: "redis://redis:6379"
LOG_LEVEL: "info"
템플릿 작성
# 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 }}
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-app.fullname" . }}
labels:
{{- include "my-app.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
app.kubernetes.io/name: {{ .Chart.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
annotations:
checksum/config: {{ include (print .Template.BasePath "/configmap.yaml") . | sha256sum }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- containerPort: {{ .Values.service.targetPort }}
envFrom:
- configMapRef:
name: {{ include "my-app.fullname" . }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
livenessProbe:
httpGet:
path: /health
port: {{ .Values.service.targetPort }}
initialDelaySeconds: 10
readinessProbe:
httpGet:
path: /ready
port: {{ .Values.service.targetPort }}
initialDelaySeconds: 5
배포 및 관리 명령어
# 의존성 설치
helm dependency update ./my-app
# 템플릿 렌더링 확인 (드라이런)
helm template my-release ./my-app -f values-prod.yaml
# 린트 검사
helm lint ./my-app
# 배포
helm install my-release ./my-app -n production --create-namespace
helm upgrade my-release ./my-app -f values-prod.yaml -n production
# 롤백
helm rollback my-release 1 -n production
# 히스토리 확인
helm history my-release -n production
환경별 관리 팁
| 전략 | 방법 | 장점 |
|---|---|---|
| 값 파일 분리 | values-dev.yaml, values-prod.yaml | 환경별 명확한 분리 |
| Helmfile | helmfile.yaml로 선언적 관리 | 멀티 차트 오케스트레이션 |
| ArgoCD 연동 | GitOps 기반 자동 동기화 | Git이 Single Source of Truth |
- 시크릿은 values.yaml에 평문으로 넣지 말고 External Secrets Operator나 Sealed Secrets를 사용하세요
- 차트 버전과 앱 버전을 분리하여 관리하면 차트 구조 변경과 앱 업데이트를 독립적으로 추적할 수 있습니다
댓글 0