LabHub
배우기 러닝패스 코스

Helm 차트 제작과 배포 · 범위와 공백 · 실습

렌더 결과가 YAML 이 아니었다 — 범위와 공백

LabHub 에서 이어서 보기

목표

with·range 가 점을 바꾸는 것, 공백 다듬기가 줄을 붙여 버리는 것, 따옴표를 뺀 값이 숫자와 불리언이 되는 것을 각각 일부러 일으켜 보고, --debug·required·fail·helm lint --strict 로 막는 법까지 간다.

왜 중요한가

템플릿에서 나는 사고의 대부분은 함수를 몰라서가 아니라 결과가 YAML 이 아니게 되어서 난다. 그래서 오류 메시지가 원인을 가리키지 않는다. mapping values are not allowed in this context 는 YAML 파서의 말이지 템플릿의 말이 아니라서, 그 줄을 아무리 들여다봐도 -}} 하나가 범인이라는 것은 보이지 않는다. 같은 이유로 with 안에서 .Release 가 nil 이라는 메시지도 '점이 바뀌었다' 는 사실을 알기 전에는 읽히지 않는다. 여기에 따옴표 문제가 겹치면 렌더까지는 멀쩡히 되고 클러스터가 거절한다 — 배포 파이프라인의 가장 늦은 지점에서 터지는 종류다. 이 넷을 한 번씩 직접 만들어 보면 다음부터는 메시지 두 줄만 보고 어디를 볼지 정할 수 있다.

단계

1. /root/hc-scope/frontier 차트(이름 frontier, 버전 0.1.0)를 만들고 values.yamlapp(name portal, team core, port 8080), notes(owner sre, runbook wiki/portal), envs(STAGE, PROD), release(tag "1.10", enabled "no") 를 두세요. templates/base.yaml 은 이름이 .Values.app.name, data.port 가 따옴표로 감싼 포트인 ConfigMap 입니다. helm template web /root/hc-scope/frontier 결과를 /root/hc-scope/out/base.yaml 에 저장하세요.
2. /root/hc-scope/frontier/templates/scoped.yaml 을 만드세요. 이름은 <app.name>-scoped, 그 아래를 {{- with .Values.app }} 블록으로 감싸고 그 안에서 data.release{{ .Release.Name }}, data.team{{ .team }} 로 씁니다. 렌더하면 실패합니다 — 그 출력을 /root/hc-scope/out/with-error.txt 에 저장하세요.
3. /root/hc-scope/frontier/templates/scoped.yaml 에서 with 블록은 그대로 두고 data.release 만 고쳐 릴리스 이름이 렌더되게 하세요. 렌더 결과를 /root/hc-scope/out/scoped.yaml 에 저장합니다 (릴리스 이름 web). data 에는 release: webteam: core 두 줄이 나와야 합니다.
4. /root/hc-scope/frontier/templates/envs.yaml 을 만드세요. 이름은 <app.name>-envs 이고, .Values.envs 를 인덱스와 값 두 변수로 받아 돌면서 data<소문자 환경이름>: "<인덱스>-<app.port>" 한 줄씩 냅니다. 렌더 결과에 stage: "0-8080"prod: "1-8080" 이 나와야 합니다. 결과를 /root/hc-scope/out/envs.yaml 에 저장하세요.
5. /root/hc-scope/broken 차트(이름 broken)를 따로 만들고 values.yamlapp(name portal, team core)과 notes(owner sre, runbook wiki/portal)를 두세요. templates/portal.yamlannotations: 아래 줄에서 {{- toYaml .Values.notes | indent 4 -}} 로 주석을 꽂고 그 뒤에 labels: 가 오는 모양입니다. 렌더하면 실패합니다 — 보통 출력은 /root/hc-scope/out/ws-error.txt 에, --debug 를 붙인 출력은 /root/hc-scope/out/ws-debug.txt 에 저장하세요. 이 차트는 고치지 말고 그대로 둡니다.
6. /root/hc-scope/broken/root/hc-scope/fixed 로 복사하고(차트 이름은 fixed 로 바꿉니다) templates/portal.yaml 만 고쳐 렌더가 성공하게 만드세요. 주석 블록은 annotations: 아래에 네 칸 들여써서 두 줄로, labels.teamcore 로 나와야 합니다. 결과를 /root/hc-scope/out/fixed.yaml 에 저장하세요.
7. /root/hc-scope/frontier/templates/release.yaml 을 만드세요. 이름은 <릴리스이름>-release, data.tag.Values.release.tag, data.enabled.Values.release.enabled따옴표 없이 꽂습니다. 이 템플릿만 렌더해 yq -o=json 을 거친 결과를 /root/hc-scope/out/quote-yaml12.json 에, 그 렌더를 kubectl apply --dry-run=server 에 넣은 출력을 /root/hc-scope/out/quote-error.txt 에 저장하세요. 그다음 두 값에 quote 를 걸어 고치고, 다시 서버 검증을 통과한 출력을 /root/hc-scope/out/quote-ok.txt 에 저장하세요.
8. /root/hc-scope/frontier/templates/guard.yaml 을 만드세요. 포트가 1024 미만이면 fail 로 멈추고, data.teamrequired 로 값이 없을 때 멈춥니다. 정상 값으로는 이름이 <app.name>-guard 인 ConfigMap 이 나와야 합니다. --set app.port=80 으로 렌더한 출력을 /root/hc-scope/out/guard-fail.txt 에, --set app.team=null 로 렌더한 출력을 /root/hc-scope/out/guard-required.txt 에 저장하고, 옵션 없이 렌더한 전체 결과를 /root/hc-scope/out/guard-ok.yaml 에 저장하세요.
9. /root/hc-scope/lintbad 차트(이름 lintbad)를 만들고 templates/cm.yaml 의 ConfigMap 이름을 Bad_Name 으로 두세요. helm lint 의 출력과 종료 코드를 /root/hc-scope/out/lint-plain.txt 에, helm lint --strict 의 출력과 종료 코드를 /root/hc-scope/out/lint-strict.txt 에 저장하세요. 두 파일의 마지막 줄에 exit=<종료 코드> 를 덧붙입니다. 같은 차트인데 통과 여부가 갈리는 것이 이 단계의 답입니다.

참고

단계 9개

  1. 값 구조를 먼저 깔고 한 번 렌더한다
  2. with 안에서 .Release 를 찾지 못한다
  3. 달러 기호로 뿌리를 다시 잡는다
  4. range 안에서도 뿌리 값을 함께 쓴다
  5. 공백 다듬기 하나가 YAML 을 무너뜨린다
  6. nindent 로 줄바꿈까지 넘겨 준다
  7. 따옴표를 빼먹자 클러스터가 거절했다
  8. 잘못된 값이면 렌더 단계에서 멈춘다
  9. 경고를 오류로 다루게 만든다