LabHub
배우기 러닝패스 코스

Helm Deployment and Rollback Scenarios

In What Order Are values Merged

LabHub 에서 이어서 보기

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

한 줄 요약

-f 는 여러 번 쓸 수 있고 뒤에 온 것이 이긴다. --set 은 모든 -f 를 이긴다. 이 순서를 모르면 "분명히 값을 넣었는데 반영이 안 된다" 로 하루를 태운다.

Concept map: 뒤에 온 것이 이긴다. · 낮은 것부터 · 맵은 병합되지만 배열은 통째로 교체된다. · --set 의 쉼표와 점.

왜 이게 필요했나

운영 배포는 values 파일이 보통 두세 겹이다. 차트 기본값, 환경별 값, 그리고 CI 가 주입하는 이미지 태그. 어느 것이 이기는지 헷갈리면 스테이징 값이 프로덕션에 새어 들어간다.

우선순위는 낮은 것부터 이렇다.

  1. 차트의 values.yaml
  2. 부모 차트가 서브차트에 준 값
  3. -f a.yaml (먼저 온 것)
  4. -f b.yaml (나중에 온 것 — a 를 덮는다)
  5. --set / --set-string / --set-file

어떻게 동작하나

합쳐진 결과를 추측하지 말고 확인한다.

helm template demo ./chart -f prod.yaml --set image.tag=abc123 \
  --show-only templates/deployment.yaml

helm get values demo            # 배포된 릴리스에 실제로 들어간 값
helm get values demo --all      # 기본값까지 합친 전체

helm get values 는 사고 조사에서 가장 먼저 치는 명령이다. "무슨 값으로 떴는가" 에 대한 유일한 사실이다.

흔한 착각

맵은 병합되지만 배열은 통째로 교체된다. -f 두 개에 각각 리스트가 있으면 합쳐지지 않고 뒤엣것이 앞엣것을 통째로 덮는다. 그래서 extraEnv 같은 리스트를 환경별로 나눠 두면 하나만 남는다. 리스트를 합치고 싶으면 맵으로 설계하는 것이 정석이다.

--set 의 쉼표와 점. --set a.b=1,a.c=2 는 두 값이다. 값 안에 쉼표가 있으면 \, 로 이스케이프해야 한다. 이걸 놓쳐서 이미지 태그가 잘리는 사고가 흔하다. 값이 복잡하면 --set-string 이나 임시 values 파일을 쓰는 게 안전하다.

의존성은 잠가 두어야 재현된다

Chart.yamldependencies 에 적은 버전은 범위 입니다.

dependencies:
  - name: postgresql
    version: "15.x.x"        # 15.5.0 도, 15.9.2 도 이 범위다
    repository: https://charts.bitnami.com/bitnami

helm dependency update 를 돌릴 때마다 다른 버전이 잡힐 수 있습니다. 그 결과가 Chart.lock 에 적히고, 이 파일을 저장소에 커밋해야 다른 사람과 CI 가 같은 것을 받습니다. .gitignore 에 넣어 두면 "내 컴퓨터에서는 되는데" 가 시작됩니다.

helm dependency build     # Chart.lock 대로 받는다 (재현된다)
helm dependency update    # 범위를 다시 풀어 lock 을 갱신한다 (의도할 때만)

CI 에서는 build 를 씁니다. update 를 쓰면 매 배포마다 다른 의존성이 올 수 있습니다.

조건과 태그로 켜고 끄기

서브차트를 상황에 따라 빼야 할 때가 있습니다. 개발에서는 차트에 딸린 PostgreSQL 을 쓰고, 운영에서는 관리형 DB 를 쓰는 식입니다.

# Chart.yaml
dependencies:
  - name: postgresql
    version: 15.5.0
    repository: https://charts.bitnami.com/bitnami
    condition: postgresql.enabled     # 이 값이 false 면 통째로 빠진다
# values/prod.yaml
postgresql:
  enabled: false
externalDatabase:
  host: labhub-db-prod-rw.labhub-prod.svc

condition 은 값 하나를 보고, tags 는 여러 서브차트를 한 스위치로 묶습니다. 조건이 거짓이면 렌더링 자체가 되지 않으므로, 그 서브차트의 값이 잘못돼 있어도 배포가 통과합니다 — 켜는 순간 처음 드러납니다.

왜 값이 안 먹는지 세 걸음으로 찾기

# 1) 최종 값이 무엇인가 — 여기서 대개 끝난다
helm template demo ./chart -f prod.yaml --set image.tag=abc | grep -A2 image:

# 2) 값은 맞는데 템플릿이 안 쓰는가
helm template demo ./chart --debug 2>&1 | head -40      # 렌더 전 값이 보인다

# 3) 배포된 릴리스에 실제로 들어간 값
helm get values demo --all

2번에서 자주 나오는 원인이 오타 입니다. imagePullSecretsimagePullSecret 으로 적어도 Helm 은 아무 말 하지 않습니다 — 값은 그냥 쓰이지 않을 뿐입니다. 그래서 차트에 values.schema.json 을 두면 모르는 키를 배포 전에 잡을 수 있습니다.

실무에서 진짜 중요한 것

서브차트의 값은 부모 차트에서 서브차트 이름을 키로 지정한다.

# 부모 차트의 values.yaml
postgresql:
  auth:
    database: labhub

global: 아래 둔 값만 모든 서브차트가 함께 본다. 이 구분을 모르면 "서브차트가 값을 안 읽는다" 로 헤맨다.