infra
Platform

모듈 맵

[Kubernetes] 복잡한 매니페스트를 차트(Chart) 단위로 원클릭 배포하기

0 / 29 완료

펼치기
0 / 29 완료0%

쿠버네티스 & GitOps · 21 / 29

[Kubernetes] 복잡한 매니페스트를 차트(Chart) 단위로 원클릭 배포하기

Helm Chart 구조와 values.yaml 오버라이드로 Kubernetes 앱을 패키지처럼 설치하고 관리합니다

🚨INCIDENT ALERT
HIGH

운영팀이 YAML 12개를 순서대로 적용하다가 Service 이름 하나를 잘못 바꿔 배포가 실패했습니다. 여러 리소스를 한 애플리케이션 단위로 설치하고 되돌리려면 패키징 도구가 필요합니다. Helm은 Kubernetes 매니페스트를 릴리스 단위로 관리하게 해줍니다.

팀에 새 개발자가 합류해서 로컬에 Redis를 띄워달라고 했습니다. helm install my-redis bitnami/redis를 입력하면 10초 만에 Redis StatefulSet, Service, Secret, ConfigMap이 모두 설치됩니다. 반면 YAML 파일을 직접 작성하면 수백 줄의 매니페스트를 작성하고, 환경마다 값을 바꾸고, 업그레이드 시 변경사항을 추적해야 합니다.

Helm은 Kubernetes의 패키지 매니저입니다. npm이 Node.js 라이브러리를 패키지로 관리하듯, Helm은 Kubernetes 애플리케이션을 Chart라는 패키지로 관리합니다. 복잡한 멀티 리소스 애플리케이션을 하나의 명령으로 설치하고, 버전별로 업그레이드하며, 문제가 생기면 이전 버전으로 롤백합니다. ArtifactHub에는 PostgreSQL, Prometheus, cert-manager 등 검증된 Chart가 수천 개 공개되어 있습니다.

이번 챕터에서 배울 것
  • 1Helm을 설치하고 핵심 개념(Chart, Release, Repository, Revision)을 설명할 수 있다
  • 2helm install/upgrade/rollback/uninstall 워크플로를 수행할 수 있다
  • 3--set과 -f로 values.yaml 오버라이드 패턴을 적용할 수 있다
  • 4ArtifactHub에서 공개 Chart를 찾아 사용할 수 있다
  • 5Helm Chart의 기본 구조를 이해할 수 있다
  • 6환경별 values 파일로 dev/staging/prod를 관리할 수 있다
실습 환경 준비
Helm 설치 확인
helm version --short

미설치라면 공식 패키지·릴리스의 버전과 체크섬을 확인한 뒤 설치

실습용 네임스페이스 생성
kubectl create namespace helm-demo
Bitnami 저장소 추가
helm repo add bitnami https://charts.bitnami.com/bitnami && helm repo update
저장소 목록 확인
helm repo list
💡개념

핵심 개념: Chart, Release, Repository, Revision

처음 Prometheus 스택을 배포할 때 Deployment, Service, ConfigMap, RBAC, ServiceMonitor 등 수십 개의 YAML을 순서대로 적용해야 했다면, 하나라도 빠지거나 순서가 틀리면 배포가 실패하는 경험을 해봤을 것입니다. Helm Chart는 이 여러 리소스를 하나의 패키지로 묶어 helm install 한 번으로 설치하고 helm rollback 한 번으로 이전 상태로 되돌릴 수 있게 해줍니다. Helm의 4가지 핵심 개념(Chart, Repository, Release, Revision)을 이해하면 "왜 같은 Chart를 여러 이름으로 설치할 수 있는지", "롤백이 어떻게 동작하는지" 를 설명할 수 있습니다.

핵심 개념: Chart, Release, Repository, Revision확대

Repository (저장소)   →   Chart (패키지)   →   Release (설치된 인스턴스)
bitnami               →   bitnami/redis    →   my-redis (helm install로 생성)
                                           →   my-redis2 (같은 Chart, 다른 이름)

