LabHub
배우기 러닝패스 코스

Authoring and Shipping Helm Charts

The Field I Edited by Hand Disappeared on Upgrade

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

클러스터에서 손으로 고친 값과 라벨이 helm upgrade 뒤에 어떻게 되는지 직접 만들어 확인하고, 이전 사용자 값을 이어받는 세 가지 옵션의 차이를 릴리스 기록으로 비교한다.

왜 중요한가

헬름 3 은 업그레이드할 때 옛 매니페스트·새 매니페스트·클러스터 실물 셋을 놓고 패치를 만든다. 이 규칙 하나로 현장에서 반복되는 두 가지 현상이 설명된다 — 장애 중에 kubectl scale 로 올려 둔 복제 수는 다음 배포에서 되돌아가고, 급히 붙여 둔 라벨은 그대로 남는다. 차트가 선언한 필드는 선언이 이기고, 차트가 모르는 필드는 건드리지 않기 때문이다. 여기에 값 쪽 규칙이 하나 더 있다. helm upgrade 는 기본적으로 이전 릴리스의 사용자 값을 이어받지 않는다. 그래서 배포 스크립트가 --set 을 하나 빠뜨리면 그 값은 조용히 차트 기본값으로 돌아간다. --reuse-values 는 이 문제를 풀지만 값이 릴리스 안에만 남아 저장소에서 보이지 않게 만든다. 어느 쪽을 쓸지는 취향이 아니라 '배포를 재현할 수 있는가' 로 정해야 하고, 그러려면 세 옵션이 실제로 무엇을 하는지 한 번 봐야 한다.

단계

  1. /root/hc-upgrade/ledger 차트(이름 ledger, 버전 0.1.0)를 만드세요. values.yamlreplicas: 1, image: "registry.local/ledger:1.0.0", extraLabel: "" 세 값입니다. templates/deployment.yaml 은 이름이 <릴리스이름>-ledger 인 Deployment 이고, metadata.labelsapp: ledger 를 두되 extraLabel 이 비어 있지 않을 때만 tier: <그 값> 을 더합니다. 릴리스 이름 books 로 설치한 뒤 helm get manifest books/root/hc-upgrade/out/rev1-manifest.yaml 에 저장하세요.
  2. kubectlbooks-ledger Deployment 의 복제 수를 5 로 올리고 라벨 owner=ops 를 붙이세요. 그 상태를 /root/hc-upgrade/out/before-upgrade.json{"replicas": …, "owner": …, "tier": …} 세 키의 JSON 으로 저장합니다(없는 라벨은 null).
  3. 차트도 값도 전혀 바꾸지 않은 채 helm upgrade books /root/hc-upgrade/ledger 를 돌리세요. 그다음 같은 세 키의 JSON 을 /root/hc-upgrade/out/after-upgrade.json 에 저장하고, 손으로 고친 두 가지 중 무엇이 살아남고 무엇이 되돌아갔는지 확인하세요.
  4. --set extraLabel=gold 로 업그레이드해 tier 라벨이 붙은 상태를 /root/hc-upgrade/out/label-added.json 에 저장하세요. 이어서 extraLabel빈 문자열로 주어 다시 업그레이드해 tier 라벨이 사라진 상태를 /root/hc-upgrade/out/label-removed.json 에 저장합니다. 두 파일 모두 같은 세 키의 JSON 입니다. 이때 owner 라벨은 어떻게 되는지도 함께 보세요.
  5. --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 이 어떻게 되는지가 답입니다.
  6. 이전 릴리스의 사용자 값을 이어받으면서 --set extraLabel=bronze 만 더해 업그레이드하세요. helm get values books -o json 결과를 /root/hc-upgrade/out/values-reuse.json 에 저장합니다. replicas 는 앞 단계의 6 이 남고 extraLabel 은 bronze 여야 합니다.
  7. 먼저 --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 에 저장하세요.
  8. --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.jsonmanual_scale_kept·manual_label_kept·chart_removed_label_deleted·default_upgrade_reuses_values·manual_label_survives_force 다섯 불리언과 final_replicas 숫자를 적으세요. 값은 앞 단계에서 저장한 파일들에서 읽습니다.

참고

되돌려 볼 것을 먼저 배포한다

/root/hc-upgrade/ledger 차트(이름 ledger, 버전 0.1.0)를 만드세요. values.yamlreplicas: 1, image: "registry.local/ledger:1.0.0", extraLabel: "" 세 값입니다. templates/deployment.yaml 은 이름이 <릴리스이름>-ledger 인 Deployment 이고, metadata.labelsapp: ledger 를 두되 extraLabel 이 비어 있지 않을 때만 tier: <그 값> 을 더합니다. 릴리스 이름 books 로 설치한 뒤 helm get manifest books/root/hc-upgrade/out/rev1-manifest.yaml 에 저장하세요.

kwok 클러스터에서는 파드가 실제로 돌지 않지만 Deployment 오브젝트는 정상으로 만들어집니다 — 이 실습은 오브젝트의 필드 값만 봅니다. 라벨을 조건부로 붙이는 부분은 {{- if .Values.extraLabel }} 블록으로 감싸고, 앞의 - 로 조건이 거짓일 때 빈 줄이 남지 않게 하세요.

클러스터에서 손으로 고친다

kubectlbooks-ledger Deployment 의 복제 수를 5 로 올리고 라벨 owner=ops 를 붙이세요. 그 상태를 /root/hc-upgrade/out/before-upgrade.json{"replicas": …, "owner": …, "tier": …} 세 키의 JSON 으로 저장합니다(없는 라벨은 null).

kubectl scale deploy/books-ledger --replicas=5kubectl 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.jsonmanual_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 을 견주면 그대로 나옵니다.