콘텐츠로 이동
Study NoteCKA

Helm — 패키지 설치와 릴리스 관리

결론부터
Helm은 차트와 값을 조합해 설치하고, 그 결과를 릴리스로 추적해 업그레이드와 롤백을 수행한다.

매니페스트가 많은 컴포넌트를 환경에 맞게 설치하고 되돌려야 할 때 Helm을 쓴다. 차트·값·릴리스의 관계를 먼저 보고 설치, 설정 변경, 롤백을 따라간다. YAML의 환경별 변형은 Kustomize에서 다룬다.

Helm이 푸는 문제는 “남이 만든 수십 장짜리 매니페스트를, 내 환경 값으로 바꿔서 통째로 설치하고 통째로 되돌리는 일”이다. 여기서 두 가지 장치가 나온다 — 바뀔 자리를 구멍으로 뚫어 둔 템플릿, 그리고 설치한 결과를 한 덩어리로 기억하는 릴리스. 앞의 것이 있어서 값 하나만 바꿔 재사용할 수 있고, 뒤의 것이 있어서 kubectl apply로는 불가능한 롤백과 일괄 삭제가 된다.

선언된 상태를 apiserver에 넣는 주체가 하나 더 생기는 것일 뿐, 그 뒤의 루프(시작하기 전에)는 달라지지 않는다 — Helm은 클러스터 밖에서 YAML을 만들어 보내는 도구다.

Chart

패키지. 템플릿 + 기본값의 묶음.

Values

차트에 주입하는 설정값.

Release

클러스터에 설치된 차트의 인스턴스. 이름이 있고, 같은 차트를 여러 번 설치할 수 있다.

Repository

차트를 배포하는 곳.

  • 디렉터리mychart/
    • Chart.yaml 이름, 버전, 의존성
    • values.yaml 기본값
    • 디렉터리templates/ Go 템플릿이 섞인 매니페스트
      • deployment.yaml
      • service.yaml
      • _helpers.tpl
    • 디렉터리charts/ 서브차트
      • …

트리에서 시험에 필요한 것은 values.yaml(무엇을 바꿀 수 있는가)과 Chart.yaml(무엇을 설치하는가) 둘이다. templates/의 Go 템플릿 문법이나 공용 조각을 모아두는 _helpers.tpl, 의존 차트를 담는 charts/는 차트를 만드는 쪽 이야기라 이름만 알아두면 된다.

같은 차트를 다른 이름의 릴리스로 여러 번 설치할 수 있다. 릴리스 정보는 네임스페이스의 Secret에 저장된다 (Helm 3부터. Helm 2의 서버 컴포넌트였던 Tiller는 없어졌다).

이 “릴리스 정보”가 Helm의 상태 관리 전부다 — 어떤 차트를 어떤 값으로 설치했고 지금 리비전이 몇 번인지가 그 Secret에 들어 있다. helm rollback이 가능한 이유이자, 클러스터에 Helm 전용 서버가 따로 없는 이유이기도 하다. Helm 2 시절에는 그 역할을 클러스터 안의 Tiller가 맡았고 권한 문제로 악명이 높았다 — 지금은 없어졌으니 이름만 알고 지나가면 된다.

  1. 저장소 등록

    터미널 창
    helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
    helm repo update
    helm repo list
    helm search repo ingress
    helm search hub prometheus
  2. 차트 살펴보기 — ★ 무엇을 바꿀 수 있는지 여기서 찾는다

    터미널 창
    helm show values ingress-nginx/ingress-nginx # 설정 가능한 값 전부
    helm show chart ingress-nginx/ingress-nginx
    helm pull ingress-nginx/ingress-nginx --untar # 로컬로 받아서 뜯어보기
  3. 설치

    터미널 창
    helm install my-ingress ingress-nginx/ingress-nginx \
    --namespace ingress-nginx --create-namespace
  4. 확인

    터미널 창
    helm list -A
    helm status my-ingress -n ingress-nginx
    helm get values my-ingress -n ingress-nginx
    helm get manifest my-ingress -n ingress-nginx # 실제로 적용된 YAML

헷갈리기 쉬운 짝 두 개 —

  • helm search repo vs search hub — repo는 내가 helm repo add로 등록한 저장소 안을 찾고, hub는 공개 카탈로그(Artifact Hub) 전체를 찾는다. 시험처럼 네트워크가 제한된 환경에서 실제로 쓰는 것은 repo 쪽이다
  • helm get values vs get manifest — 앞은 내가 준 값, 뒤는 그 값으로 렌더된 최종 YAML이다. “무엇이 실제로 적용됐나”를 볼 때는 get manifest다

특정 이미지가 어느 release에서 왔는지 찾을 때도 이 연결을 거꾸로 쓴다. helm list -A로 release와 네임스페이스를 얻고, 각 helm get manifest RELEASE -n NAMESPACE에서 이미지 문자열을 찾으면 리소스 이름을 release 이름으로 오인하지 않는다.

터미널 창
helm install my-ingress ingress-nginx/ingress-nginx \
--set controller.replicaCount=3 \
--set controller.service.type=NodePort \
--set-string controller.config.use-forwarded-headers="true"

값 한두 개만 바꿀 때. 시험에서 가장 자주 쓰는 형태.

--set-string은 값을 무조건 문자열로 넣는다. true나 1.10 같은 값을 --set으로 주면 YAML이 불리언·숫자로 해석해 버려 차트가 기대한 타입과 어긋나는 일이 있는데, 그때 쓴다.

터미널 창
# 적용 전에 결과 확인 — 시험·실무 모두 유용하다
helm template my-ingress ingress-nginx/ingress-nginx -f my-values.yaml
helm install my-ingress ingress-nginx/ingress-nginx --dry-run --debug

