kubectl apply -f 로 관리하던 YAML 묶음을 차트로 바꾸는 이유는 값을 빼내기 위해서다. 개발·운영에서 다른 것은 이미지 태그, 레플리카 수, 도메인, 스토리지 클래스 정도인데 파일을 통째로 복제해 관리하면 두 벌이 서서히 어긋난다. 차트로 옮기면 템플릿은 하나, 값만 환경별로 갖는다.
차트로 옮긴다고 해서 배포가 더 안전해지지는 않는다. 값이 몇 개 없는 단일 애플리케이션이라면 kustomize 쪽이 더 단순할 수 있다.
helm create myapp
rm myapp/templates/*.yaml myapp/templates/tests/*.yaml
cp deployment.yaml service.yaml ingress.yaml myapp/templates/
helm create 가 만들어 주는 예제 템플릿은 지운다. 남겨 두면 렌더링 결과에 쓰지 않는 리소스가 섞인다. _helpers.tpl 은 이름 규칙 함수가 들어 있으므로 남겨 두면 쓸모가 있다.
옮긴 뒤 환경마다 달라지는 값만 골라 치환한다. 처음부터 전부 변수로 빼면 템플릿이 읽히지 않는다. Deployment → Service → Ingress 순으로 하나씩 하고, 매번 렌더링 결과를 확인한다.
# templates/deployment.yaml
spec:
replicas: {{ .Values.replicaCount }}
template:
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
# values.yaml
replicaCount: 3
image:
repository: registry.example.com/myapp
tag: ""
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
targetPort: 8080
helmify 는 쿠버네티스 매니페스트를 받아 차트 뼈대를 만들어 주는 CLI 도구다. 표준 입력이나 파일을 받아 Chart.yaml · values.yaml · templates/ 를 만든다.
# 단일 파일
helmify -f my-app.yaml mychart
# 디렉터리 안의 여러 파일을 이어 붙여 넘긴다
awk 'FNR==1 && NR!=1 {print "---"}{print}' ./manifests/*.yaml | helmify mychart
초안을 만드는 도구이지 완성품을 내주는 도구가 아니다. 변환 결과에서 다음은 손봐야 한다.
values.yaml 의 구조를 다시 정리한다.values.yaml 에 들어가지 않았는지 반드시 확인한다. 차트를 저장소에 올리기 전에 볼 것.CRD 를 포함한 오퍼레이터 매니페스트는 변환 뒤에도 설치 순서 문제가 남는다. CRD 는 crds/ 디렉터리에 따로 두어야 템플릿보다 먼저 설치된다.
배포하기 전에 렌더링 결과를 본다. helm template 은 클러스터에 붙지 않고 로컬에서 렌더링만 하고, --dry-run 은 API 서버에 보내 검증까지 받는다.
# 로컬 렌더링. 클러스터 없이도 된다
helm template myapp ./myapp -f values-prod.yaml
# API 서버 검증까지 포함. 실제로 설치하지는 않는다
helm install myapp ./myapp -f values-prod.yaml --dry-run --debug
# 이미 설치된 릴리스를 올릴 때 무엇이 바뀌는지
helm upgrade myapp ./myapp -f values-prod.yaml --dry-run --debug
--dry-run 은 클러스터에 접속할 수 있어야 하고, 그 네임스페이스에 대한 권한이 필요하다. 접속이 안 되는 자리에서 문법만 보려면 helm template 과 helm lint 를 쓴다.
helm lint ./myapp -f values-prod.yaml
렌더링 결과를 파일로 떨궈 매니페스트 검증 도구에 넘기면 스키마 오류까지 잡을 수 있다.