LabHub

Helm 차트 제작과 배포 · 템플릿과 values · 실습

템플릿 함수로 values 를 안전하게 꽂기

LabHub 에서 이어서 보기

목표

템플릿 함수로 values 를 안전하게 매니페스트에 꽂고, 값이 없을 때·필수일 때·블록일 때 각각 어떤 도구를 써야 하는지 손으로 익힙니다.

왜 중요한가

Helm 템플릿은 YAML 편집기가 아니라 문자열 생성기입니다. 최종 결과가 문자열로 완성된 뒤에야 YAML 파서가 그것을 읽습니다. 그래서 들여쓰기가 두 칸 어긋나면 오류가 나는 대신 블록이 통째로 사라지거나 엉뚱한 부모 밑으로 들어갑니다. toYaml 로 편 블록에 nindent 를 반드시 붙이는 이유가 여기 있습니다 — indent 는 앞의 줄바꿈을 만들어 주지 않아 첫 줄이 앞 키에 그대로 붙습니다. 값 설계도 마찬가지입니다. default 는 "없어도 되는 값"에, required 는 "없으면 배포하면 안 되는 값"에 씁니다. 이 둘을 뒤집으면 잘못된 기본값으로 조용히 배포되거나, 반대로 아무나 못 쓰는 차트가 됩니다. 마지막으로 값의 우선순위는 낮은 것부터 차트의 values.yaml, -f 로 준 파일들(왼쪽에서 오른쪽), --set 순서이며, 맵은 깊게 병합되지만 리스트는 통째로 교체된다는 점을 꼭 기억하세요.

단계

1. /root/helm/tpl/labhub-api 에 차트를 만드세요(helm create labhub-api 로 시작해도 좋습니다). values.yamlimage.repositorynginx, image.tag"1.27" 로 두고 Chart.yamlappVersion"1.26" 으로 둡니다. 그다음 helm template labhub-api /root/helm/tpl/labhub-api > /root/helm/tpl/out/base.yaml 로 렌더링을 저장하세요. 결과에 Deployment 가 있고 컨테이너 이미지가 저장소:태그 형태여야 하며, 중괄호나 <no value> 가 남아 있으면 안 됩니다.
2. 컨테이너 이미지 태그를 {{ .Values.image.tag | default .Chart.AppVersion }} 처럼 쓰고, helm template labhub-api /root/helm/tpl/labhub-api --set image.tag="" > /root/helm/tpl/out/default.yaml 을 저장하세요. 태그를 비웠는데도 이미지에는 nginx:1.26 처럼 태그가 붙어 있어야 하며, 기본값으로 latest 를 쓰면 안 됩니다.
3. values.yamlingress.enabled: trueingress.host: api.labhub.local 을 두고, /root/helm/tpl/labhub-api/templates/ingress.yaml 에서 호스트를 required 로 감싸세요(예: {{ required "ingress.host 를 반드시 지정하세요" .Values.ingress.host }}). 그다음 helm template labhub-api /root/helm/tpl/labhub-api --set ingress.host="" > /root/helm/tpl/out/required-error.txt 2>&1 로 일부러 실패시키고 그 출력을 저장하세요. 파일에는 렌더링 실패 메시지와 함께 어떤 키가 빠졌는지가 보여야 합니다.
4. values.yamlresourceslimits.cpu: 500m, limits.memory: 512Mi, requests.cpu: 100m, requests.memory: 128Mi 로 채우고, Deployment 컨테이너에서 {{- toYaml .Values.resources | nindent 12 }} 형태로 통째로 넘기세요. /root/helm/tpl/out/base.yaml 을 다시 렌더링하면 컨테이너의 resources.limits.cpuresources.requests.memory 가 보여야 합니다.
5. values.yamlenv으로 두고 APP_MODE: server, LOG_LEVEL: info, TZ: Asia/Seoul 세 개를 정의하세요. Deployment 에서 range $k, $v := .Values.env 로 컨테이너 env 목록을 만듭니다. /root/helm/tpl/out/base.yaml 의 컨테이너 env 는 정확히 3개여야 하고 그중 하나의 이름이 LOG_LEVEL 이어야 합니다.
6. /root/helm/tpl/labhub-api/templates/_helpers.tpldefine 으로 차트 식별 문자열(이름-버전)을 만들고, Deployment 의 metadata.annotationslabhub.io/chart: {{ include "labhub-api.chart" . }} 를 붙이세요. 그리고 /root/helm/tpl/out/include-note.txttemplateinclude 의 차이를 한 줄로 적으세요 — include 는 결과를 문자열로 반환하므로 파이프로 이어 후처리(들여쓰기)를 할 수 있다는 내용이 들어가야 합니다.
7. /root/helm/tpl/values-base.yamlreplicaCount: 2, env.LOG_LEVEL: info, image.tag: base 를, /root/helm/tpl/values-stage.yamlreplicaCount: 4, env.LOG_LEVEL: debug, image.tag: stage 를 두세요. 그다음 helm template labhub-api /root/helm/tpl/labhub-api -f /root/helm/tpl/values-base.yaml -f /root/helm/tpl/values-stage.yaml --set image.tag=cli > /root/helm/tpl/out/merged.yaml 을 실행하세요. 결과의 replicas 는 4, LOG_LEVELdebug, 이미지 태그는 cli 여야 합니다. 마지막으로 /root/helm/tpl/out/precedence.txt 에 우선순위를 낮은 것부터 한 줄씩 적으세요: 차트의 values.yaml, -f values-base.yaml, -f values-stage.yaml, --set.
8. ConfigMap 템플릿을 추가해 values.yamlconfig 맵을 data 로 내보내고, 파드 템플릿의 metadata.annotationschecksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} 를 붙이세요. 파드 수준 spec.template.spec.securityContext.runAsNonRoottrue 가 되어야 합니다. 완성된 렌더링을 /root/helm/tpl/out/final.yaml 로 저장하세요(오브젝트 3개 이상, 컨테이너 env 3개 이상, <no value> 없음). 그리고 helm lint /root/helm/tpl/labhub-api > /root/helm/tpl/out/lint.txt 도 저장하며 [ERROR] 가 없어야 합니다.

참고

단계 8개

  1. values 를 참조해 렌더링하기
  2. default 로 빈 값 메우기
  3. required 로 필수 값 강제하기
  4. toYaml 과 nindent 로 블록 넘기기
  5. range 로 환경변수 펼치기
  6. 네임드 템플릿 정의하고 include 하기
  7. 값 우선순위 확인하기
  8. 설정 해시와 보안 컨텍스트까지 붙이기