둘의 차이 — helm template은 클러스터에 붙지 않고 로컬에서 렌더만 한다. --dry-run은 릴리스를 실제로 설치하지 않으면서 설치 경로를 그대로 밟아 보는 것이라, 클러스터에 연결해 API 버전 같은 정보를 반영한 결과를 보여준다 (서버 쪽 검증까지 받으려면 --dry-run=server). 값이 제대로 꽂혔는지 눈으로 보는 목적이면 template이 가볍고 빠르다.

--version을 주지 않으면 저장소의 최신 차트를 쓴다. 특정 버전이 조건이면 helm search repo <차트> --versions로 버전을 확인하고 --version으로 고정한다. --namespace도 렌더 결과에 반영되므로 함께 지정하고, 결과를 남길 때는 > 파일로 보낸다.

터미널 창
helm template my-ingress ingress-nginx/ingress-nginx \
--version 4.11.0 --namespace ingress-nginx > ~/ingress-nginx.yaml
차트 값을 바꾸라는 문제를 helm show values부터 upgrade까지 푸는 순서

릴리스가 있어서 가능해지는 것이 이 절이다. kubectl apply로 설치한 것은 “어제 상태로 되돌려라”가 안 된다 — 무엇을 적용했는지 아무도 기억하지 않기 때문이다. Helm은 설치·업그레이드마다 리비전 번호를 붙여 값과 매니페스트를 통째로 보관하므로, 번호 하나만 대면 그 시점으로 되돌아간다.

터미널 창
helm upgrade my-ingress ingress-nginx/ingress-nginx --set controller.replicaCount=5
helm upgrade --install my-ingress ingress-nginx/ingress-nginx \
-f my-values.yaml --atomic --timeout 5m # 실패하면 자동 롤백
helm history my-ingress -n ingress-nginx
# REVISION UPDATED STATUS CHART DESCRIPTION
# 1 2026-08-01 superseded ingress-nginx-4.11.0 Install complete
# 2 2026-08-05 deployed ingress-nginx-4.11.0 Upgrade complete
helm rollback my-ingress 1 -n ingress-nginx --wait --timeout 5m
helm uninstall my-ingress -n ingress-nginx
helm upgrade의 값 처리 옵션 세 가지와 uninstall이 CRD를 남기는 동작

--atomic은 업그레이드가 실패하면 변경을 롤백하고 --wait도 자동으로 켠다. 그래도 릴리스 상태와 Kubernetes 워크로드 상태는 다른 층이다. 완료 뒤 둘 다 확인한다.

터미널 창
helm status my-ingress -n ingress-nginx
helm get values my-ingress -n ingress-nginx --all
helm get manifest my-ingress -n ingress-nginx
kubectl get deploy,pods,svc -n ingress-nginx

helm status가 failed거나 워크로드가 준비되지 않으면 helm history에서 마지막 정상 리비전을 찾고 helm rollback --wait로 되돌린 뒤 같은 검증을 반복한다. helm get manifest는 Helm이 렌더한 최종 YAML이고, kubectl get은 컨트롤러가 실제로 만든 리소스와 현재 상태다.

CRD(CustomResourceDefinition)는 쿠버네티스에 새로운 리소스 종류를 등록하는 오브젝트다 (CRD에서 자세히 본다). cert-manager를 설치하면 Certificate 같은 종류가 생기는데, 그 종류를 정의한 것이 CRD다. CRD를 지우면 그 종류로 만들어 둔 오브젝트가 전부 함께 사라지므로 — 위 예로 치면 발급해 둔 인증서가 다 날아간다 — Helm은 일부러 남긴다. 지우려면 kubectl delete crd <이름>으로 직접 지워야 한다.

“CRD는 이미 설치되어 있으니 빼라”거나 “CRD까지 함께 설치하라”는 조건이 붙을 때가 있다. 차트가 CRD를 싣는 방식이 둘이라서, 넣고 빼는 방법도 둘이다.

CRD가 있는 곳helm installhelm template빼는 방법
차트의 crds/ 디렉터리클러스터에 없으면 설치하고, 있으면 건너뛴다기본 출력에 넣지 않는다. --include-crds를 주면 넣는다--skip-crds
templates/ 안의 일반 템플릿차트 값에 따른다차트 값에 따른다차트가 정한 값을 끈다

crds/ 디렉터리의 CRD는 템플릿 처리를 거치지 않고, Helm이 업그레이드하거나 삭제하지도 않는다 (Helm 공식 문서). 그래서 CRD를 계속 관리하려는 차트는 CRD를 일반 템플릿으로 싣고 값으로 켜고 끈다. 이때 키 이름은 차트마다 다르다.

차트CRD를 켜고 끄는 값기본값
cert-managercrds.enabledfalse
Argo CDcrds.installtrue
External Secrets OperatorinstallCRDstrue

표의 값은 2026-10-03에 각 차트의 values.yaml에서 확인했다. 외울 대상이 아니라, 아래 명령으로 그때그때 찾는다.

터미널 창
helm show values <저장소>/<차트> --version <버전> | grep -n -i crd
helm template <릴리스> <저장소>/<차트> --set <찾은-키>=false | grep -c 'kind: CustomResourceDefinition' # 0이면 빠졌다

값이 없는데도 CRD가 설치되는 차트라면 crds/ 방식이다. 그때는 --skip-crds를 쓴다. 파일로 렌더하는 전체 순서는 실전 과제에서 연습한다.

  • Helm은 차트와 값을 조합해 설치하고, 그 결과를 릴리스로 추적해 업그레이드와 롤백을 수행한다.
  • values를 바꿀 때 최종 manifest와 설치된 워크로드 상태를 구분해서 확인한다.
  • history와 rollback으로 정상 리비전으로 돌아가고 결과를 검증한다.