본문으로 건너뛰기
Kubernetes 로고

생성 수정

Kubernetes · 9장

헬름 차트

매니페스트를 복사해 붙이는 단계에서 벗어난다. 차트로 패키징하고 값으로 환경을 가르고, 릴리스 단위로 올리고 되돌리는 방법을 익힌다.

9장 · 총 7개 절 · 전체 9개 장 중 9번째

헬름이 푸는 문제 — 매니페스트의 중복

9장 · 01

앱 하나를 배포하는 데 디플로이먼트·서비스·인그레스·컨피그맵 네 파일이 필요합니다. 환경이 셋(dev·staging·prod)이면 열두 파일이 되고, 그 대부분은 몇 글자만 다른 복사본입니다. 헬름은 이 중복을 템플릿과 값으로 갈라놓습니다.

  • 차트(Chart) — 한 앱을 배포하는 데 필요한 매니페스트 묶음(패키지)
  • 값(Values) — 환경마다 달라지는 부분. 같은 차트에 다른 values 를 주면 다른 환경이 된다
  • 릴리스(Release) — 차트를 클러스터에 설치한 한 벌. 이름이 붙고 버전이 매겨진다
  • 쿠버네티스의 apt·npm에 해당한다 — 남이 만든 차트를 가져와 설치할 수도 있다
  • 헬름 3부터는 서버 측 구성 요소(Tiller)가 없다 — kubeconfig만 있으면 동작한다
  • "환경별로 복사한 YAML"을 없애는 것이 헬름을 쓰는 첫 번째 이유다

설치와 저장소, 첫 릴리스

9장 · 02

헬름은 클라이언트 바이너리 하나입니다. 설치한 뒤 차트 저장소를 등록하면, 남이 만들어둔 차트를 명령 한 줄로 클러스터에 올릴 수 있습니다.

  • 설치 스크립트 또는 패키지 매니저(apt·brew)로 바이너리 하나를 받는다
  • 저장소(repo)를 등록하고 update 로 색인을 받아온다 — Bitnami가 가장 널리 쓰인다
  • helm search repo 로 차트를 찾고, helm show values 로 어떤 값을 바꿀 수 있는지 먼저 확인한다
  • helm install <릴리스명> <차트> 가 설치, helm list 가 설치된 릴리스 목록이다
  • 네임스페이스를 -n 으로 지정하고 --create-namespace 를 붙이면 없는 네임스페이스도 만들어준다

1. 헬름 설치

2. 저장소 등록과 검색

3. 첫 릴리스

차트 구조 — Chart.yaml · values.yaml · templates

9장 · 03

차트는 정해진 디렉터리 구조를 가진 폴더입니다. helm create 로 뼈대를 만들면 그 구조가 그대로 생기고, 각 파일의 역할이 분명하게 나뉩니다.

  • Chart.yaml — 차트의 이름·버전·앱 버전 등 메타데이터
  • values.yaml — 기본값. 사용자가 덮어쓰지 않으면 이 값이 쓰인다
  • templates/ — 실제 매니페스트 템플릿. 여기 파일들이 렌더링돼 클러스터로 간다
  • templates/_helpers.tpl — 이름 생성 규칙 같은 공통 조각을 정의해 재사용한다
  • charts/ — 의존하는 하위 차트(subchart)를 두는 자리
  • NOTES.txt — 설치 후 터미널에 출력되는 안내문. 접속 방법을 적어두는 게 관례다
  • .helmignore — 패키징에서 제외할 파일 목록

뼈대 만들기

생성되는 구조

my-app/
my-app/
├── Chart.yaml          # 차트 메타데이터
├── values.yaml         # 기본값
├── charts/             # 의존 차트
├── templates/
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── _helpers.tpl    # 공통 템플릿 조각
│   └── NOTES.txt       # 설치 후 안내문
└── .helmignore

템플릿 문법과 값 오버라이드

9장 · 04

템플릿은 Go 템플릿 문법으로 쓰이고, 값은 .Values 로 참조합니다. 렌더링 결과를 미리 확인하는 습관(template·--dry-run)이 실수를 크게 줄여줍니다.

  • {{ .Values.<키> }} — values.yaml 의 값을 꽂는다
  • {{ .Release.Name }} · {{ .Chart.Name }} — 릴리스·차트 정보를 참조하는 내장 객체
  • {{- if }} · {{- range }} — 조건과 반복. 앞의 하이픈은 공백 제어다(YAML은 들여쓰기가 문법이라 중요하다)
  • {{ include "차트.fullname" . }} — _helpers.tpl 의 조각을 불러온다
  • 값 우선순위 — 기본 values.yaml < -f 로 준 파일 < --set 으로 준 인자
  • helm template 은 클러스터 없이 렌더링만, --dry-run 은 서버 검증까지 한다
  • helm lint 로 문법과 관례 위반을 미리 잡는다

