IT/Kubernets

Helm --set-json, 이거 모르는 분 꽤 많더라

gfrog 2026. 8. 9. 21:10

오늘 팀원한테 Helm values override 얘기를 하다가 알게 됐다. --set-json 플래그 쓰는 사람이 생각보다 적더라. 대부분 --set으로 어떻게든 우겨넣거나 임시 values 파일 만들어서 -f로 넘긴다.

근데 CI 파이프라인에서 잠깐 하나만 override할 때는 이게 좀 애매하다. values 파일 만들자니 번거롭고, --set으로 배열/객체 넣자니 콤마 이스케이프 지옥이 시작된다. 이럴 때 --set-json이 답이다.

--set의 콤마 지옥

sidecar 하나 붙이려고 --set으로 배열 넣어본 적 있으면 안다. 이런 걸 만나게 된다.

# 실패 확률 높은 코드
helm install redis ./chart \
  --set master.sidecars[0].name=logger \
  --set master.sidecars[0].image=fluent/fluent-bit \
  --set master.sidecars[0].ports[0].containerPort=2020

배열 인덱스 문법도 그렇고, 값에 콤마가 하나라도 들어가면 (resources.limits.cpu=1,memory=256Mi 같은) 이스케이프 규칙 때문에 진짜 짜증난다. 인용부호 규칙도 shell/CI 러너마다 달라서 로컬에서 되던 게 GitHub Actions에서 깨진다.

--set-json으로 그냥 JSON 넘기기

Helm 3.10부터 정식으로 지원한다. 이렇게 쓴다.

helm install redis ./chart --set-json '
master.sidecars=[
  {
    "name":"logger",
    "image":"fluent/fluent-bit:3.1",
    "ports":[{"containerPort":2020}]
  }
]'

또는 아예 최상위 오브젝트를 통째로.

helm upgrade redis ./chart --set-json '{
  "master":{
    "sidecars":[{"name":"logger","image":"fluent/fluent-bit:3.1"}],
    "resources":{"limits":{"cpu":"500m","memory":"512Mi"}}
  }
}'

핵심은 값 부분에 JSON 리터럴이 그대로 들어간다는 것. Helm 내부에서 JSON 파서로 처리해주니까 콤마 이스케이프 신경 안 써도 된다. 배열 순서, nested object, null까지 다 정확히 표현된다.

어디에 유용한가

우리 팀에서는 주로 두 군데 쓴다.

첫째, ArgoCD ApplicationSet의 helm.parameters 대신 helm.valuesObject 못 쓰는 구버전 환경에서 임시 override할 때. JSON 문자열 하나로 복잡한 구조를 밀어넣을 수 있다.

둘째, CI에서 이미지 태그 + 롤아웃 전략을 한 번에 바꿀 때. 두 값이 각자 다른 경로에 있으면 --set 두 번 쓰는 것보다 --set-json으로 한 방에 넘기는 게 깔끔하다.

주의할 점 하나. shell 인용부호를 잘못 쓰면 여전히 깨진다. bash에서는 바깥은 single quote, JSON 내부는 double quote 조합이 안전하다. PowerShell이면 얘기가 또 달라진다.

이것만 알아도 삽질 시간 꽤 줄어든다. 다들 한번 써보시길.