LabHub
배우기 러닝패스 코스

CKAD — Kubernetesアプリケーション開発者

プローブの設計と中断バジェット

LabHub 에서 이어서 보기

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

목표

세 가지 프로브를 검사 방식(httpGet/tcpSocket/exec)과 타이밍 필드까지 지정해서 만들고, Deployment 의 준비 상태와 종료 동작, 그리고 PodDisruptionBudget 을 설계할 수 있게 된다.

왜 중요한가

프로브를 안 붙인 Deployment 는 롤링 업데이트의 안전장치가 전부 무력화된 상태다. maxUnavailable: 0 을 줘도 컨테이너가 뜬 즉시 Ready 로 간주되어 초기화 중인 파드로 트래픽이 흘러 들어간다. 반대로 프로브를 너무 공격적으로 잡으면 정상 파드가 계속 재시작되면서 오히려 장애를 만든다. 그래서 프로브는 "붙였는가"가 아니라 "숫자를 계산해서 붙였는가"가 관건이다.

liveness 와 readiness 를 헷갈리면 사고가 커진다. 의존 서비스(DB)가 잠깐 죽었을 때 그걸 liveness 로 검사하면, 모든 파드가 동시에 재시작을 반복하며 DB 가 살아나도 회복이 늦어진다. 외부 의존성은 readiness 로 검사한다 — 트래픽만 안 받으면 되고 재시작할 이유는 없다.

startup 프로브는 이 둘 사이의 긴장을 푼다. liveness 에 initialDelaySeconds: 300 을 주면 운영 중 장애 감지도 5분 늦어지지만, startup 으로 300초 예산을 따로 주면 기동 후에는 liveness 를 촘촘하게 유지할 수 있다.

단계

  1. 네임스페이스 ckad-obs 를 만들고 파드 web-live 를 만든다. 이미지 nginx:1.27, livenessProbehttpGet 으로 path /healthz, port 80, initialDelaySeconds: 5, periodSeconds: 10.
  2. 파드 db-ready 를 만든다. 이미지 nginx:1.27, readinessProbetcpSocket port 5432, initialDelaySeconds: 10, periodSeconds: 5, failureThreshold: 3.
  3. 파드 file-check 를 만든다. 이미지 busybox:1.36, command: ["/bin/sh","-c","sleep 3600"], livenessProbeexec 으로 command: ["cat","/tmp/healthy"], periodSeconds: 5, failureThreshold: 2.
  4. 파드 legacy-app 을 만든다. 이미지 nginx:1.27. startupProbehttpGet path /startup, port 8080, failureThreshold: 30, periodSeconds: 10 (= 300초 예산). 같은 컨테이너에 livenessProbehttpGet path /healthz, port 8080, periodSeconds: 10 으로 붙인다.
  5. 파드 budget-app 을 만든다. 이미지 nginx:1.27, readinessProbehttpGet path /ready, port 80, initialDelaySeconds: 15. 첫 실패 이후 20초 안에 엔드포인트에서 빠지도록 periodSecondsfailureThreshold 를 직접 정한다. 조건은 periodSeconds × failureThreshold ≤ 20, failureThreshold ≥ 3, periodSeconds ≥ 2.
  6. Deployment api 를 만든다. 레플리카 3, 라벨 app=api, 이미지 nginx:1.27. 컨테이너에 readinessProbe(httpGet /ready:8080)와 livenessProbe(httpGet /healthz:8080)를 붙이고, terminationMessagePolicy: FallbackToLogsOnError 를 지정한다.
  7. PodDisruptionBudget api-pdb 를 만든다. minAvailable: 2, selectorapp=api.
  8. Deployment apistartupProbe 를 추가한다 — httpGet path /startup, port 8080, failureThreshold: 12, periodSeconds: 5. 그리고 파드 스펙의 terminationGracePeriodSeconds60 으로 설정한다. 기존 readiness/liveness 프로브와 레플리카 3은 그대로 유지한다.

참고

HTTP liveness 프로브

네임스페이스 ckad-obs 를 만들고 파드 web-live 를 만든다. 이미지 nginx:1.27, livenessProbehttpGet 으로 path /healthz, port 80, initialDelaySeconds: 5, periodSeconds: 10.

