✨ Helm의 Kubernetes 배포 모범 사례 & 📘 CKA 실전 Lab Book

:open_file_folder: Helm 차트 구조 이해하기
먼저, Helm 차트는 아래와 같이 구성하는 것이 바람직합니다:

my-helm-chart/
├── Chart.yaml
├── values.yaml
├── templates/
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── _helpers.tpl
│   └── tests/
│       └── test-connection.yaml
├── environments/
│   ├── dev-values.yaml
│   ├── uat-values.yaml
│   └── prod-values.yaml

:backhand_index_pointing_right: 기본 값은 values.yaml에 두고, 환경별로 꼭 필요한 항목만 별도의 파일에서 오버라이드하는 방식을 권장합니다.


:white_check_mark: 베스트 프랙티스 #1: 중복된 워크로드 Flatten 작업

  • 동일한 앱을 여러 번 배포할 경우, 차트를 따로 만들지 말고 Helm의 템플릿과 replica 스케일링을 사용하세요.
  • Bad:
# multiple charts for tomcat1, tomcat2, tomcat3
  • Good:
replicaCount: 3
# templates/deployment.yaml
spec:
  replicas: {{ .Values.replicaCount }}
  • Service는 Deployment 앞단에 배치해 Kubernetes의 로드밸런싱을 활용합니다:
# templates/service.yaml
spec:
  selector:
    app: {{ include "mychart.name" . }}

:globe_showing_europe_africa: 베스트 프랙티스 #2: 환경 인식 변수 사용

  • 전역 환경 변수를 values.yaml에 정의합니다:
global:
  environment: dev
  • 템플릿에서 활용:
metadata:
  labels:
    env: {{ .Values.global.environment }}
  • 프로덕션은 prod-values.yaml로 오버라이드:
global:
  environment: prod

:stethoscope: 베스트 프랙티스 #3: 헬스 체크는 필수

  • 모든 배포에 livenessProbereadinessProbe를 설정하세요.
livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 15
  periodSeconds: 10

readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5
  • 환경별로 필요 시 values 파일에서 타이밍만 조정합니다.

:package: 베스트 프랙티스 #4: Values 모듈화

  • 환경 차이를 템플릿에 하드코딩하지 않고, 별도의 values 파일을 사용합니다.
# environments/dev-values.yaml
replicaCount: 1
resources:
  limits:
    cpu: 100m
    memory: 128Mi

# environments/prod-values.yaml
replicaCount: 5
resources:
  limits:
    cpu: 500m
    memory: 512Mi
  • 배포 시:
helm install my-app-dev ./my-helm-chart -f environments/dev-values.yaml
helm install my-app-prod ./my-helm-chart -f environments/prod-values.yaml

:repeat_button: 베스트 프랙티스 #5: _helpers.tpl로 DRY(Don’t Repeat Yourself) 지키기

  • 네이밍 규칙과 라벨은 _helpers.tpl에 정의합니다:
{{- define "mychart.fullname" -}}
{{ printf "%s-%s" .Release.Name .Values.global.environment | trunc 63 | trimSuffix "-" }}
{{- end }}
  • 템플릿에서는 이렇게 사용:
metadata:
  name: {{ include "mychart.fullname" . }}

:test_tube: 베스트 프랙티스 #6: Hook으로 배포 테스트

  • 연결성을 확인하는 테스트 훅 추가:
# templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
  name: "{{ include "mychart.fullname" . }}-test-connection"
  annotations:
    "helm.sh/hook": test
spec:
  containers:
    - name: wget
      image: busybox
      command: ['wget']
      args: ['{{ include "mychart.fullname" . }}:8080/healthz']
  restartPolicy: Never
  • 실행:
helm test my-app-prod

:gear: 베스트 프랙티스 #7: 서비스 Configurable 유지

  • 개발자가 쉽게 Service 타입/포트를 바꿀 수 있도록 values에서 정의합니다:
service:
  type: LoadBalancer
  port: 80
  • 템플릿에서 반영:
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}

:label: 베스트 프랙티스 #8: 네이밍 규칙으로 혼란 방지

  • 리소스 이름에 릴리스 이름과 환경을 포함합니다:
metadata:
  name: {{ include "mychart.fullname" . }}
  • 피해야 할 문제들:
    • 환경 간 이름 중복
    • 리소스 이름 충돌 → Helm 에러
    • 모니터링 대시보드 혼란

:blue_book: CKA 합격 후 무료 랩북
20개 이상의 실전 시나리오, YAML만 사용, 시험 스타일 그대로 구성했으며, :backhand_index_pointing_right: Payhip + Gumroad에서 무료 다운로드 가능합니다.

[출처] Mastering Helm: Best Practices for Multi-Environment Kubernetes Deployments | by DevOpsDynamo | Medium