Authoring and Shipping Helm Charts
The Field I Edited by Hand Disappeared on Upgrade
한국어 원문으로 표시합니다.
목표
클러스터에서 손으로 고친 값과 라벨이 helm upgrade 뒤에 어떻게 되는지 직접 만들어 확인하고, 이전 사용자 값을 이어받는 세 가지 옵션의 차이를 릴리스 기록으로 비교한다.
왜 중요한가
헬름 3 은 업그레이드할 때 옛 매니페스트·새 매니페스트·클러스터 실물 셋을 놓고 패치를 만든다. 이 규칙 하나로 현장에서 반복되는 두 가지 현상이 설명된다 — 장애 중에 kubectl scale 로 올려 둔 복제 수는 다음 배포에서 되돌아가고, 급히 붙여 둔 라벨은 그대로 남는다. 차트가 선언한 필드는 선언이 이기고, 차트가 모르는 필드는 건드리지 않기 때문이다. 여기에 값 쪽 규칙이 하나 더 있다. helm upgrade 는 기본적으로 이전 릴리스의 사용자 값을 이어받지 않는다. 그래서 배포 스크립트가 --set 을 하나 빠뜨리면 그 값은 조용히 차트 기본값으로 돌아간다. --reuse-values 는 이 문제를 풀지만 값이 릴리스 안에만 남아 저장소에서 보이지 않게 만든다. 어느 쪽을 쓸지는 취향이 아니라 '배포를 재현할 수 있는가' 로 정해야 하고, 그러려면 세 옵션이 실제로 무엇을 하는지 한 번 봐야 한다.
단계
/root/hc-upgrade/ledger차트(이름ledger, 버전0.1.0)를 만드세요.values.yaml은replicas: 1,image: "registry.local/ledger:1.0.0",extraLabel: ""세 값입니다.templates/deployment.yaml은 이름이<릴리스이름>-ledger인 Deployment 이고,metadata.labels에app: ledger를 두되extraLabel이 비어 있지 않을 때만tier: <그 값>을 더합니다. 릴리스 이름books로 설치한 뒤helm get manifest books를/root/hc-upgrade/out/rev1-manifest.yaml에 저장하세요.kubectl로books-ledgerDeployment 의 복제 수를5로 올리고 라벨owner=ops를 붙이세요. 그 상태를/root/hc-upgrade/out/before-upgrade.json에{"replicas": …, "owner": …, "tier": …}세 키의 JSON 으로 저장합니다(없는 라벨은null).- 차트도 값도 전혀 바꾸지 않은 채
helm upgrade books /root/hc-upgrade/ledger를 돌리세요. 그다음 같은 세 키의 JSON 을/root/hc-upgrade/out/after-upgrade.json에 저장하고, 손으로 고친 두 가지 중 무엇이 살아남고 무엇이 되돌아갔는지 확인하세요. --set extraLabel=gold로 업그레이드해tier라벨이 붙은 상태를/root/hc-upgrade/out/label-added.json에 저장하세요. 이어서extraLabel을 빈 문자열로 주어 다시 업그레이드해tier라벨이 사라진 상태를/root/hc-upgrade/out/label-removed.json에 저장합니다. 두 파일 모두 같은 세 키의 JSON 입니다. 이때owner라벨은 어떻게 되는지도 함께 보세요.--set replicas=4 --set extraLabel=silver로 업그레이드하고helm get values books -o json을/root/hc-upgrade/out/values-1.json에 저장하세요. 이어서--set replicas=6하나만 주고 다시 업그레이드한 뒤 같은 명령의 결과를/root/hc-upgrade/out/values-2.json에 저장하세요.extraLabel이 어떻게 되는지가 답입니다.- 이전 릴리스의 사용자 값을 이어받으면서
--set extraLabel=bronze만 더해 업그레이드하세요.helm get values books -o json결과를/root/hc-upgrade/out/values-reuse.json에 저장합니다.replicas는 앞 단계의 6 이 남고extraLabel은 bronze 여야 합니다. - 먼저
--set replicas=4 --set extraLabel=silver로 업그레이드해 기준을 만드세요. 거기서--set replicas=7에 차트 기본값으로 되돌린 뒤 지난번 사용자 값을 다시 얹는 옵션을 붙여 업그레이드하고 결과를/root/hc-upgrade/out/values-rtr.json에 저장하세요. 이어서--set replicas=9에 지난번 값을 버리는 옵션을 붙여 업그레이드하고 결과를/root/hc-upgrade/out/values-reset.json에 저장하세요. --set replicas=3으로 서버 측 미리 보기를 돌려 출력을/root/hc-upgrade/out/dryrun.yaml에 저장하세요(릴리스는 바뀌지 않아야 합니다). 그다음 같은 값으로--force를 붙여 실제 업그레이드하고 그 뒤의 상태를 2단계와 같은 세 키의 JSON 으로/root/hc-upgrade/out/after-force.json에 저장하세요 — 손으로 붙인owner라벨이 어떻게 되는지 확인하세요.helm history books -o json을/root/hc-upgrade/out/history.json에 저장하고,/root/hc-upgrade/out/merge-report.json에manual_scale_kept·manual_label_kept·chart_removed_label_deleted·default_upgrade_reuses_values·manual_label_survives_force다섯 불리언과final_replicas숫자를 적으세요. 값은 앞 단계에서 저장한 파일들에서 읽습니다.
참고
helm get values <릴리스> -o json은 사용자가 준 값만,--all은 차트 기본값까지 보여 준다kubectl get deploy <이름> -o json | jq '{...}'로 필요한 필드만 뽑아 비교한다helm upgrade --dry-run=server는 API 서버까지 보내 검증만 하고 릴리스를 만들지 않는다- 흔한 실수: 장애 중
kubectl scale로 올린 값을 다음 배포가 되돌린다 - 흔한 실수: 배포 스크립트에서
--set하나를 빠뜨려 그 값만 기본값으로 돌아간다 - 공식 문서: https://helm.sh/docs/helm/helm_upgrade/ · https://helm.sh/docs/faq/changes_since_helm2/
되돌려 볼 것을 먼저 배포한다
/root/hc-upgrade/ledger 차트(이름 ledger, 버전 0.1.0)를 만드세요. values.yaml 은 replicas: 1, image: "registry.local/ledger:1.0.0", extraLabel: "" 세 값입니다. templates/deployment.yaml 은 이름이 <릴리스이름>-ledger 인 Deployment 이고, metadata.labels 에 app: ledger 를 두되 extraLabel 이 비어 있지 않을 때만 tier: <그 값> 을 더합니다. 릴리스 이름 books 로 설치한 뒤 helm get manifest books 를 /root/hc-upgrade/out/rev1-manifest.yaml 에 저장하세요.
kwok 클러스터에서는 파드가 실제로 돌지 않지만 Deployment 오브젝트는 정상으로 만들어집니다 — 이 실습은 오브젝트의 필드 값만 봅니다. 라벨을 조건부로 붙이는 부분은 {{- if .Values.extraLabel }} 블록으로 감싸고, 앞의 - 로 조건이 거짓일 때 빈 줄이 남지 않게 하세요.
클러스터에서 손으로 고친다
kubectl 로 books-ledger Deployment 의 복제 수를 5 로 올리고 라벨 owner=ops 를 붙이세요. 그 상태를 /root/hc-upgrade/out/before-upgrade.json 에 {"replicas": …, "owner": …, "tier": …} 세 키의 JSON 으로 저장합니다(없는 라벨은 null).
kubectl scale deploy/books-ledger --replicas=5 와 kubectl label deploy/books-ledger owner=ops --overwrite 두 명령입니다. 장애 대응 중에 흔히 하는 일이고, 문제는 그다음 배포에서 생깁니다. JSON 으로 뽑을 때는 kubectl get deploy books-ledger -o json | jq '{...}' 를 쓰세요.
차트를 하나도 안 바꾸고 업그레이드한다
차트도 값도 전혀 바꾸지 않은 채 helm upgrade books /root/hc-upgrade/ledger 를 돌리세요. 그다음 같은 세 키의 JSON 을 /root/hc-upgrade/out/after-upgrade.json 에 저장하고, 손으로 고친 두 가지 중 무엇이 살아남고 무엇이 되돌아갔는지 확인하세요.
헬름 3 은 옛 매니페스트·새 매니페스트·클러스터 실물 셋을 놓고 패치를 만듭니다. 차트가 값을 선언한 필드는 클러스터 실물이 달라도 선언 쪽으로 맞춰집니다. 차트가 아예 모르는 필드는 건드리지 않습니다. 두 규칙으로 결과를 설명할 수 있어야 합니다.
차트에서 뺀 필드는 클러스터에서도 지워진다
--set extraLabel=gold 로 업그레이드해 tier 라벨이 붙은 상태를 /root/hc-upgrade/out/label-added.json 에 저장하세요. 이어서 extraLabel 을 빈 문자열로 주어 다시 업그레이드해 tier 라벨이 사라진 상태를 /root/hc-upgrade/out/label-removed.json 에 저장합니다. 두 파일 모두 같은 세 키의 JSON 입니다. 이때 owner 라벨은 어떻게 되는지도 함께 보세요.
조건이 거짓이 되면 새 매니페스트에는 그 라벨이 없습니다. 헬름은 옛 매니페스트와 견주어 빠진 필드를 지우는 패치를 만듭니다. 반면 owner 는 어느 매니페스트에도 없었던 필드라 패치 대상이 아닙니다. 차트가 관리하는 것과 사람이 붙인 것의 경계가 여기서 갈립니다. 주의: 값을 하나도 주지 않고 업그레이드하면 헬름은 직전 릴리스의 사용자 값을 그대로 씁니다 — 그래서 --set 을 빼는 것만으로는 gold 가 사라지지 않습니다. 직접 해 보고 차이를 확인하세요.
업그레이드는 지난번 사용자 값을 버린다
--set replicas=4 --set extraLabel=silver 로 업그레이드하고 helm get values books -o json 을 /root/hc-upgrade/out/values-1.json 에 저장하세요. 이어서 --set replicas=6 하나만 주고 다시 업그레이드한 뒤 같은 명령의 결과를 /root/hc-upgrade/out/values-2.json 에 저장하세요. extraLabel 이 어떻게 되는지가 답입니다.
helm get values 는 사용자가 준 값만 보여 줍니다(차트 기본값까지 보려면 --all). 기본 동작에서 업그레이드는 이전 릴리스의 사용자 값을 이어받지 않고 이번에 준 것만 씁니다. 배포 스크립트가 매번 모든 --set 을 다시 적어야 하는 이유가 여기 있습니다.
지난번 값을 이어받아 한 값만 바꾼다
이전 릴리스의 사용자 값을 이어받으면서 --set extraLabel=bronze 만 더해 업그레이드하세요. helm get values books -o json 결과를 /root/hc-upgrade/out/values-reuse.json 에 저장합니다. replicas 는 앞 단계의 6 이 남고 extraLabel 은 bronze 여야 합니다.
이어받기 옵션이 따로 있습니다(helm upgrade --help 에서 reuse 가 든 것). 편해 보이지만 함정이 있습니다 — 이어받은 값은 명령줄에도 저장소에도 안 보이고 릴리스 안에만 있습니다. 그래서 오래된 릴리스일수록 '지금 무슨 값으로 돌고 있는지' 를 아무도 모르게 됩니다.
세 가지 이어받기 옵션을 나란히 놓는다
먼저 --set replicas=4 --set extraLabel=silver 로 업그레이드해 기준을 만드세요. 거기서 --set replicas=7 에 차트 기본값으로 되돌린 뒤 지난번 사용자 값을 다시 얹는 옵션을 붙여 업그레이드하고 결과를 /root/hc-upgrade/out/values-rtr.json 에 저장하세요. 이어서 --set replicas=9 에 지난번 값을 버리는 옵션을 붙여 업그레이드하고 결과를 /root/hc-upgrade/out/values-reset.json 에 저장하세요.
세 옵션의 이름이 서로 비슷해서 헷갈립니다 — helm upgrade --help 에서 셋을 나란히 읽어 보세요. 하나는 지난번 값을 그대로 이어받고, 하나는 기본값으로 되돌린 뒤 지난번 사용자 값을 다시 얹고, 하나는 지난번 값을 아예 버립니다. 저장된 두 파일의 키 개수 차이로 구분할 수 있습니다.
미리 보고, 교체로 적용하고, 규칙을 정리한다
--set replicas=3 으로 서버 측 미리 보기를 돌려 출력을 /root/hc-upgrade/out/dryrun.yaml 에 저장하세요(릴리스는 바뀌지 않아야 합니다). 그다음 같은 값으로 --force 를 붙여 실제 업그레이드하고 그 뒤의 상태를 2단계와 같은 세 키의 JSON 으로 /root/hc-upgrade/out/after-force.json 에 저장하세요 — 손으로 붙인 owner 라벨이 어떻게 되는지 확인하세요. helm history books -o json 을 /root/hc-upgrade/out/history.json 에 저장하고, /root/hc-upgrade/out/merge-report.json 에 manual_scale_kept·manual_label_kept·chart_removed_label_deleted·default_upgrade_reuses_values·manual_label_survives_force 다섯 불리언과 final_replicas 숫자를 적으세요. 값은 앞 단계에서 저장한 파일들에서 읽습니다.
--dry-run=server 는 API 서버까지 보내 검증만 하고 릴리스를 만들지 않습니다. --force 는 패치 대신 교체 방식으로 적용합니다 — 패치로는 바꿀 수 없는 불변 필드가 있을 때 쓰지만, 교체이므로 오브젝트가 통째로 새 매니페스트로 갈아 끼워집니다. 그러면 3단계에서 살아남았던 것이 이번에는 어떻게 될지 생각해 보고 확인하세요. 다섯 불리언은 2~5단계와 방금 저장한 JSON 을 견주면 그대로 나옵니다.