LabHub
배우기 러닝패스 코스

KCNA — 쿠버네티스·클라우드 네이티브 입문 · 실행·준비·복구 신호를 실제 동작으로 구분하기 · 이론

Running·Ready·업무 성공은 다른 질문이다

LabHub 에서 이어서 보기

한 줄 요약

Running은 Pod 생명주기의 요약이고, Ready는 지금 요청을 맡겨도 되는지에 관한 조건입니다.
재시작 횟수와 실제 HTTP 응답까지 함께 보아야 '프로세스가 살아 있다'와 '서비스가 일을 한다'를 구분할 수 있습니다.

왜 이게 필요했나

택배 창고에 직원이 출근했다고 해서 배송 준비가 끝난 것은 아닙니다. 직원은 살아서 움직이지만
송장 프린터가 연결되지 않았을 수도 있습니다. 출근 여부를 확인하는 질문과 새 주문을 배정할지를
결정하는 질문은 다릅니다. 서버도 프로세스가 떠 있는 동안 설정을 읽거나 연결을 복구할 수 있습니다.

운영자가 화면의 Running만 보고 장애가 없다고 판단하면 사용자의 실패가 설명되지 않습니다.
반대로 응답 한 번이 늦었다고 프로세스를 계속 죽이면, 아직 정상인 인스턴스에 요청이 몰리고
다시 그 인스턴스도 느려집니다. 건강 신호는 초록불을 많이 만드는 기능이 아니라, 관측 결과에
어떤 행동을 연결할지 정하는 약속입니다.

어떻게 동작하나

Pod에는 하나의 '건강 점수'가 없습니다. status.phase, status.conditions, 컨테이너별 상태가
서로 다른 질문에 답합니다. kubectl get pods의 짧은 표는 요약이므로 먼저 어느 열을 보고 있는지
확인해야 합니다. 재시작이 있었는데 현재 Running이라고 해서 과거 실패까지 없어진 것은 아닙니다.

Running 단계는 Pod가 노드에 배정되고 컨테이너들이 생성된 뒤, 적어도 하나가 실행 중이거나
시작·재시작 중인 경우도 포함합니다. 모든 컨테이너의 업무가 정상이라는 뜻은 아닙니다.
또한 표의 STATUS에 보이는 CrashLoopBackOff와 API의 status.phase는 같은 필드가 아닙니다.
요약 문자열 하나를 건강 판정으로 외우기보다 컨테이너별 상태까지 펼쳐 읽으세요.

| 관측 | 답하는 질문 | 이것만으로 알 수 없는 것 |
| --- | --- | --- |
| phase=Running | Pod가 실행 단계에 들어갔는가 | 업무 요청이 성공하는가 |
| Ready 조건 | 현재 트래픽을 받을 준비가 됐는가 | 모든 사용자 시나리오가 성공하는가 |
| restartCount | 이 컨테이너가 몇 번 다시 시작됐는가 | 어느 장애가 재시작 원인이었는가 |
| 실제 HTTP 응답 | 이 경로의 이번 요청이 성공했는가 | 다른 경로·다른 시점도 성공하는가 |

readiness 검사는 kubelet이 수행하고, 그 결과가 Pod 조건과 서비스의 전송 대상에 반영됩니다.
일반적인 Service에서는 준비되지 않은 Pod를 새 요청의 정상 대상으로 사용하지 않습니다.
이때 EndpointSlice에 주소가 문자 그대로 없어졌는지만 보지 마세요. 주소가 남은 채
conditions.ready=false일 수도 있습니다. Pod UID와 주소, 조건을 함께 대조해야 같은 대상을 보는 것입니다.
publishNotReadyAddresses=true인 Service는 별도 동작이므로 이 실습에서는 명시적으로 false로 둡니다.

Pod A와 B가 같은 Service 뒤에 있다고 합시다. A의 readiness만 실패시키면 A는 여전히 Running일 수 있습니다.
A에 직접 보낸 요청은 연결되지만 업무 응답이 실패하고, Service를 통한 새 요청은 B가 처리하는 모습을
비교할 수 있습니다. 여기서 중요한 증거는 'B 응답을 한 번 봤다'만이 아닙니다. A의 Ready=false,
EndpointSlice의 A 조건, A의 기존 컨테이너 ID와 재시작 횟수 유지까지 함께 확인해야 합니다.

반면 liveness는 컨테이너를 계속 살려 둘 것인지에 관한 검사입니다. 설정한 연속 실패 기준을 넘으면
kubelet이 해당 컨테이너를 종료하고 재시작 정책을 따릅니다. 같은 Pod 안에서 컨테이너가 다시 뜨는
경우 Pod UID는 같고 컨테이너 ID는 달라집니다. Deployment가 Pod를 교체한 경우와 다른 사건입니다.
이 구분을 놓치면 'Pod가 그대로니 재시작은 없었다'라는 잘못된 결론을 내리게 됩니다.

현장에서 만나는 모습

첫 번째 상황은 일시적인 의존 서비스 장애입니다. 애플리케이션 자체는 살아 있고 연결을 다시 시도할
수 있다면 요청 배정을 잠시 멈추는 것이 적절할 수 있습니다. 의존 서비스가 복구되면 같은 프로세스가
다시 Ready가 됩니다. 프로세스를 죽이는 것으로 상대 서비스의 장애를 고칠 수는 없습니다.

두 번째 상황은 애플리케이션 내부의 진행 불능입니다. 새 요청을 받아도 처리가 전혀 전진하지 않고
프로세스 재시작으로 복구 가능한 상태라면 liveness가 도움이 될 수 있습니다. 다만 이 실습의 고장
표식은 실제 교착 상태가 아니라 복구 동작을 비교하기 위한 합성 장애입니다. 이 결과로 운영 앱의
교착을 탐지했다고 주장하지 않습니다. 실제 앱의 검사 경로가 무엇을 측정할지는 별도 설계해야 합니다.

다음 레슨으로 연결

다음 교재에서는 검사 자체가 잘못 설계됐을 때 생기는 착시를 봅니다. TCP 연결 성공과 HTTP 업무 성공,
느린 초기화와 복구 불가능한 실패를 구분합니다. 뒤 실습에서는 Pod·컨테이너 신원을 기록하고,
readiness 실패와 liveness 실패를 각각 만든 뒤 정상 비교군이 영향을 받지 않았는지 확인합니다.

공식 근거: [Pod 생명주기와 phase](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/) ·
[Pod 건강 검사](https://kubernetes.io/docs/concepts/workloads/pods/probes/) ·
[EndpointSlice 조건](https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/).