livenessProbe.httpGetpathport 를 준다. 프로브는 컨테이너 밑에 있고 파드 수준이 아니다. 응답 코드 200~399 면 성공으로 본다.

TCP readiness 프로브

파드 db-ready 를 만든다. 이미지 nginx:1.27, readinessProbetcpSocket port 5432, initialDelaySeconds: 10, periodSeconds: 5, failureThreshold: 3.

tcpSocket 은 포트만 있으면 된다 — 연결이 맺어지면 성공이다. readiness 는 실패해도 재시작하지 않고 엔드포인트에서만 빠진다.

exec 프로브

파드 file-check 를 만든다. 이미지 busybox:1.36, command: ["/bin/sh","-c","sleep 3600"], livenessProbeexec 으로 command: ["cat","/tmp/healthy"], periodSeconds: 5, failureThreshold: 2.

exec.command 는 문자열 배열이고 셸을 거치지 않는다. 종료 코드 0 이면 성공이다. 파일 존재만 확인하려면 굳이 셸을 부를 필요가 없다.

startup 프로브로 느린 기동 감싸기

파드 legacy-app 을 만든다. 이미지 nginx:1.27. startupProbehttpGet path /startup, port 8080, failureThreshold: 30, periodSeconds: 10 (= 300초 예산). 같은 컨테이너에 livenessProbehttpGet path /healthz, port 8080, periodSeconds: 10 으로 붙인다.

startup 프로브가 성공하기 전까지 liveness/readiness 는 아예 시작하지 않는다. 기동 예산은 periodSeconds × failureThreshold 로 계산한다. 이 파드에는 liveness 도 함께 붙인다.

감지 지연을 계산해서 값 정하기

파드 budget-app 을 만든다. 이미지 nginx:1.27, readinessProbehttpGet path /ready, port 80, initialDelaySeconds: 15. 첫 실패 이후 20초 안에 엔드포인트에서 빠지도록 periodSecondsfailureThreshold 를 직접 정한다. 조건은 periodSeconds × failureThreshold ≤ 20, failureThreshold ≥ 3, periodSeconds ≥ 2.

첫 실패부터 조치까지 걸리는 시간은 대략 periodSeconds × failureThreshold 다. 요구된 상한 안에 들어오면서 failureThreshold 를 충분히 크게 두어 일시적 실패에 흔들리지 않게 만든다. 정답은 하나가 아니다.

Deployment 에 프로브와 종료 메시지 정책 붙이기

Deployment api 를 만든다. 레플리카 3, 라벨 app=api, 이미지 nginx:1.27. 컨테이너에 readinessProbe(httpGet /ready:8080)와 livenessProbe(httpGet /healthz:8080)를 붙이고, terminationMessagePolicy: FallbackToLogsOnError 를 지정한다.

Deployment 의 프로브는 spec.template.spec.containers[] 밑에 들어간다. 종료 메시지 정책은 같은 컨테이너 수준 필드이고, 값이 두 가지뿐이니 kubectl explain 으로 확인한다.

PodDisruptionBudget 으로 자발적 중단 제한

PodDisruptionBudget api-pdb 를 만든다. minAvailable: 2, selectorapp=api.

PDB 는 policy/v1 이고 minAvailable 또는 maxUnavailable 중 하나만 쓴다. selector 는 Deployment 가 아니라 파드 라벨을 가리켜야 한다.

기동 예산과 종료 예산을 함께 (종합)

Deployment apistartupProbe 를 추가한다 — httpGet path /startup, port 8080, failureThreshold: 12, periodSeconds: 5. 그리고 파드 스펙의 terminationGracePeriodSeconds60 으로 설정한다. 기존 readiness/liveness 프로브와 레플리카 3은 그대로 유지한다.

앞에서 만든 Deployment 에 startup 프로브를 추가하고 종료 유예 시간을 늘린다. terminationGracePeriodSeconds 는 파드 스펙(spec.template.spec) 수준이고 컨테이너 수준이 아니다. 기존 liveness/readiness 는 그대로 남겨 둔다.