1. 템플릿과 값

templates/deployment.yaml (일부)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "my-app.fullname" . }}
spec:
  replicas: {{ .Values.replicaCount }}
  template:
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          {{- if .Values.env }}
          env:
            {{- range $k, $v := .Values.env }}
            - name: {{ $k }}
              value: {{ $v | quote }}
            {{- end }}
          {{- end }}
values-prod.yaml
replicaCount: 3
image:
  repository: nginx
  tag: "1.27"
env:
  LOG_LEVEL: info
  APP_ENV: production

2. 렌더링 결과 먼저 확인

릴리스 관리 — upgrade · rollback · history

9장 · 05

설치한 뒤부터가 헬름의 진짜 값어치입니다. 같은 릴리스에 새 값을 적용하면 리비전이 하나 올라가고, 문제가 생기면 이전 리비전으로 한 줄에 되돌릴 수 있습니다.

  • helm upgrade — 값이나 차트 버전을 바꿔 적용한다. 리비전 번호가 1씩 올라간다
  • --install 을 함께 주면 없을 때 설치, 있을 때 업그레이드가 된다(CI에서 쓰기 좋다)
  • helm history — 리비전 이력과 각 리비전의 상태를 본다
  • helm rollback <릴리스> <리비전> — 지정한 리비전으로 되돌린다
  • helm get values — 그 릴리스에 실제로 적용된 값을 확인한다(무엇이 배포됐는지 다투지 않게)
  • helm uninstall — 릴리스를 제거한다. --keep-history 를 주면 이력은 남는다
  • 리비전 기록은 클러스터의 시크릿에 저장된다 — 별도 서버가 필요 없는 이유다

릴리스 다루기

나만의 차트 만들고 배포하기

9장 · 06

마지막 실습은 앞 장에서 손으로 만들던 매니페스트를 차트로 옮기는 것입니다. 다 만든 차트는 압축해 저장소에 올리면 다른 사람이 그대로 설치할 수 있습니다.

  • 7장에서 만든 디플로이먼트·서비스·인그레스를 templates/ 로 옮기고, 환경마다 다른 값만 values 로 뽑아낸다
  • 이름은 직접 짓지 말고 _helpers.tpl 의 fullname 헬퍼를 쓴다 — 릴리스 이름과 충돌하지 않는다
  • helm package 로 .tgz 를 만들고, helm repo index 로 색인을 만들면 그 폴더가 곧 저장소가 된다
  • 정적 호스팅(GitHub Pages·S3·R2)에 올려두면 helm repo add 로 누구나 쓸 수 있다
  • OCI 레지스트리(Harbor·ECR·GHCR)에 차트를 push 하는 방식이 최근의 표준에 가깝다
  • 차트 버전(version)과 앱 버전(appVersion)은 다르다 — 앱을 안 바꾸고 템플릿만 고쳐도 차트 버전은 올린다

패키징과 배포

Chart.yaml 두 버전의 차이

Chart.yaml
apiVersion: v2
name: my-app
description: 사내 웹 서비스 배포 차트
type: application
version: 0.1.0        # 차트 자체의 버전 — 템플릿이 바뀌면 올린다
appVersion: "1.27"    # 담고 있는 애플리케이션의 버전

다음 단계 — GitOps와 패키지 운영

9장 · 07

차트까지 오면 "배포"가 파일이 아니라 버전이 붙은 아티팩트가 됩니다. 여기서부터는 사람이 명령을 치는 대신 저장소가 클러스터를 따라오게 만드는 단계로 넘어갑니다.

  • GitOps — 저장소의 선언을 단일 진실 공급원으로 삼고 Argo CD·Flux가 클러스터를 그에 맞춘다
  • Kustomize — 템플릿 대신 패치로 환경 차이를 표현한다. 헬름과 함께 쓰기도 한다
  • 시크릿 관리 — External Secrets·Sealed Secrets로 비밀값을 저장소 밖에 둔다
  • 차트 테스트 — helm test 훅과 CI에서의 lint·template 검증을 파이프라인에 넣는다
  • 관측 스택(Prometheus·Grafana·Loki)도 대부분 차트로 설치한다 — 여기까지 오면 도구가 손에 익는다
  • 이 시리즈의 끝 — 1장의 이론이 9장의 패키징까지 한 줄로 이어졌는지 되짚어본다

다음 시리즈로 다룰 후보는 GitOps(Argo CD)와 관측 스택이다. 순서와 범위는 수업 진행에 맞춰 정한다.

8장 K8s