Release의 변경 이력 = Revision
  Revision 1: helm install
  Revision 2: helm upgrade (이미지 업데이트)
  Revision 3: helm rollback 1 (Revision 1로 되돌림)
로컬 터미널
# 저장소 추가 및 검색
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add stable https://charts.helm.sh/stable
helm repo update

# Chart 검색
helm search repo redis
# NAME                    CHART VERSION   APP VERSION   DESCRIPTION
# bitnami/redis           18.19.4         7.2.5         Redis® is an open source, advanced key-value ...
# bitnami/redis-cluster   9.6.7           7.2.5         Redis® is an open source...

# ArtifactHub 검색 (웹 UI)
helm search hub prometheus
🔍실행 후 확인할 것
  • helm list -n <namespace>에서 STATUS 열 먼저 확인 — deployed면 정상, failed이면 helm history <release>로 실패 리비전 확인 후 helm rollback <release> <revision>으로 복구
  • REVISION 수치 기준: 1이면 최초 설치, 2 이상이면 업그레이드 이력. helm history <release>로 각 리비전의 변경 사유(DESCRIPTION)를 확인해 문제 리비전 특정
  • STATUS=deployed이지만 파드가 없으면 → Chart가 설치됐으나 렌더링된 리소스에 문제. helm template <release> <chart> --values values.yaml으로 렌더링 결과를 확인해 YAML 오류 또는 조건부 블록 누락 파악
💡개념

helm install 한 번이 클러스터 리소스가 되기까지 — 차트에서 릴리스까지 6단계

helm install my-redis bitnami/redis -f values-dev.yaml 한 줄이면 Deployment·Service·Secret·ConfigMap이 한꺼번에 생깁니다. 이 한 줄 안에서 Helm은 차트를 읽고, 값을 병합하고, 템플릿을 렌더해 완성된 매니페스트를 만든 뒤 API server에 넘기고, 그 결과를 리비전으로 기록합니다. 이 파이프라인을 단계로 알면 "값이 왜 안 먹지", "렌더가 왜 깨지지", "already exists가 왜 나지"를 어느 단계의 문제인지로 좁힐 수 있습니다.

