同一个值怎么写决定了它的类型
한국어 원문으로 표시합니다.
목표
--set 계열 옵션의 문법을 값 덤프로 하나씩 확인하고, 같은 값을 values 파일로 줄 때와 --set 으로 줄 때 결과가 어떻게 달라지는지 JSON 타입까지 비교한다.
왜 중요한가
--set 은 급할 때 쓰는 편의 옵션처럼 보이지만 실제로는 작은 언어다. 점은 깊이를 파고, 쉼표는 값을 나누고, 중괄호는 리스트를 만들고, 대괄호는 원소를 집고, 역슬래시는 그 규칙을 잠시 끈다. 문법을 몰라서 생기는 사고보다 타입을 몰라서 생기는 사고가 더 잦다. --set image.tag=8 은 숫자 8 을 넣고, values 파일의 tag: "8" 은 문자열을 넣는다. 차트가 | quote 를 걸어 두었다면 둘 다 같아 보이지만, 걸지 않은 차트에서는 매니페스트가 조용히 달라진다. 값을 null 로 지우는 것과 빈 문자열로 두는 것도 다르고, 파일 본문을 값으로 넣는 일에는 전용 옵션이 필요하다. 이 실습은 그 차이를 전부 눈에 보이게 만들어 두고 하나씩 확인한다.
단계
/root/hc-set/dumper차트(이름dumper, 버전0.1.0)를 만드세요.values.yaml은image(repositoryregistry.local/api, tag"1.10"),replicas: 2,nodeSelector: {},args: [],config: {}를 담습니다.templates/dump.yaml은<릴리스이름>-dumpConfigMap 이고data에dump.json키 하나만 두는데, 그 값은.Values전체를 JSON 으로 바꿔 따옴표로 감싼 것입니다. 렌더한 뒤 그 JSON 만 뽑아/root/hc-set/out/base.json에 저장하세요.- 기본값을 고치지 말고
--set만으로image.repository를registry.local/web로,replicas를5로,args를alpha·beta·gamma세 원소의 리스트로 바꿔 렌더하고 그 JSON 을/root/hc-set/out/basics.json에 저장하세요. --set으로nodeSelector에kubernetes.io/os: linux를,config에feature.flag: beta를 넣어 렌더하고 JSON 을/root/hc-set/out/escape.json에 저장하세요. 두 키 모두 이름 안에 점이 들어 있습니다.- 같은 태그를 세 가지로 넣어 렌더하고 각각 저장하세요 —
--set image.tag=8은/root/hc-set/out/num-set.json,--set-string image.tag=8은/root/hc-set/out/num-setstring.json,--set image.tag=1.10은/root/hc-set/out/num-float.json입니다. 세 파일에서image.tag의 JSON 타입이 어떻게 갈리는지 확인하세요. --set-json으로config를{"retries": 3, "mode": "strict"}로,args를["--a", "--b"]로 넣어 렌더하고 JSON 을/root/hc-set/out/setjson.json에 저장하세요.retries는 숫자여야 합니다./root/hc-set/ca.pem에 인증서 모양의 세 줄짜리 파일을 만드세요(-----BEGIN CERTIFICATE-----,MIIBkTCB+wIJAKt,-----END CERTIFICATE-----). 이 파일의 내용을config.ca값으로 넣어 렌더하고 JSON 을/root/hc-set/out/setfile.json에 저장하세요. 경로가 아니라 내용이 들어가야 합니다.--set으로image.tag를 지워서(키 자체가 없어져야 합니다) 렌더한 JSON 을/root/hc-set/out/null.json에,args의 0번 원소에name: first와value: 1을 넣어 렌더한 JSON 을/root/hc-set/out/index.json에 저장하세요.value는 숫자여야 합니다./root/hc-set/override.yaml에image.tag: "8"과replicas: 5를 적고 그 파일로 렌더한 JSON 을/root/hc-set/out/via-file.json에 저장하세요. 같은 두 값을--set image.tag=8 --set replicas=5로 준 결과를/root/hc-set/out/via-set.json에,--set-string image.tag=8 --set replicas=5로 준 결과를/root/hc-set/out/via-setstring.json에 저장합니다. 파일 판과 set 판의 차이를diff로 떠서/root/hc-set/out/compare.txt에 남기세요(차이가 있으므로 diff 는 0 이 아닌 코드로 끝납니다).
참고
- 차트가
.Values를 JSON 으로 덤프하므로 값의 타입까지 눈에 보인다 jq -r '.image.tag | type'으로 숫자인지 문자열인지 확인한다--set옵션은 셸이 먼저 건드리지 않도록 작은따옴표로 감싼다- 흔한 실수: 키 안의 점을 탈출하지 않아 중첩 맵이 만들어진다
- 흔한 실수: 이미지 태그를
--set으로 주어 숫자가 된다 —--set-string을 쓴다 - 공식 문서: https://helm.sh/docs/chart_best_practices/values/ · https://helm.sh/docs/helm/helm_template/
넘어온 값을 있는 그대로 내보내는 차트
/root/hc-set/dumper 차트(이름 dumper, 버전 0.1.0)를 만드세요. values.yaml 은 image(repository registry.local/api, tag "1.10"), replicas: 2, nodeSelector: {}, args: [], config: {} 를 담습니다. templates/dump.yaml 은 <릴리스이름>-dump ConfigMap 이고 data 에 dump.json 키 하나만 두는데, 그 값은 .Values 전체를 JSON 으로 바꿔 따옴표로 감싼 것입니다. 렌더한 뒤 그 JSON 만 뽑아 /root/hc-set/out/base.json 에 저장하세요.
{{ .Values | toJson | quote }} 한 줄이면 됩니다. 렌더 결과에서 그 문자열만 꺼내려면 yq -r '.data."dump.json"' 를 쓰세요. 이렇게 해 두면 값의 타입까지 눈으로 확인할 수 있습니다 — YAML 로 덤프하면 문자열인지 숫자인지가 따옴표 규칙에 가려집니다.
점·쉼표·중괄호 — set 의 문법
기본값을 고치지 말고 --set 만으로 image.repository 를 registry.local/web 로, replicas 를 5 로, args 를 alpha·beta·gamma 세 원소의 리스트로 바꿔 렌더하고 그 JSON 을 /root/hc-set/out/basics.json 에 저장하세요.
점은 깊이를 파고, 쉼표는 한 옵션 안에서 여러 값을 나눕니다. 리스트를 통째로 주려면 중괄호로 감싼 목록({a,b,c})을 씁니다 — 셸이 중괄호를 먼저 펼치지 않도록 따옴표로 감싸세요. --set 은 여러 번 쓸 수도 있습니다.
키 안에 점이 들어 있을 때
--set 으로 nodeSelector 에 kubernetes.io/os: linux 를, config 에 feature.flag: beta 를 넣어 렌더하고 JSON 을 /root/hc-set/out/escape.json 에 저장하세요. 두 키 모두 이름 안에 점이 들어 있습니다.
아무 처리 없이 쓰면 점이 깊이를 파는 기호로 읽혀 kubernetes 아래 io/os 라는 중첩 맵이 만들어집니다. 키의 일부인 점은 역슬래시로 탈출합니다(\.). 셸도 역슬래시를 먹으므로 옵션 전체를 작은따옴표로 감싸는 편이 안전합니다.
숫자로 읽히는 값과 그렇지 않은 값
같은 태그를 세 가지로 넣어 렌더하고 각각 저장하세요 — --set image.tag=8 은 /root/hc-set/out/num-set.json, --set-string image.tag=8 은 /root/hc-set/out/num-setstring.json, --set image.tag=1.10 은 /root/hc-set/out/num-float.json 입니다. 세 파일에서 image.tag 의 JSON 타입이 어떻게 갈리는지 확인하세요.
--set 은 값이 정수로 읽히면 숫자로 넣습니다. 소수점이 든 값이나 0 으로 시작하는 값은 정수로 읽히지 않아 문자열로 남습니다 — 직접 렌더해서 확인하세요. 타입은 jq -r '.image.tag | type' 으로 볼 수 있습니다. 이미지 태그처럼 숫자로 보이는 문자열이 문제를 일으키는 자리가 바로 여기입니다.
리스트와 객체를 통째로 넣는다
--set-json 으로 config 를 {"retries": 3, "mode": "strict"} 로, args 를 ["--a", "--b"] 로 넣어 렌더하고 JSON 을 /root/hc-set/out/setjson.json 에 저장하세요. retries 는 숫자여야 합니다.
--set 으로 중첩 객체를 만들려면 config.retries=3,config.mode=strict 처럼 평평하게 풀어써야 하고, 리스트 안에 객체가 들어가면 금세 읽기 어려워집니다. --set-json 은 값을 JSON 그대로 받으므로 타입도 의도한 대로 들어갑니다. 셸이 중괄호와 따옴표를 건드리지 않도록 작은따옴표로 감싸세요.
파일 내용을 값으로 넣는다
/root/hc-set/ca.pem 에 인증서 모양의 세 줄짜리 파일을 만드세요(-----BEGIN CERTIFICATE-----, MIIBkTCB+wIJAKt, -----END CERTIFICATE-----). 이 파일의 내용을 config.ca 값으로 넣어 렌더하고 JSON 을 /root/hc-set/out/setfile.json 에 저장하세요. 경로가 아니라 내용이 들어가야 합니다.
--set config.ca=/root/... 로 주면 경로 문자열이 그대로 값이 됩니다. 파일을 읽어 넣는 전용 옵션이 따로 있습니다(helm template --help 에서 set 으로 시작하는 옵션들을 훑어보세요). 인증서·설정 파일 본문처럼 여러 줄짜리 값을 넣을 때 씁니다.
값을 지우고, 리스트 원소를 집어서 고친다
--set 으로 image.tag 를 지워서(키 자체가 없어져야 합니다) 렌더한 JSON 을 /root/hc-set/out/null.json 에, args 의 0번 원소에 name: first 와 value: 1 을 넣어 렌더한 JSON 을 /root/hc-set/out/index.json 에 저장하세요. value 는 숫자여야 합니다.
--set key=null 은 그 키를 비우는 것이 아니라 없앱니다. 빈 문자열(key=)과는 다른 결과입니다 — 차트가 if .Values.image.tag 로 분기한다면 두 경우가 같게 동작하지만, hasKey 로 보는 곳에서는 갈립니다. 리스트 원소는 args[0].name=... 처럼 대괄호로 자리를 집습니다.
같은 값을 파일로 줄 때와 set 으로 줄 때
/root/hc-set/override.yaml 에 image.tag: "8" 과 replicas: 5 를 적고 그 파일로 렌더한 JSON 을 /root/hc-set/out/via-file.json 에 저장하세요. 같은 두 값을 --set image.tag=8 --set replicas=5 로 준 결과를 /root/hc-set/out/via-set.json 에, --set-string image.tag=8 --set replicas=5 로 준 결과를 /root/hc-set/out/via-setstring.json 에 저장합니다. 파일 판과 set 판의 차이를 diff 로 떠서 /root/hc-set/out/compare.txt 에 남기세요(차이가 있으므로 diff 는 0 이 아닌 코드로 끝납니다).
세 파일 중 둘은 완전히 같고 하나만 다릅니다. 어느 둘인지 먼저 예상해 보고 확인하세요. jq -S . <파일> 로 키 순서를 정렬해 두면 비교가 쉽습니다. diff 가 0 이 아닌 코드로 끝나므로 || true 를 붙이거나 종료 코드를 무시하는 식으로 쓰세요.