Authoring and Shipping Helm Charts
Package a Chart, Publish It to a Private Repository, and Pull It Back
한국어 원문으로 표시합니다.
목표
차트 디렉터리를 tgz 로 꾸리고, 색인을 만들어 사설 HTTP 저장소로 올리고, 그 저장소에서 판을 골라 받아 오고, 다른 차트의 의존성으로 잠그는 한 바퀴를 손으로 돌린다.
왜 중요한가
차트가 내 디렉터리를 떠나는 순간 남는 것은 tgz 와 index.yaml 두 가지뿐이다. 차트 저장소는 그 둘을 내려 주는 정적 HTTP 서버 이상이 아니고, 그래서 사내 저장소를 세우는 일은 생각보다 작다. 대신 작아서 생기는 사고가 있다 — 색인은 자동으로 갱신되지 않으므로 새 판을 올릴 때 --merge 를 빠뜨리면 옛 판이 목록에서 통째로 사라진다. 받는 쪽에서는 version 과 appVersion 을 혼동해 '애플리케이션은 그대로인데 왜 판이 올랐냐' 는 질문이 반복된다. 마지막으로 의존성은 build 와 update 중 무엇을 쓰느냐에 따라 CI 가 재현 가능한 빌드를 하기도 하고 매번 다른 판을 물어 오기도 한다. 이 세 가지를 한 번씩 직접 일으켜 보면 다음부터는 눈에 보인다.
단계
/root/hc-package에서helm create catalog로 차트를 만들고,/root/hc-package/catalog/Chart.yaml의version을1.0.0,appVersion을"2.4.0",description을상품 목록 서비스로 바꾸세요. 이 두 버전이 서로 다른 것을 가리킨다는 사실이 이 실습 내내 판정 기준입니다./root/hc-package/repo디렉터리에catalog를 두 번 꾸리세요. 첫 번째는 차트 버전1.0.0· appVersion2.4.0, 두 번째는 차트 버전1.1.0· appVersion2.5.0입니다.Chart.yaml을 다시 고치지 말고helm package의 옵션으로 덮어쓰세요. 결과 파일 이름이 무엇으로 정해지는지 확인하세요.helm repo index로/root/hc-package/repo/index.yaml을 만드세요. 색인에catalog항목이 두 판 모두 들어 있어야 하고, 각 판에digest와urls가 있어야 합니다. 색인을 열어appVersion이 판마다 다르게 적혀 있는 것을 확인하세요./root/hc-package/repo를python3 -m http.server 8971 --bind 127.0.0.1로 서빙한 뒤,helm repo add hclocal http://127.0.0.1:8971로 등록하고helm repo update hclocal을 돌리세요. 차트 저장소가 정적 HTTP 서버 그 이상이 아니라는 것을 여기서 확인합니다.helm search repo hclocal/catalog를 모든 판이 나오도록 돌려 결과를 JSON 으로/root/hc-package/out/search.json에 저장하세요. 아무 옵션 없이 검색하면 몇 개가 나오는지도 먼저 보세요.- 저장소에서 1.0.0 판을 골라
/root/hc-package/pulled아래로 풀어 받으세요(/root/hc-package/pulled/catalog/Chart.yaml이 생겨야 합니다). 이어서 1.1.0 판의 Chart.yaml 을/root/hc-package/out/show-1.1.0.txt에, 기본값을/root/hc-package/out/show-values.yaml에 저장하세요. 받아서 풀지 않고도 내용을 볼 수 있다는 것이 요점입니다. /root/hc-package/stage에 차트 버전1.2.0· appVersion2.6.0을 꾸린 뒤, 기존 색인을 합쳐서/root/hc-package/stage/index.yaml을 만드세요. 합친 색인에는 세 판이 모두 있어야 합니다. 그다음 stage 의 tgz 와 index.yaml 을/root/hc-package/repo로 옮기고helm repo update hclocal을 돌려 세 판이 검색되는지 확인하세요./root/hc-package/storefront차트를 만들어catalog1.1.0을 저장소(http://127.0.0.1:8971)에서 받아 오도록 선언하고 의존성을 확정하세요. 그다음 선언을1.2.0으로 올리고helm dependency build를 먼저 돌려 그 출력을/root/hc-package/out/dep-build-error.txt에 저장한 뒤, 알맞은 명령으로 다시 확정하세요. 끝나면Chart.lock이1.2.0이고/root/hc-package/storefront/charts/catalog-1.2.0.tgz가 있어야 합니다.
참고
helm package <차트> --version <v> --app-version <a> -d <디렉터리>helm repo index <디렉터리> --merge <옛 index.yaml>helm search repo <저장소>/<차트> --versions -o json- helm 3 은
file://를 저장소 프로토콜로 받지 않는다 — 이 파드에서는python3 -m http.server로 띄운다 - 흔한 실수: 새 판을 올릴 때 색인을 합치지 않아 옛 판이 사라진다
- 흔한 실수: Chart.yaml 의 의존성 판을 고친 뒤
helm dependency build를 돌려 lock 어긋남 오류를 만난다 - 공식 문서: https://helm.sh/docs/topics/chart_repository/ · https://helm.sh/docs/helm/helm_repo_index/
꾸릴 차트에 신원을 먼저 적는다
/root/hc-package 에서 helm create catalog 로 차트를 만들고, /root/hc-package/catalog/Chart.yaml 의 version 을 1.0.0, appVersion 을 "2.4.0", description 을 상품 목록 서비스 로 바꾸세요. 이 두 버전이 서로 다른 것을 가리킨다는 사실이 이 실습 내내 판정 기준입니다.
version 은 차트 자신의 판 번호이고 appVersion 은 그 차트가 담아 나르는 소프트웨어의 판 번호입니다. 둘은 따로 움직입니다 — 템플릿만 고치면 version 만 오르고, 애플리케이션만 올리면 appVersion 만 오릅니다. appVersion 은 1.10 같은 값이 숫자로 해석되지 않도록 따옴표로 감싸는 것이 관례입니다.
두 판을 꾸려서 tgz 를 만든다
/root/hc-package/repo 디렉터리에 catalog 를 두 번 꾸리세요. 첫 번째는 차트 버전 1.0.0 · appVersion 2.4.0, 두 번째는 차트 버전 1.1.0 · appVersion 2.5.0 입니다. Chart.yaml 을 다시 고치지 말고 helm package 의 옵션으로 덮어쓰세요. 결과 파일 이름이 무엇으로 정해지는지 확인하세요.
helm package <차트> --version <v> --app-version <a> -d <디렉터리> 입니다. tgz 이름은 <이름>-<차트버전>.tgz 로 정해지며 appVersion 은 이름에 나타나지 않습니다 — 그래서 같은 appVersion 을 담은 차트 판이 여럿일 수 있습니다. 꾸린 tgz 안을 tar -tzf 로 들여다보세요.
저장소 색인을 만든다
helm repo index 로 /root/hc-package/repo/index.yaml 을 만드세요. 색인에 catalog 항목이 두 판 모두 들어 있어야 하고, 각 판에 digest 와 urls 가 있어야 합니다. 색인을 열어 appVersion 이 판마다 다르게 적혀 있는 것을 확인하세요.
helm repo index <디렉터리> 는 그 디렉터리의 tgz 를 전부 읽어 index.yaml 을 새로 씁니다. 색인은 저장소의 목록일 뿐이고, 실제 차트는 tgz 안에 있습니다. digest 는 tgz 의 sha256 이라 파일이 바뀌면 색인도 다시 만들어야 합니다.
저장소를 띄우고 helm 에 등록한다
/root/hc-package/repo 를 python3 -m http.server 8971 --bind 127.0.0.1 로 서빙한 뒤, helm repo add hclocal http://127.0.0.1:8971 로 등록하고 helm repo update hclocal 을 돌리세요. 차트 저장소가 정적 HTTP 서버 그 이상이 아니라는 것을 여기서 확인합니다.
서버는 백그라운드로 띄웁니다(&). helm 3 은 file:// 를 저장소 프로토콜로 받지 않습니다 — 직접 해 보면 could not find protocol handler for: file 이 납니다. 등록이 끝나면 $HOME/.config/helm/repositories.yaml 에 주소가 적히고 $HOME/.cache/helm/repository/ 아래에 색인 사본이 내려옵니다.
판을 모두 보이게 검색한다
helm search repo hclocal/catalog 를 모든 판이 나오도록 돌려 결과를 JSON 으로 /root/hc-package/out/search.json 에 저장하세요. 아무 옵션 없이 검색하면 몇 개가 나오는지도 먼저 보세요.
기본 검색은 저장소마다 가장 높은 판 하나만 보여 줍니다. 모든 판을 보려면 옵션이 하나 더 필요합니다. 출력 형식은 -o json 으로 바꿉니다. JSON 항목의 키는 name·version·app_version·description 입니다.
옛 판을 골라 받아서 풀어 본다
저장소에서 1.0.0 판을 골라 /root/hc-package/pulled 아래로 풀어 받으세요(/root/hc-package/pulled/catalog/Chart.yaml 이 생겨야 합니다). 이어서 1.1.0 판의 Chart.yaml 을 /root/hc-package/out/show-1.1.0.txt 에, 기본값을 /root/hc-package/out/show-values.yaml 에 저장하세요. 받아서 풀지 않고도 내용을 볼 수 있다는 것이 요점입니다.
helm pull <저장소>/<차트> --version <v> --untar -d <디렉터리> 는 tgz 를 받아 그 자리에서 풉니다. helm show chart 와 helm show values 는 받지 않고 저장소에서 바로 읽어 표준출력으로 내보냅니다 — helm show readme 도 같은 식입니다.
새 판을 올리면서 옛 판을 지우지 않는다
/root/hc-package/stage 에 차트 버전 1.2.0 · appVersion 2.6.0 을 꾸린 뒤, 기존 색인을 합쳐서 /root/hc-package/stage/index.yaml 을 만드세요. 합친 색인에는 세 판이 모두 있어야 합니다. 그다음 stage 의 tgz 와 index.yaml 을 /root/hc-package/repo 로 옮기고 helm repo update hclocal 을 돌려 세 판이 검색되는지 확인하세요.
helm repo index 는 기본적으로 그 디렉터리에 있는 tgz 만 보고 색인을 새로 씁니다. stage 에는 1.2.0 하나뿐이니 그대로 올리면 앞의 두 판이 목록에서 사라집니다. 옛 색인을 합치는 옵션이 따로 있습니다(helm repo index --help). 실무에서 이걸 빠뜨려 배포 파이프라인이 옛 판을 통째로 날리는 사고가 흔합니다.
저장소에서 의존성을 잠그고, 잠금이 어긋나게 만든다
/root/hc-package/storefront 차트를 만들어 catalog 1.1.0 을 저장소(http://127.0.0.1:8971)에서 받아 오도록 선언하고 의존성을 확정하세요. 그다음 선언을 1.2.0 으로 올리고 helm dependency build 를 먼저 돌려 그 출력을 /root/hc-package/out/dep-build-error.txt 에 저장한 뒤, 알맞은 명령으로 다시 확정하세요. 끝나면 Chart.lock 이 1.2.0 이고 /root/hc-package/storefront/charts/catalog-1.2.0.tgz 가 있어야 합니다.
build 는 Chart.lock 을 그대로 믿고 그 판을 받아 옵니다 — 그래서 CI 에서 쓰는 명령입니다. update 는 Chart.yaml 을 다시 읽어 범위를 풀고 lock 을 새로 씁니다. 선언을 고친 뒤 build 를 돌리면 둘이 어긋났다는 오류가 납니다. 출력을 파일로 남기려면 2>&1 로 오류도 함께 받으세요.