Helm 차트 구축기

Helm 명령어와 배포 실습

2026. 06. 19.
KubernetesHelmDevOps

이 글의 목표: 실제로 차트를 설치/업그레이드/롤백하면서 어떤 명령어가 어떤 동작을 하는지 익힌다.


사전 준비

Helm 설치

# macOS
brew install helm
 
# 버전 확인
helm version
# version.BuildInfo{Version:"v3.x.x", ...}

kubectl이 EKS를 가리키게

aws eks update-kubeconfig \
  --region ap-northeast-2 \
  --name meeny-prod-eks
 
kubectl get nodes
# 노드 목록이 나오면 OK

⚠️ Helm은 kubectl 의 현재 컨텍스트를 그대로 사용한다. 잘못된 컨텍스트에서 install 하면 다른 클러스터에 깔린다. 항상 kubectl config current-context 로 확인.


명령어 한눈에

명령어한 줄
helm dependency updateChart.yaml의 dependencies 다운로드
helm lint차트 문법/구조 검사
helm template렌더링 결과 출력 (설치 X)
helm install새로 설치 (Release 생성)
helm upgrade기존 Release 업그레이드
helm upgrade --install있으면 upgrade, 없으면 install
helm rollback이전 revision으로 되돌림
helm list설치된 Release 목록
helm historyRelease의 변경 이력
helm get valuesRelease에 적용된 values
helm get manifestRelease의 렌더링된 매니페스트
helm uninstallRelease 제거

차트 의존성 다운로드

helm/ingress, helm/ingress-internal, helm/external-secrets 처럼 Chart.yamldependencies 가 있는 차트는 먼저 다운로드해야 install/upgrade 가능하다.

cd helm/ingress
helm dependency update
# → charts/ingress-nginx-4.9.1.tgz 가 받아짐

Chart.lock 파일이 같이 갱신된다 (실제로 받아진 정확한 버전이 기록됨).

