- Authors

- Name
- Youngju Kim
- @fjvbn20031
1. 네이밍 규칙
1.1 차트 이름
- 소문자만 사용, 하이픈으로 단어 구분
- 63자 이내 (DNS 서브도메인 규칙)
- 예:
my-web-app,backend-api,data-pipeline
1.2 리소스 이름
# _helpers.tpl의 fullname은 릴리스 이름 + 차트 이름 조합
# 63자 제한을 반드시 준수
{{- define "my-chart.fullname" -}}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
1.3 표준 레이블
Kubernetes 공식 권장 레이블:
# templates/_helpers.tpl
{{- define "my-chart.labels" -}}
app.kubernetes.io/name: {{ include "my-chart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/component: "backend"
app.kubernetes.io/part-of: "my-platform"
app.kubernetes.io/managed-by: {{ .Release.Service }}
helm.sh/chart: {{ include "my-chart.chart" . }}
{{- end }}
| 레이블 | 용도 |
|---|---|
| app.kubernetes.io/name | 애플리케이션 이름 |
| app.kubernetes.io/instance | 릴리스 인스턴스 이름 |
| app.kubernetes.io/version | 앱 버전 |
| app.kubernetes.io/component | 컴포넌트 역할 (frontend, backend, database) |
| app.kubernetes.io/part-of | 상위 시스템 이름 |
| app.kubernetes.io/managed-by | 관리 도구 (Helm) |
| helm.sh/chart | 차트 이름-버전 |
2. Values 설계
2.1 Flat vs Nested 구조
# Flat 구조 - 단순하지만 관련 설정 그룹화 어려움
imageRepository: nginx
imageTag: '1.25'
imagePullPolicy: IfNotPresent
# Nested 구조 - 권장
image:
repository: nginx
tag: '1.25'
pullPolicy: IfNotPresent
권장: 논리적으로 관련된 값은 중첩(nested) 구조로 그룹화합니다.
2.2 기본값(Defaults) 전략
# values.yaml - 합리적인 기본값 제공
replicaCount: 1
image:
repository: nginx
tag: '' # 비어있으면 Chart.appVersion 사용
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 80
ingress:
enabled: false
className: ''
annotations: {}
hosts: []
tls: []
# 빈 객체/리스트로 확장 포인트 제공
podAnnotations: {}
podLabels: {}
nodeSelector: {}
tolerations: []
affinity: {}
extraEnvVars: []
extraVolumes: []
extraVolumeMounts: []
2.3 required와 기본값
# 필수값은 required 함수로 강제
image: {{ required "image.repository is required" .Values.image.repository }}
# 선택적 값은 default로 안전하게 처리
tag: {{ .Values.image.tag | default .Chart.AppVersion }}
# 복잡한 기본값 로직
{{- if .Values.persistence.existingClaim }}
claimName: {{ .Values.persistence.existingClaim }}
{{- else }}
claimName: {{ include "my-chart.fullname" . }}-data
{{- end }}
3. 멀티 환경 관리
3.1 Values 파일 레이어링
values.yaml # 기본값 (차트에 포함)
values-common.yaml # 공통 오버라이드
values-dev.yaml # 개발 환경
values-staging.yaml # 스테이징 환경
values-production.yaml # 프로덕션 환경
# 환경별 배포
helm upgrade --install my-app ./my-chart \
-f values-common.yaml \
-f values-production.yaml \
--set image.tag=v2.1.0
3.2 환경별 values 예시
# values-production.yaml
replicaCount: 3
image:
pullPolicy: Always
resources:
limits:
cpu: '2'
memory: 2Gi
requests:
cpu: 500m
memory: 512Mi
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 20
targetCPUUtilizationPercentage: 70
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: app.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: app-tls
hosts:
- app.example.com
podDisruptionBudget:
enabled: true
minAvailable: 2
4. 서브차트와 엄브렐라 차트
4.1 서브차트 패턴
개별 컴포넌트를 독립적인 차트로 관리:
my-platform/
Chart.yaml
values.yaml
charts/
frontend/
backend-api/
worker/
4.2 엄브렐라 차트
여러 서브차트를 하나로 묶어 전체 시스템을 배포:
# Chart.yaml
apiVersion: v2
name: my-platform
version: 1.0.0
type: application
dependencies:
- name: frontend
version: '2.x.x'
repository: 'file://charts/frontend'
- name: backend-api
version: '3.x.x'
repository: 'file://charts/backend-api'
- name: redis
version: '17.x.x'
repository: 'https://charts.bitnami.com/bitnami'
condition: redis.enabled
- name: postgresql
version: '12.x.x'
repository: 'https://charts.bitnami.com/bitnami'
condition: postgresql.enabled
4.3 서브차트 vs 엄브렐라 선택 기준
| 기준 | 서브차트 | 엄브렐라 차트 |
|---|---|---|
| 독립 배포 | 가능 | 불가 (전체 배포) |
| 버전 관리 | 컴포넌트별 독립 | 전체 통합 |
| 복잡도 | 낮음 | 높음 |
| 적합한 경우 | 마이크로서비스 개별 관리 | 전체 플랫폼 일괄 배포 |
5. GitOps 통합
5.1 ArgoCD + Helm
# ArgoCD Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/helm-charts
targetRevision: main
path: charts/my-app
helm:
releaseName: my-app
valueFiles:
- values.yaml
- values-production.yaml
parameters:
- name: image.tag
value: 'v2.1.0'
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
5.2 Flux + HelmRelease
# Flux HelmRelease
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: my-app
namespace: production
spec:
interval: 10m
chart:
spec:
chart: my-app
version: '>=1.0.0'
sourceRef:
kind: HelmRepository
name: my-charts
namespace: flux-system
values:
replicaCount: 3
image:
repository: myregistry/my-app
tag: v2.1.0
valuesFrom:
- kind: ConfigMap
name: my-app-values
valuesKey: production.yaml
upgrade:
remediation:
retries: 3
rollback:
timeout: 5m
5.3 GitOps에서의 Values 관리 패턴
gitops-repo/
apps/
my-app/
base/
kustomization.yaml
helmrelease.yaml
overlays/
dev/
kustomization.yaml
values.yaml
staging/
kustomization.yaml
values.yaml
production/
kustomization.yaml
values.yaml
6. 보안 Best Practices
6.1 이미지 태그 관리
# 나쁜 예: latest 태그 사용
image:
tag: latest
# 좋은 예: 불변(immutable) 태그 또는 다이제스트 사용
image:
tag: "v2.1.0"
# 또는 다이제스트
# digest: sha256:abc123...
6.2 시크릿 관리
# 나쁜 예: values에 시크릿 평문 저장
database:
password: 'my-secret-password'
# 좋은 예: 외부 시크릿 참조
# helm-secrets, External Secrets Operator, Sealed Secrets 사용
externalSecret:
enabled: true
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
6.3 리소스 제한 필수화
# values.schema.json에서 resources 필수화
{
'required': ['resources'],
'properties': { 'resources': { 'type': 'object', 'required': ['limits', 'requests'] } },
}
6.4 SecurityContext 기본 적용
# values.yaml 기본값
podSecurityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containerSecurityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
7. 차트 유지보수
7.1 버전 관리 전략
- Chart version: 차트 구조/템플릿 변경 시 증가 (SemVer)
- appVersion: 배포하는 애플리케이션 버전
- 두 버전은 독립적으로 관리
7.2 CHANGELOG 관리
# Chart.yaml annotations
annotations:
artifacthub.io/changes: |
- kind: added
description: Add HPA support
- kind: changed
description: Update default resource limits
- kind: fixed
description: Fix ingress TLS configuration
7.3 deprecation 전략
# values.yaml에서 deprecated 값 처리
{{- if .Values.oldConfig }}
{{- fail "oldConfig is deprecated. Use newConfig instead." }}
{{- end }}
# 또는 경고 메시지 출력
{{- if .Values.oldConfig }}
{{- printf "WARNING: oldConfig is deprecated and will be removed in v3.0. Use newConfig instead." | fail }}
{{- end }}
8. 정리
Helm 차트 설계 Best Practices 요약:
- 네이밍과 레이블: Kubernetes 공식 레이블 표준 준수, 63자 제한
- Values 설계: Nested 구조, 합리적 기본값, 확장 포인트 제공
- 멀티 환경: Values 파일 레이어링으로 환경별 구성 관리
- 서브차트/엄브렐라: 컴포넌트 독립성과 전체 배포 편의성 균형
- GitOps 통합: ArgoCD Application 또는 Flux HelmRelease로 선언적 배포
- 보안: 불변 태그, 외부 시크릿 관리, SecurityContext 기본 적용
- 유지보수: SemVer, CHANGELOG, deprecation 전략