値がマージされる順序をレンダーで確認する
한국어 원문으로 표시합니다.
목표
값이 합쳐지는 순서를 외우는 대신 렌더해서 확인하는 습관을 만듭니다. 로컬
서브차트를 의존성으로 걸고, 값 파일 두 장과 --set 을 겹쳐 누가 이기는지 보고,
스키마로 잘못된 값을 배포 전에 막는 데까지 갑니다.
왜 중요한가
운영 배포는 값 파일이 보통 두세 겹입니다. 차트 기본값, 환경별 값, 그리고 CI 가 주입하는 이미지 태그입니다. 어느 것이 이기는지 헷갈리면 스테이징 값이 프로덕션에 새어 들어갑니다. 여기에 함정이 둘 더 있습니다. 맵은 병합되지만 리스트는 통째로 교체된다는 것, 그리고 서브차트에 주는 값은 서브차트 이름을 키로 감싸야 전달된다는 것입니다.
의존성도 같은 종류의 문제를 냅니다. Chart.yaml 에 적는 버전은 범위이고, 실제로
무엇이 잡혔는지는 Chart.lock 에 적힙니다. 이 파일을 커밋하지 않으면 사람마다
다른 의존성을 받고, 그때부터 "내 컴퓨터에서는 되는데" 가 시작됩니다.
환경
인터넷이 없으므로 차트 저장소를 받아올 수 없습니다. 대신 서브차트를 옆
디렉터리에 만들고 file:// 로 가리킵니다. helm dependency update 는 이 방식으로
정상 동작합니다. 작업 디렉터리는 /root/hs-val 이고 산출물은 /root/hs-val/out
아래에 둡니다. 채점은 파일을 글자로 보지 않고 helm template 을 직접 돌려
결과를 읽습니다.
단계
- 서브차트
cache와 부모platform을 만들고file://의존성을 걸어 잠급니다. platform/values.yaml에서cache키로 서브차트에 값을 내려보냅니다.global.env를 두고 양쪽 차트가 함께 읽는 것을 확인합니다.values/base.yaml과values/prod.yaml을 겹쳐 렌더해/root/hs-val/out/render.yaml에 저장합니다.- 리스트가 교체된다는 것을 확인하고
/root/hs-val/out/list-note.txt에 적습니다. cache.enabled: false로 서브차트를 통째로 끕니다.values.schema.json으로 범위를 넘는 값을 막고 거절 출력을 저장합니다.val-lab에 설치하고helm get values결과를 저장합니다.
참고
- 서브차트 템플릿을 고쳤으면
helm dependency update를 다시 돌리세요.charts/안의 꾸러미는 자동으로 갱신되지 않습니다. --set의 쉼표는 키 구분자입니다. 값 안에 쉼표가 필요하면 백슬래시로 이스케이프하거나 임시 값 파일에 담으세요.- 흔한 실수는 서브차트 값을 최상위에 적는 것입니다. 그러면 부모 차트의 값이 될 뿐이고 helm 은 아무 경고도 하지 않습니다.
- 스키마에
required를 넣을 때는 값 파일 없이 렌더하는 경우까지 생각하세요.
로컬 서브차트를 의존성으로 걸고 잠근다
/root/hs-val 에 차트 두 개를 만드세요. 서브차트는 cache, 부모는 platform 입니다. platform/Chart.yaml 에 cache 의존성을 file://../cache 저장소로 적고 condition: cache.enabled 를 붙인 뒤 helm dependency update 를 돌리세요.
인터넷이 없으므로 저장소 주소로 file:// 을 씁니다. helm dependency update <부모차트> 를 돌리면 서브차트가 꾸러미로 묶여 platform/charts/cache-0.1.0.tgz 로 들어오고, 잡힌 버전이 platform/Chart.lock 에 적힙니다. 이 잠금 파일을 저장소에 커밋해야 다른 사람과 CI 가 같은 것을 받습니다. CI 에서는 helm dependency build 를 쓰고, 범위를 다시 푸는 update 는 의도할 때만 씁니다.
서브차트에 값을 내려보낸다
platform/values.yaml 끝에 cache 키를 만들고 그 아래 enabled: true 와 replicaCount: 3 을 두세요. 부모 자신의 replicaCount 는 기본값 1 그대로 둡니다.
서브차트에 값을 주려면 부모 values 에서 서브차트 이름을 키로 감싸야 합니다. 최상위에 그냥 적으면 부모 차트의 값이 될 뿐입니다. 고친 뒤 helm template plat ./platform 을 돌려 Deployment 두 개의 replicas 가 각각 3과 1로 갈리는지 확인하세요.
global 아래 값만 모든 차트가 함께 본다
platform/values.yaml 에 global.env 를 두고, 부모와 서브차트 양쪽에 그 값을 담는 ConfigMap 템플릿을 만드세요. 이름은 각각 {{ .Release.Name }}-platform-env 와 {{ .Release.Name }}-cache-env 이고, data.env 에 .Values.global.env 를 넣습니다.
서브차트는 부모의 최상위 값을 볼 수 없지만 global 아래 값은 함께 봅니다. 함정이 하나 있습니다. 서브차트 템플릿을 고쳐도 platform/charts/ 안의 꾸러미는 옛것이라, helm dependency update 를 다시 돌려야 렌더에 반영됩니다. 렌더 결과에서 두 ConfigMap 의 data.env 가 같은 값이면 성공입니다.
두 값 파일과 --set 을 겹쳐 누가 이기는지 본다
/root/hs-val/values/base.yaml 과 prod.yaml 을 만들고, tier 와 image.tag 를 서로 다르게 적으세요. 부모 차트에 {{ .Release.Name }}-settings ConfigMap 템플릿을 만들어 tier·tag·envNames 를 담고, -f base.yaml -f prod.yaml --set image.tag=ci-42 로 렌더한 결과를 /root/hs-val/out/render.yaml 에 저장하세요.
우선순위는 낮은 것부터 차트의 values.yaml, -f 로 준 파일(먼저 온 것 → 나중 것), 그리고 --set 입니다. base.yaml 에는 tier·replicaCount·image.tag·extraEnv 를 두고, prod.yaml 에는 tier·image.tag·extraEnv 를 둡니다. replicaCount 는 prod 에 적지 마세요. 나중 파일에 없는 키가 어떻게 되는지 8단계에서 다시 씁니다. 채점기는 같은 명령을 다시 돌려 여러분의 파일과 대조합니다.
리스트는 병합되지 않고 통째로 바뀐다
4단계에서 만든 두 값 파일의 extraEnv 를 그대로 두고, 렌더 결과의 envNames 가 어느 쪽 목록인지 확인하세요. 확인한 규칙을 /root/hs-val/out/list-note.txt 첫 줄에 LIST_MERGE=replace 로 적고, 그 아래에 왜 그런지 한두 문장을 덧붙이세요.
맵은 키 단위로 병합되지만 리스트는 뒤엣것이 앞엣것을 통째로 덮습니다. -f base.yaml -f prod.yaml 로 렌더하면 base 의 항목이 하나도 남지 않습니다. 환경별로 나눠 둔 extraEnv 가 하나만 남는 사고가 여기서 나옵니다. 합치고 싶다면 리스트가 아니라 맵으로 설계해야 합니다.
조건이 거짓이면 서브차트는 렌더되지 않는다
prod.yaml 에 cache.enabled: false 를 두고, 그 값을 준 렌더와 주지 않은 렌더를 비교하세요. 끈 쪽에는 서브차트 리소스가 하나도 없어야 합니다.
Chart.yaml 의 condition 이 가리키는 값이 거짓이면 그 서브차트는 아예 렌더되지 않습니다. 그래서 그 서브차트의 값이 잘못돼 있어도 배포는 통과하고, 켜는 순간 처음 드러납니다. 서브차트가 낸 리소스인지는 렌더 결과의 # Source: platform/charts/cache/ 주석으로 구분할 수 있습니다.
스키마로 잘못된 값을 배포 전에 막는다
/root/hs-val/platform/values.schema.json 을 만들어 replicaCount 를 1 이상 5 이하의 정수로 제한하세요. 그리고 상한을 넘는 값으로 렌더를 시도해 거절당한 출력을 /root/hs-val/out/schema-reject.txt 에 저장하세요.
Helm 은 차트 루트의 values.schema.json 으로 합쳐진 값을 검사합니다. 오타 난 키를 배포 전에 잡는 것이 목적입니다. 주의할 것이 하나 있습니다. 환경 파일에만 있는 키를 required 에 넣으면 값 파일 없이 렌더하는 경우까지 막혀 앞 단계들이 깨집니다. 거절 출력은 표준 오류로 나가므로 2>&1 로 받아야 파일에 남습니다.
배포된 릴리스에 실제로 들어간 값을 확인한다
platform 을 val-lab 네임스페이스에 plat 이라는 이름으로, -f base.yaml -f prod.yaml --set image.tag=ci-42 를 그대로 주어 설치하세요. 그다음 helm get values 를 JSON 으로 받아 /root/hs-val/out/user-values.json 에 저장하세요.
helm get values 는 사용자가 준 값만, --all 은 차트 기본값까지 합친 전체를 보여 줍니다. 사고 조사에서 먼저 보는 것은 앞쪽입니다. 저장한 뒤 세 가지를 확인하세요. image.tag 가 --set 값인지, tier 가 뒤에 준 파일 값인지, 그리고 prod 에 없는 replicaCount 가 base 값 그대로 남았는지입니다. 마지막 것이 맵 병합의 증거입니다.