→ Git에 커밋하는 것은 보통: Chart.lock은 커밋, charts/*.tgz 는 .gitignore에 넣고 커밋 X (재현은 lock으로 됨). 단, 우리 프로젝트는 .tgz도 커밋되어 있어서 그대로 따라가면 된다.


설치 전 검증 — lint / template / dry-run

helm lint — 차트 문법 검사

helm lint ./helm/backend
# ==> Linting ./helm/backend
# [INFO] Chart.yaml: icon is recommended
# 1 chart(s) linted, 0 chart(s) failed

helm template — 렌더링 결과를 화면에 ⭐

helm template my-test ./helm/backend -f ./helm/backend/values.yaml

→ 실제로 클러스터에 안 보내고, 이 차트가 만들 YAML이 어떤 모습인지 그대로 출력한다. 디버깅의 1번 무기.

helm install --dry-run --debug

helm install backend ./helm/backend --dry-run --debug

→ 클러스터에 적용은 안 하지만, K8s API 검증까지 수행한다. 스키마 에러를 잡을 수 있다.


첫 설치 (install)

권장 설치 순서

# ① External Secrets Operator (가장 먼저)
cd helm/external-secrets
helm dependency update
helm upgrade --install external-secrets . \
  -n external-secrets \
  --create-namespace
 
# ② Ingress Controller (외부)
cd ../ingress
helm dependency update
helm upgrade --install ingress-nginx . \
  -n ingress-nginx \
  --create-namespace
 
# ③ Ingress Controller (내부)
cd ../ingress-internal
helm dependency update
helm upgrade --install ingress-nginx-internal . \
  -n ingress-nginx-internal \
  --create-namespace
 
# ④ 우리 백엔드 앱
cd ../backend
helm upgrade --install backend . \
  -n default

--install 플래그를 항상 붙이는 이유

helm upgrade --install 는 멱등(idempotent)하다.

  • 처음이면 → install
  • 이미 있으면 → upgrade

→ CI/CD에서 "처음 배포인지 두 번째 배포인지" 분기를 안 해도 된다. 업계 표준 패턴.


업그레이드 (upgrade)

이미지 태그만 바꿀 때 (가장 흔함)

helm upgrade backend ./helm/backend \
  -n default \
  --reuse-values \
  --set image.tag=0.0.2
옵션의미
--reuse-values이전 install 때 줬던 values 재사용 + --set 만 덮어씀
--reset-values이전 values 무시 + values.yaml 다시 읽음
(둘 다 없음)values.yaml + -f + --set 만 사용 (이전 -f 는 무시됨)

⚠️ 무옵션 동작이 직관과 다르다. 헷갈릴 땐 항상 -f values.yaml 을 명시적으로 주는 게 안전.

values 파일을 바꿔서 업그레이드

helm upgrade backend ./helm/backend \
  -n default \
  -f ./helm/backend/values.yaml \
  -f ./helm/backend/values-prod.yaml   # 환경별 오버라이드

→ 뒤에 오는 -f 가 앞을 덮어쓴다.

업그레이드 후 확인

helm history backend -n default
# REVISION  STATUS      CHART                   APP VERSION  DESCRIPTION
# 1         superseded  meeny-backend-1.0.0     1.0.0        Install complete
# 2         deployed    meeny-backend-1.0.0     1.0.0        Upgrade complete
 
helm get values backend -n default
# 적용된 최신 values 확인
 
kubectl rollout status deployment/backend -n default
# Pod가 새 이미지로 굴러갔는지 확인

롤백 (rollback)

# 이전(직전) 리비전으로
helm rollback backend -n default
 
# 특정 리비전으로
helm rollback backend 5 -n default

→ Helm은 매 리비전마다 매니페스트를 K8s Secret에 보관하므로 상시 복귀 가능.

⚠️ 단, CRD나 PVC처럼 데이터가 있는 리소스는 롤백해도 데이터는 안 돌아온다. 주의.


디버깅이 필요할 때

매니페스트가 어떻게 나갔는지 보고 싶다

helm get manifest backend -n default
# kubectl get으로 보는 것과 거의 같지만, Helm이 적용한 그대로

values는 뭐가 적용됐지?

# 사용자가 명시한 values만
helm get values backend -n default
 
# 차트 기본값 + 사용자 values 모두
helm get values backend -n default --all

Pod가 안 뜬다

kubectl describe pod backend-xxxxx -n default
# Events 섹션에서 ErrImagePull, CrashLoopBackOff 등 단서 확인
 
kubectl logs backend-xxxxx -n default
kubectl logs backend-xxxxx -n default --previous   # 재시작 전 로그

ExternalSecret이 동작 안 한다

kubectl get externalsecret backend -n default -o yaml
# .status.conditions 확인
 
kubectl get clustersecretstore aws-secretsmanager -o yaml
# 인증 실패면 IRSA(SA에 IAM Role 매핑) 점검

제거 (uninstall)

helm uninstall backend -n default

→ Helm이 만든 모든 리소스(Deployment, Service, Ingress, ExternalSecret, Secret)가 함께 삭제된다.

⚠️ PVC는 남는 경우가 있다 (reclaimPolicy: Retain). 데이터 보존을 위해 일부러 그렇게 됐을 수 있으니 확인 후 수동 삭제.

⚠️ uninstall은 되돌릴 수 없다 (롤백 불가). 정말 지울지 한번 더 확인.


환경별 values 분리 패턴 (실전)

helm/backend/
├── values.yaml          # 공통 + dev 기본
├── values-staging.yaml  # staging 오버라이드만
└── values-prod.yaml     # prod 오버라이드만
# dev
helm upgrade --install backend ./helm/backend
 
# staging
helm upgrade --install backend ./helm/backend -f values-staging.yaml
 
# prod
helm upgrade --install backend ./helm/backend -f values-prod.yaml

→ 보통 차이는 replicaCount, image.tag, env.DB_URL, resources 정도. 차트 자체는 한 벌.


자주 쓰는 명령어 카드 ⭐

# 검증 3종 세트 (설치 전에 항상)
helm lint ./helm/backend
helm template backend ./helm/backend
helm upgrade --install backend ./helm/backend --dry-run --debug
 
# 실제 배포 (멱등)
helm upgrade --install backend ./helm/backend -n default
 
# 빠른 image tag 교체
helm upgrade backend ./helm/backend -n default --reuse-values --set image.tag=0.0.2
 
# 상태 확인
helm list -A
helm history backend -n default
helm get values backend -n default
helm get manifest backend -n default
 
# 롤백
helm rollback backend -n default

다음 글에서는 실패 케이스, IRSA/Secret 이슈, 서비스 헬스 점검 등 트러블슈팅을 본다.