TEXT
[사용자]  helm install my-redis bitnami/redis -f values-dev.yaml
   │
   ① 차트 로드: Chart.yaml·templates/·values.yaml을 읽고 charts/ 의존 차트 해석
   │
   ② values 병합: 차트 기본 values.yaml ← -f 파일 ← --set  (뒤일수록 우선)
   │
   ③ 템플릿 렌더링: templates/*.yaml의 .Values·.Release·.Chart 참조를 병합값으로 치환 (Go template)
   │
   ④ 매니페스트 생성: 렌더 결과를 완성된 K8s YAML 묶음으로 산출
   │    (helm template로 배포 전 미리 확인 가능)
   │
   ⑤ API server에 apply: Deployment·Service·Secret·ConfigMap을 클러스터에 생성
   │
   ⑥ 릴리스 이력 저장: 이 리비전 스냅샷을 Secret(sh.helm.release.v1.<릴리스>.v<N>)에 기록
   ▼
[클러스터]  릴리스 my-redis  (REVISION 1, STATUS deployed)

각 단계에서 무슨 일이 일어나고, 막히면 어떤 증상인가:

단계하는 일막히면 증상
① 차트 로드Chart.yaml·values.yaml·templates/를 읽고 charts/ 의존 차트 해석차트 이름·경로 오타 → chart not found · 의존 차트 미다운로드 → helm dependency update 필요
② values 병합기본 values ← -f 파일 ← --set 순으로 덮어씀(뒤일수록 우선)키 경로 오타는 조용히 무시돼 기본값이 그대로 적용 → 렌더 결과가 기대와 다름
③ 템플릿 렌더링.Values·.Release·.Chart 참조를 병합값으로 치환(Go template)필수 값 누락·문법 오류 → nil pointer evaluating·parse error로 install 중단
④ 매니페스트 생성렌더 결과를 완성된 K8s YAML 묶음으로 산출렌더는 됐지만 스키마 위반이면 ⑤ apply에서 API server가 거부
⑤ apply렌더된 리소스를 클러스터에 생성/갱신같은 이름 릴리스 존재 → release already exists(→ upgrade --install) · 권한 부족 → forbidden
⑥ 이력 저장리비전 스냅샷을 Secret(sh.helm.release.v1.<릴리스>.v<N>)에 기록중간에 끊기면 pending-upgrade로 잠겨 다음 작업이 another operation in progress로 거부

정리하면 helm install로컬에서 매니페스트를 완성(①~④) → 클러스터에 반영(⑤) → 이력 저장(⑥) 세 국면입니다. 값이 기대대로 안 먹으면 helm template으로 ③④의 렌더 결과를 배포 없이 눈으로 확인하고, apply 실패는 ⑤(이름 충돌·권한·스키마), 잠금·롤백은 ⑥의 릴리스 Secret을 봅니다. helm upgrade도 같은 파이프라인을 그대로 타되 ⑥에서 리비전이 하나 더 쌓일 뿐이라, 롤백이 곧 "예전 리비전 스냅샷을 다시 적용"이 됩니다.

💡개념

helm install과 values.yaml 오버라이드

bitnami/redis를 개발 환경에는 단일 인스턴스로, 운영 환경에는 레플리카 3개로 설치해야 할 때 Chart를 수정하면 원본이 바뀌어 업스트림 업데이트를 받기 어렵습니다. values.yaml 오버라이드는 Chart 자체는 그대로 두고 환경에 맞는 값만 주입하는 패턴입니다. --set으로 한두 개 값을, -f custom-values.yaml로 환경 전체 설정을 주입하면 동일한 Chart로 개발/스테이징/운영을 모두 관리할 수 있습니다. 이 패턴을 이해하면 helm install 명령 옵션이 왜 그렇게 설계됐는지 납득이 됩니다.

Helm vs kubectl apply — kubectl은 YAML을 직접 적용(단순 배포·소규모), Helm은 패키지(Chart) 관리. helm install로 Deployment·Service·Secret·ConfigMap을 한 번에 설치, helm upgrade/rollback으로 Revision 기반 이력·즉시 복원, values-dev/prod.yaml 오버라이드로 환경별 차이를 Git에 명확히 추적. 멀티환경·롤백·팀 공유 Chart가 필요하면 Helm확대

로컬 터미널
# 기본값으로 설치
helm install my-redis bitnami/redis -n helm-demo

# --set으로 개별 값 오버라이드
helm install my-redis bitnami/redis \
  -n helm-demo \
  --set auth.enabled=false \
  --set replica.replicaCount=1 \
  --set architecture=standalone

# Chart의 기본 values.yaml 확인 (어떤 값을 바꿀 수 있는지)
helm show values bitnami/redis | head -50

# 커스텀 values 파일 생성 (권장: 환경별 파일 관리)
cat > redis-values-dev.yaml << 'EOF'
architecture: standalone
auth:
  enabled: false
replica:
  replicaCount: 0
master:
  resources:
    requests:
      cpu: 100m
      memory: 128Mi
    limits:
      cpu: 500m
      memory: 256Mi
  persistence:
    enabled: false   # 개발환경: PVC 없이
EOF

helm install my-redis bitnami/redis \
  -n helm-demo \
  -f redis-values-dev.yaml

# 설치된 릴리스 목록
helm list -n helm-demo
# NAME       NAMESPACE   REVISION   STATUS     CHART           APP VERSION
# my-redis   helm-demo   1          deployed   redis-18.19.4   7.2.5

# 생성된 리소스 확인
helm status my-redis -n helm-demo
kubectl get all -n helm-demo
💡개념

helm upgrade와 롤백: 버전 관리

새 버전으로 helm upgrade를 실행했는데 파드가 CrashLoopBackOff에 빠졌을 때, Helm 없이 kubectl로 개별 리소스를 수동으로 이전 상태로 되돌리려면 어느 리소스가 바뀌었는지 일일이 추적해야 합니다. Helm은 모든 업그레이드를 Revision으로 기록하기 때문에 helm rollback 한 줄로 이전 상태로 되돌릴 수 있습니다. 롤백 자체도 새 Revision으로 기록되어 이력이 남고, 어떤 값으로 배포됐는지 helm get values로 확인할 수 있습니다. --upgrade --install 패턴은 처음 배포인지 재배포인지 구분 없이 동일한 명령어를 쓸 수 있어 CI/CD에서 표준으로 쓰입니다.

로컬 터미널
# 업그레이드 (값 변경)
helm upgrade my-redis bitnami/redis \
  -n helm-demo \
  -f redis-values-dev.yaml \
  --set master.resources.limits.memory=512Mi

# 릴리스 이력 확인
helm history my-redis -n helm-demo
# REVISION   STATUS     CHART           DESCRIPTION
# 1          superseded redis-18.19.4   Install complete
# 2          deployed   redis-18.19.4   Upgrade complete

# --install 플래그: 없으면 install, 있으면 upgrade (CI/CD 표준 패턴)
helm upgrade --install my-redis bitnami/redis \
  -n helm-demo \
  -f redis-values-dev.yaml \
  --create-namespace    # 네임스페이스 없으면 자동 생성

# 롤백
helm rollback my-redis 1 -n helm-demo  # Revision 1로 되돌림

helm history my-redis -n helm-demo
# REVISION   STATUS      CHART           DESCRIPTION
# 1          superseded  redis-18.19.4   Install complete
# 2          superseded  redis-18.19.4   Upgrade complete
# 3          deployed    redis-18.19.4   Rollback to 1  ← 롤백도 새 리비전

# 삭제
helm uninstall my-redis -n helm-demo
# (PVC는 삭제되지 않음 — 데이터 보호)
💡개념

Helm Chart 구조 이해

공개 Chart를 helm show values로 살펴보다 "이 값을 어디서 쓰는 거지?"라고 궁금해지거나, 직접 Chart를 만들어야 할 때 어디서 시작할지 막막하다면 Chart 디렉토리 구조를 먼저 이해해야 합니다. Chart는 Chart.yaml(메타데이터), values.yaml(기본값), templates/(Kubernetes 리소스 템플릿) 세 가지 핵심 요소로 구성되며, 각 파일의 역할을 이해하면 공개 Chart 분석과 커스텀 Chart 작성이 수월해집니다.

Helm Chart 디렉토리 구조와 템플릿 렌더링 — mychart/ 아래 Chart.yaml(메타데이터), values.yaml(기본값·오버라이드 대상), charts/(서브차트), templates/(K8s 매니페스트 템플릿: deployment.yaml·service.yaml·configmap.yaml·_helpers.tpl 공통 함수·NOTES.txt 안내), .helmignore. templates의 replicas 자리에 Values.replicaCount 참조를 넣은 자리표시자를 values.yaml의 replicaCount 3으로 채워 helm template/install 시 replicas 3인 실제 매니페스트로 렌더링된다. Release.Name은 릴리스 이름, Chart.Version은 Chart.yaml의 version으로 치환. 작업 흐름은 helm create → 편집 → helm lint → helm template 미리보기 → helm package/install이며, 환경 차이는 values-dev/prod.yaml로만 만들고 templates는 공용으로 쓴다확대

mychart/ 구조입니다.

  • Chart.yaml — Chart 메타데이터 (이름, 버전, 설명)
  • values.yaml — 기본값 정의
  • charts/ — 의존 Chart (서브차트)
  • templates/ — Kubernetes 매니페스트 템플릿
    • deployment.yaml, service.yaml, configmap.yaml
    • _helpers.tpl — 공통 템플릿 함수
    • NOTES.txt — helm install 후 출력되는 사용 안내
  • .helmignore — 패키징 제외 파일
로컬 터미널
# 새 Chart 생성
helm create mychart
ls mychart/

# templates/deployment.yaml에서 values.yaml 참조하는 방식
# {{ .Values.replicaCount }}  → values.yaml의 replicaCount 값
# {{ .Release.Name }}         → 릴리스 이름
# {{ .Chart.Version }}        → Chart 버전

# 렌더링 결과 미리 확인 (실제 배포 없이)
helm template my-release mychart/ -f custom-values.yaml

# 문법 검사
helm lint mychart/

# 패키징
helm package mychart/
# mychart-0.1.0.tgz 생성

실습: Prometheus 스택 설치 및 환경별 values 관리

로컬 터미널
# prometheus-community 저장소 추가
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

# Chart 정보 확인
helm show chart prometheus-community/kube-prometheus-stack | head -20

# 개발 환경용 values (경량화)
cat > prometheus-dev-values.yaml << 'EOF'
prometheus:
  prometheusSpec:
    retention: 24h
    resources:
      requests:
        cpu: 200m
        memory: 512Mi
      limits:
        cpu: 500m
        memory: 1Gi
grafana:
  enabled: true
  adminPassword: "dev-password-123"
  resources:
    requests:
      memory: 128Mi
alertmanager:
  enabled: false   # 개발환경에서는 알람 불필요
EOF

# 설치
helm upgrade --install monitoring \
  prometheus-community/kube-prometheus-stack \
  -n monitoring \
  --create-namespace \
  -f prometheus-dev-values.yaml \
  --timeout 5m

# 설치 상태 확인
helm list -n monitoring
kubectl get pods -n monitoring

# Grafana 접근 (포트 포워딩)
kubectl port-forward svc/monitoring-grafana 3000:80 -n monitoring &
# http://localhost:3000 (admin / dev-password-123)

새 이미지 버전으로 helm upgrade를 했는데 파드가 CrashLoopBackOff로 빠집니다. 고객 트래픽에 영향이 가기 전에 이전 버전으로 빠르게 돌려야 합니다.

로컬 터미널
# 증상: 업그레이드 후 파드가 비정상
helm list -n production
# NAME     NAMESPACE    REVISION   STATUS     CHART         APP VERSION
# myapp    production   3          deployed   myapp-2.1.0   3.0.0

kubectl get pods -n production -l app.kubernetes.io/instance=myapp
# NAME                   READY   STATUS             RESTARTS
# myapp-xxx-yyy          0/1     CrashLoopBackOff   5

# 1단계: 릴리스 이력 확인
helm history myapp -n production
# REVISION   STATUS      CHART         DESCRIPTION
# 1          superseded  myapp-1.5.0   Install complete
# 2          superseded  myapp-2.0.0   Upgrade complete
# 3          deployed    myapp-2.1.0   Upgrade complete  ← 문제 버전

# 2단계: 이전 리비전의 values 확인 (문제 확인)
helm get values myapp -n production --revision=2

# 3단계: 즉시 롤백 (이전 리비전으로)
helm rollback myapp 2 -n production
# Rollback was a success! Happy Helming!

# 4단계: 롤백 후 상태 확인
helm history myapp -n production
# REVISION   STATUS      CHART         DESCRIPTION
# 1          superseded  myapp-1.5.0   Install complete
# 2          superseded  myapp-2.0.0   Upgrade complete
# 3          superseded  myapp-2.1.0   Upgrade complete
# 4          deployed    myapp-2.0.0   Rollback to 2  ← 새 리비전으로 기록

kubectl get pods -n production -l app.kubernetes.io/instance=myapp
# NAME                   READY   STATUS    RESTARTS
# myapp-aaa-bbb          1/1     Running   0  ← 정상 복구

# 5단계: 실패 원인 파악 (CrashLoopBackOff 로그)
kubectl logs -l app.kubernetes.io/instance=myapp -n production --previous
# Error: Environment variable DB_HOST not found
# → values.yaml에서 새 버전에 추가된 필수 환경변수 누락이 원인

# 6단계: 올바른 values로 재업그레이드
helm upgrade myapp mychart/ \
  -n production \
  -f production-values.yaml \
  --set image.tag=3.0.0 \
  --set env.DB_HOST=postgres.production.svc.cluster.local

# 사전 예방: --atomic 플래그 사용 (실패 시 자동 롤백)
helm upgrade myapp mychart/ \
  -n production \
  -f production-values.yaml \
  --atomic \          # 실패 시 자동으로 이전 버전으로 롤백
  --timeout 5m \      # 타임아웃 설정
  --cleanup-on-fail   # 실패한 리소스 정리

예방: --atomic 플래그를 CI/CD에서 항상 사용하면 업그레이드 실패 시 자동으로 이전 리비전으로 롤백됩니다. helm upgrade --atomic은 프로덕션 배포의 안전망입니다.

심화 — Helm은 릴리스 상태를 클러스터에 저장한다

💡개념

심화: pending 상태와 '진행 중' 잠금 — 멈춘 릴리스를 푸는 법

helm history와 helm rollback이 마법처럼 동작하는 건 Helm이 릴리스의 각 리비전 스냅샷을 클러스터 안에 저장해 두기 때문입니다. 이 저장 방식을 알아야 멈춘 릴리스를 풀 수 있습니다.

  • 릴리스 상태는 Secret에 저장됩니다: Helm 3는 릴리스의 각 리비전을 같은 네임스페이스의 Secret(타입 sh.helm.release.v1.<release>.v<N>)에 저장합니다. helm list와 helm history는 이 Secret들을 읽어 보여주는 것입니다.
  • 작업 중에는 pending 상태가 됩니다: 업그레이드가 시작되면 릴리스 상태가 pending-upgrade가 되고, 정상 완료되면 deployed로 바뀝니다(설치는 pending-install). Helm은 이 pending 상태를 진행 중 잠금으로 취급해 동시 변경을 막습니다.
  • 중단되면 잠금이 남습니다: helm 프로세스가 --wait 도중 타임아웃·강제 종료(CI 잡 kill, 네트워크 끊김)로 죽으면 상태가 pending-upgrade에 그대로 멈춥니다. 다음 helm upgrade는 another operation (install/upgrade/rollback) is in progress로 거부됩니다 — 릴리스가 사실상 잠긴 것입니다.

그래서 이 잠금을 푸는 표준은 마지막으로 정상(deployed)이던 리비전으로 helm rollback하는 것입니다. 그러면 상태가 deployed로 정리되며 잠금이 풀립니다. --atomic과 넉넉한 --timeout을 쓰면 애초에 pending에 갇히는 걸 예방할 수 있습니다.

상황: CI에서 helm upgrade --install --wait --timeout 2m이 타임아웃으로 잡(job)이 죽었습니다. 재실행하니 곧바로 another operation ... is in progress 에러가 나며 아무 배포도 못 합니다. 파드는 어중간한 상태로 남아 있습니다.

원인: 직전 업그레이드가 완료 전에 프로세스가 죽어 릴리스 상태가 pending-upgrade에 멈췄습니다. Helm은 릴리스 상태를 클러스터의 Secret(sh.helm.release.v1.<release>.vN)에 저장하고, pending 상태를 진행 중 잠금으로 취급해 동시 작업을 막습니다. 그래서 새 upgrade가 거부됩니다.

진단: helm history <release>로 마지막 리비전의 STATUS가 pending-upgrade(또는 pending-install)인지 확인합니다. kubectl get secret -n <ns> -l owner=helm,name=<release>로 저장된 릴리스 Secret과 상태 라벨을 보고, 마지막으로 deployed였던 리비전 번호를 파악합니다.

해결: 마지막 정상 리비전으로 helm rollback <release> <deployed-rev> -n <ns>를 하면 상태가 deployed로 정리되고 잠금이 풀립니다. 이 방법은 실행 중인 파드를 유지하며 릴리스 메타데이터만 바로잡습니다. 이후 원하는 값으로 다시 helm upgrade합니다. 재발 방지로 배포에 --atomic(실패 시 자동 롤백)과 넉넉한 --timeout을 주고, CI가 helm을 강제 종료하지 않도록 파이프라인 타임아웃을 helm --timeout보다 길게 잡습니다.

💼
실무 맥락
현업 패턴

시나리오: 신규 서비스를 Helm Chart로 패키징해 팀과 공유

직접 작성한 FastAPI 서비스를 Helm Chart로 패키징해서 팀원들이 쉽게 다양한 환경에 배포할 수 있도록 합니다.

로컬 터미널
# 1단계: Chart 생성
helm create fastapi-service
cd fastapi-service/

# 2단계: Chart.yaml 수정
cat > Chart.yaml << 'EOF'
apiVersion: v2
name: fastapi-service
description: FastAPI 마이크로서비스
type: application
version: 0.1.0
appVersion: "1.0.0"
EOF

# 3단계: values.yaml 설계
cat > values.yaml << 'EOF'
replicaCount: 2

image:
  repository: myregistry/fastapi-service
  tag: "latest"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 8000

resources:
  requests:
    cpu: 200m
    memory: 256Mi
  limits:
    cpu: 500m
    memory: 512Mi

env:
  DATABASE_URL: "postgresql://localhost/mydb"
  LOG_LEVEL: "info"

probes:
  liveness:
    path: /healthz
  readiness:
    path: /ready
    initialDelaySeconds: 15
EOF

# 4단계: 환경별 values 파일
cat > values-production.yaml << 'EOF'
replicaCount: 5
image:
  tag: "v1.2.3"    # 프로덕션은 고정 태그
resources:
  requests:
    cpu: 500m
    memory: 512Mi
  limits:
    cpu: 2
    memory: 1Gi
env:
  DATABASE_URL: "postgresql://prod-db.internal/mydb"
  LOG_LEVEL: "warning"
EOF

# 5단계: 개발 환경 배포
helm upgrade --install fastapi-dev ./fastapi-service \
  -n development \
  --create-namespace \
  --atomic

# 6단계: 프로덕션 배포
helm upgrade --install fastapi-prod ./fastapi-service \
  -n production \
  --create-namespace \
  -f values-production.yaml \
  --atomic \
  --timeout 3m

# 7단계: Chart를 OCI 레지스트리에 푸시 (팀 공유)
helm package ./fastapi-service/
helm push fastapi-service-0.1.0.tgz oci://ghcr.io/myorg/charts

# 팀원이 설치
helm install my-api oci://ghcr.io/myorg/charts/fastapi-service --version 0.1.0

실무 포인트: 같은 Chart로 -f values-dev.yaml, -f values-staging.yaml, -f values-prod.yaml을 통해 세 환경을 관리하면 환경 간 설정 차이가 명확하게 git으로 추적됩니다. ArtifactHub의 공개 Chart는 처음부터 사용하되, 커스텀이 많이 필요하면 직접 Chart를 만들어 내부 저장소(Harbor, GHCR)에 관리하는 것이 현실적입니다.

실습 단계
1

Helm 저장소 추가 및 Chart 검색

helm repo add bitnami https://charts.bitnami.com/bitnami helm repo update helm search repo redis | head -3

예상 출력

NAME                    CHART VERSION   APP VERSION   DESCRIPTION
bitnami/redis           18.x.x         7.x.x         Redis(R) is an open source...
2

Redis Chart 기본 values 확인 후 단순 설치

helm show values bitnami/redis | grep -E '^architecture:|^auth:' | head -4 helm install my-redis bitnami/redis --set architecture=standalone --set auth.enabled=false -n helm-demo

예상 출력

NAME: my-redis
LAST DEPLOYED: ...
STATUS: deployed
3

설치된 릴리스 목록 및 상태 확인

helm list -n helm-demo kubectl get pods -n helm-demo | grep redis

예상 출력

NAME       NAMESPACE   REVISION   STATUS     CHART
my-redis   helm-demo   1          deployed   redis-
4

릴리스 업그레이드 및 이력 확인

helm upgrade my-redis bitnami/redis --set architecture=standalone --set auth.enabled=false --set master.resources.limits.memory=512Mi -n helm-demo helm history my-redis -n helm-demo

예상 출력

REVISION   STATUS     CHART         DESCRIPTION
1          superseded redis-...     Install complete
2          deployed   redis-...     Upgrade complete
5

롤백 후 정리

helm rollback my-redis 1 -n helm-demo helm list -n helm-demo helm uninstall my-redis -n helm-demo

예상 출력

Rollback was a success! Happy Helming!
Release "my-redis" uninstalled

핵심 요약

명령어설명
helm repo add <name> <url>저장소 추가
helm search repo <keyword>Chart 검색
helm show values <chart>기본 values.yaml 보기
helm install <release> <chart>신규 설치
helm upgrade --install <release> <chart>설치 또는 업그레이드
helm list -n <namespace>설치된 릴리스 목록
helm history <release>릴리스 이력 (리비전 확인)
helm rollback <release> <revision>특정 리비전으로 롤백
helm uninstall <release>릴리스 삭제
helm template <release> <chart>렌더링 미리보기 (배포 없이)

명령어·단축키 빠른 참조

이 모듈에서 다룬 helm 명령을 실전 옵션·조합과 함께 모았습니다. "예" 열은 CI/CD에서 바로 쓰는 형태로 정리했습니다.

명령어/단축키용도자주 쓰는 예
helm repo add / update차트 저장소 등록·갱신helm repo add bitnami https://charts.bitnami.com/bitnami && helm repo update
helm search repo / hub등록 저장소·ArtifactHub 검색helm search repo redis, helm search hub prometheus
helm show values오버라이드 가능한 기본값 확인helm show values bitnami/redis | head -50
helm upgrade --install없으면 설치·있으면 업그레이드(멱등, CI 표준)helm upgrade --install api ./chart -f prod.yaml --atomic --timeout 5m
--set / -f개별 값 / 파일로 values 오버라이드--set auth.enabled=false, -f redis-values-dev.yaml
--create-namespace릴리스 대상 네임스페이스 자동 생성helm upgrade --install app ./chart -n prod --create-namespace
helm list -n릴리스 목록·STATUS 확인helm list -n monitoring (deployed/failed/pending)
helm history릴리스 리비전 이력helm history myapp -n production (롤백 대상 특정)
helm get values리비전별 적용된 values 확인helm get values myapp -n production --revision=2
helm rollback특정 리비전으로 즉시 복구helm rollback myapp 2 -n production
helm template / lint배포 없이 렌더링·문법 검증helm template rel ./chart -f prod.yaml, helm lint ./chart
helm package / push패키징·OCI 레지스트리 배포helm package ./chart && helm push chart-0.1.0.tgz oci://ghcr.io/org/charts

관련 모듈로 더 깊이:

다음 모듈 helm-chart-dev에서는 직접 Helm Chart를 작성하는 방법을 다룹니다. Go 템플릿 문법, _helpers.tpl 재사용 패턴, helm lint와 helm template으로 Chart를 검증하는 실무 워크플로를 익힙니다.

지식 확인

퀴즈 — 8문제

Q1

CI/CD 파이프라인에서 'helm install'을 쓰면 두 번째 실행부터 'release already exists' 오류가 난다. 이 문제를 해결하는 가장 올바른 방법은?

Q2

helm rollback my-release 2 명령어가 하는 일은?

Q3

values.yaml에 정의된 기본값을 배포 시 오버라이드하는 올바른 방법은?

Q4

helm history my-release를 보니 REVISION 3이 현재(deployed)다. helm rollback my-release 2를 실행하면 REVISION 번호는 어떻게 되는가?

Q5

환경별로 다른 수십 개의 값을 오버라이드해야 한다. --set 나열보다 권장되는 방법은?

Q6

운영 CI에서 첫 배포든 재배포든 같은 명령으로 안전하게 처리하려면?

Q7

[심화] helm history로 보니 릴리스의 마지막 리비전 STATUS가 pending-upgrade다. 이 상태가 의미하는 것은?

Q8

[심화] 파이프라인 타임아웃으로 helm upgrade가 중간에 끊긴 뒤, 재실행이 another operation is in progress로 계속 거부된다. 서비스 영향을 최소화하며 푸는 표준 방법은?

0 / 8 답변

🧪 실습으로 확인하기

K8s 기초 — Pod/Deployment/Service 생성

초급

kubectl로 nginx Pod를 생성하고 Deployment와 Service를 차례로 만들어 클러스터 외부에서 접근 가능한 상태까지 구성한다. K8s 3대 리소스의 역할과 관계를 직접 손으로 익힌다.

55📋 5단계💻 직접 환경
실습 시작하기 →

이것도 배워보세요