IT/Kubernets

kubectl wait --for=jsonpath, 이거 모르면 손해다

gfrog 2026. 9. 2. 09:11

CI 파이프라인이나 헬름 훅에서 리소스가 특정 상태가 될 때까지 기다리는 코드, 다들 어떻게 짜시나요? 우리 팀에도 얼마 전까지는 while true; do kubectl get ...; sleep 5; done 이런 게 아직 몇 개 남아있었다. 근데 사실 kubectl wait --for=jsonpath만 알면 대부분 정리 가능하다. 이거 v1.26에서 들어온 뒤로 꾸준히 개선되고 있는데 의외로 모르는 팀이 많더라.

뭐가 좋아졌나

예전 kubectl waitcondition=Ready 같은 정형화된 컨디션이나 --for=create/delete 정도만 됐다. 그래서 "LoadBalancer 서비스의 external IP가 붙을 때까지 대기" 같은, 필드 값 하나에 딱 걸리는 대기 로직은 셸 루프로 짜야 했다.

지금은 이렇게 된다.

kubectl wait --for=jsonpath='{.status.loadBalancer.ingress[0].ip}' \
  service/my-lb --timeout=300s

값이 있으면 통과, 없으면 대기. 한 줄이다.

그리고 은근히 중요한 포인트 하나 — v1.26부터는 JSONPath가 가리키는 필드 자체가 아직 없는 상태도 정상적으로 대기한다. 그 전에는 필드가 없으면 에러로 끝나서, 필드 존재 여부를 확인하는 프리 스텝을 하나 더 넣어야 했다. 이제 그 워크어라운드는 다 지워도 된다. (참고로 v1.31-rc.1에서 이 동작이 잠깐 깨졌다가 GA 전에 다시 픽스됐다. 혹시 지금 1.31 초기 RC 물려있으면 확인해 볼 것.)

자주 쓰는 패턴 몇 개

특정 값과 정확히 일치해야 하는 경우:

# StatefulSet 3개 replica가 다 준비될 때까지
kubectl wait --for=jsonpath='{.status.readyReplicas}'=3 \
  statefulset/postgres --timeout=180s

# CRD가 Established로 넘어갈 때까지 (오퍼레이터 설치 후)
kubectl wait --for=condition=Established \
  crd/prometheuses.monitoring.coreos.com --timeout=60s

값이 존재하기만 하면 되는 경우엔 =값 부분을 빼면 된다. 이게 external IP나 dynamic하게 뽑히는 토큰 시크릿 대기에 편하다.

한 가지 주의

--for=jsonpath는 값이 나타나는 시점까지만 본다. 예를 들어 readyReplicas=3을 기다렸는데 그 순간을 지나 롤링 업데이트가 이어지면서 잠깐 2로 떨어졌다가 다시 3이 되는 케이스, 이건 이미 통과해버려서 뒤 상태를 못 잡는다. 롤아웃 완료를 진짜 보고 싶으면 kubectl rollout status가 여전히 맞다. wait는 "단순히 이 값이 처음 참이 되는 순간"을 기다리는 도구라고 생각하면 편하다.

셸 루프로 대충 짜둔 대기 로직 있으면 오늘 하나만 골라서 바꿔보길 추천한다. 파이프라인 로그도 훨씬 깔끔해진다.