Cloudera AI Inference 에 올린 대형 모델이 "한 시간에 네 번씩 죽는다"는 증상을 추적한 기록이다. 결론은 모델이 죽은 것이 아니라 헬스체크 워치독이 실패로 판정해 스스로 재기동시키고 있었다는 것이다. 재기동 주기가 워치독의 루프 간격과 정확히 일치한다는 점이 첫 단서였다.
워치독 루프가 15분 간격이면 매 사이클 실패 판정 시 정확히 시간당 네 번 재기동이 일어난다. 장애 주기가 감시 주기와 딱 맞아떨어지면 감시 도구 자체를 먼저 의심한다.
NS=serving-default
ISVC=<inference-service>
kubectl get isvc $ISVC -n $NS -o yaml > ~/isvc-$(date +%F).yaml
kubectl get isvc $ISVC -n $NS -o jsonpath='{.spec.predictor.model.args}{"\n"}'
kubectl get isvc $ISVC -n $NS -o jsonpath='{.spec.predictor.model.env}{"\n"}'
kubectl get isvc $ISVC -n $NS -o jsonpath='{.spec.predictor.model.resources}{"\n"}'
POD=$(kubectl get pod -n $NS -l serving.kserve.io/inferenceservice=$ISVC \
-o jsonpath='{.items[0].metadata.name}')
kubectl exec -n $NS $POD -c kserve-container -- ps -ef | grep -i vllm
kubectl exec -n $NS $POD -c kserve-container -- env | grep -Ei 'VLLM|MAX|GPU'
스펙과 실제로 뜬 프로세스 인자가 다를 수 있으므로 양쪽을 대조한다.
컨테이너별 재시작 횟수가 결정적이다. 파드 단위로만 보면 무엇이 재시작했는지 알 수 없다.
kubectl get pod -n $NS $POD -o jsonpath='{range .status.containerStatuses[*]}{.name} restarts={.restartCount} lastReason={.lastState.terminated.reason} exit={.lastState.terminated.exitCode}{"\n"}{end}'
kubectl logs -n $NS $POD -c queue-proxy --previous --tail=100
모델 컨테이너의 재시작이 0 인데 사이드카만 카운트가 올라가 있으면 모델은 죽지 않은 것이다. 로그에 기동 직후의 공격적 프로브 오류가 보인다면 그것은 서비스 중이 아니라 파드가 새로 뜬 구간의 기록이므로, 장시간 유지된 파드의 현재 상태를 설명하지 못한다.
부하 시점의 엔진 행(hang)도 후보다. 프로세스는 살아 있어 포트는 열려 있지만 엔진 코어가 블록되면 메트릭 응답이 나오지 않아 프로브가 타임아웃된다. 긴 컨텍스트에 동시 요청 수 상한이 없으면 KV 캐시가 고갈되며 스케줄러가 멈춘다.
kubectl exec -n $NS $POD -c kserve-container -- \
curl -s localhost:<port>/v1/metrics | grep -Ei 'running|waiting|cache_usage|preemption'
num_requests_waiting 이 쌓이거나 num_preemptions_total 이 증가하면 그 방향이다. preemption 이 0 이면 KV 압박 흔적이 없다는 뜻이라 이 가설은 접는다.
curl -k -s -o /tmp/wd.out -w 'code=%{http_code} time=%{time_total}\n' \
-H "Authorization: Bearer ${LLM_TOKEN}" \
"<워치독이 쓰는 엔드포인트>"
head -c 500 /tmp/wd.out
401 이나 403 이면 인증, 404 면 경로, 000 이면 네트워크 문제다. 200 인데 워치독이 실패로 세면 판정 로직 문제다. 게이트웨이 경유 호출에 하드코딩된 토큰이 만료되면 모델이 멀쩡해도 계속 실패로 잡힌다.
사용자의 실제 경로인 게이트웨이를 먼저 호출하고, 실패했을 때만 파드를 직접 확인해 책임을 가른다.
| 게이트웨이 | 파드 | 결론 | 조치 |
|---|---|---|---|
| 200 | — | 정상 | 없음 |
| 실패 | 200 | 게이트웨이·네트워크 문제 | 로그만 남기고 파드 유지 |
| 실패 | 실패 | 모델 문제 | 카운트하고 임계 도달 시 재기동 |
평상시에는 게이트웨이 호출 한 번으로 끝나므로 부하가 늘지 않고, 파드 직접 확인은 실패했을 때만 수행된다. 이 로직이었다면 문제의 15시간 동안 재기동은 한 번도 일어나지 않고 게이트웨이 이슈 로그만 쌓였을 것이다.
install -m 600 /dev/null /etc/<name>.env
chmod 700 <watchdog-script>
bash -n <watchdog-script>