본문 바로가기
Infra2025년 4월 7일9분 읽기

Helm Chart 작성법 — Kubernetes 앱 패키징

YS
김영삼
조회 320

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환경별 명확한 분리
Helmfilehelmfile.yaml로 선언적 관리멀티 차트 오케스트레이션
ArgoCD 연동GitOps 기반 자동 동기화Git이 Single Source of Truth
  • 시크릿은 values.yaml에 평문으로 넣지 말고 External Secrets Operator나 Sealed Secrets를 사용하세요
  • 차트 버전과 앱 버전을 분리하여 관리하면 차트 구조 변경과 앱 업데이트를 독립적으로 추적할 수 있습니다

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록