ЁЯПл The SchoolтА║тШ╕я╕П KubernetesтА║ЁЯЩЛ рдзрдбрд╛ 07 тАФ Health probes: "рдЬрд╛рдЧреА рдЖрд╣реЗрд╕ рдХрд╛? рддрдпрд╛рд░ рдЖрд╣реЗрд╕ рдХрд╛?"
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯЩЛ рдзрдбрд╛ 07 тАФ Health probes: "рдЬрд╛рдЧреА рдЖрд╣реЗрд╕ рдХрд╛? рддрдпрд╛рд░ рдЖрд╣реЗрд╕ рдХрд╛?"

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 13 рдкреИрдХреА рдзрдбрд╛ 07 ┬╖ рдорд╛рдЧрдЪрд╛: lesson-06-configmaps-secrets ┬╖ рдкреБрдврдЪрд╛: lesson-08-resources


ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ

рдзрдбреЗ 01тАУ06, рдЖрдгрд┐: liveness рдЖрдгрд┐ readiness probes тАФ Kubernetes рдирд┐рд░реЛрдЧреА pod рдЖрдгрд┐ zombie рдпрд╛рддрд▓рд╛ рдлрд░рдХ рдХрд╕рд╛ рдУрд│рдЦрддреЛ. рдЦрд░реА file:

ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ

рд╢рд┐рдХреНрд╖рд┐рдХрд╛ рд╡рд░реНрдЧрд╛рдд рдлрд┐рд░рддрд╛рдд рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ рдореБрд▓рд╛рд▓рд╛ рджреЛрди рд╡реЗрдЧрд╡реЗрдЧрд│реЗ рдкреНрд░рд╢реНрди рд╡рд┐рдЪрд╛рд░рддрд╛рдд:

  1. "рдЬрд╛рдЧрд╛ рдЖрд╣реЗрд╕ рдХрд╛?" ЁЯШ┤ тАФ рдПрдЦрд╛рджреЗ рдореВрд▓ рдмрд╛рдХрд╛рд╡рд░ рдбреЛрдХреЗ рдЯреЗрдХреВрди рдЭреЛрдкрд▓реЗ рдЕрд╕реЗрд▓ рдЖрдгрд┐ рд▓рд╛рдЧреЛрдкрд╛рда рдЕрдиреЗрдХ рд╡реЗрд│рд╛ рдЙрддреНрддрд░ рджреЗрдд рдирд╕реЗрд▓, рддрд░ рд╢рд┐рдХреНрд╖рд┐рдХрд╛ рддреНрдпрд╛рд▓рд╛ рдирд░реНрд╕рдХрдбреЗ рдкрд╛рдард╡рддрд╛рдд рдЖрдгрд┐ рддрд╛рдЬреЗрддрд╡рд╛рдиреЗ рдореВрд▓ рдЖрдгрддрд╛рдд. (рдХрдбрдХ рд╢рд╛рд│рд╛. рдкрдг рдЦреВрдк рдкрд░рд┐рдгрд╛рдордХрд╛рд░рдХ.) тЖТ рд╣рд╛ liveness probe: рдЙрддреНрддрд░ рдирд╛рд╣реА = container restart рдХрд░рд╛.

  2. "рдкреНрд░рд╢реНрдирд╛рдВрдЪреА рдЙрддреНрддрд░реЗ рджреНрдпрд╛рдпрд▓рд╛ рддрдпрд╛рд░ рдЖрд╣реЗрд╕ рдХрд╛?" ЁЯЩЛ тАФ PE рдЪреНрдпрд╛ рддрд╛рд╕рд╛рд╡рд░реВрди рдиреБрдХрддреЗрдЪ рдкрд░рдд рдЖрд▓реЗрд▓реЗ, рдЕрдЬреВрди рдмреБрдЯрд╛рдЪреНрдпрд╛ рдирд╛рдбреНрдпрд╛ рдмрд╛рдВрдзрдд рдЕрд╕рд▓реЗрд▓реЗ рдореВрд▓ рдЬрд╛рдЧреЗ рдЖрд╣реЗ рдкрдг рддрдпрд╛рд░ рдирд╛рд╣реА. рдореВрд▓ рд╣рд╛рдд рд╡рд░ рдХрд░реЗрдкрд░реНрдпрдВрдд рд╢рд┐рдХреНрд╖рд┐рдХрд╛ рддреНрдпрд╛рд▓рд╛ рдкреНрд░рд╢реНрди рд╡рд┐рдЪрд╛рд░рддрдЪ рдирд╛рд╣реАрдд. тЖТ рд╣рд╛ readiness probe: рддрдпрд╛рд░ рдирд╛рд╣реА = рддреБрд▓рд╛ traffic рдирд╛рд╣реА (рдзрдбрд╛ 04 рдордзрд▓реА Service рддреБрд▓рд╛ рд╡рдЧрд│рддреЗ), рдкрдг restart рдкрдг рдирд╛рд╣реА.

рджреЛрди рдкреНрд░рд╢реНрди, рджреЛрди рдЕрдЧрджреА рд╡реЗрдЧрд│реЗ рдкрд░рд┐рдгрд╛рдо. рдпрд╛ рджреЛрдШрд╛рдВрдЪреА рд╕рд░рдорд┐рд╕рд│ рдХрд░рдгреЗ рд╣реА Kubernetes рдордзрд▓реА рд╕рд░реНрд╡рд╛рдд рдиреЗрд╣рдореАрдЪреА рдЪреВрдХ рдЖрд╣реЗ!

ЁЯЧ║я╕П рдЖрдХреГрддреА

flowchart TB
    K["kubelet - the teacher<br/>asks every few seconds"]
    K -->|"GET /healthz"| L{"alive?"}
    L -->|"yes"| ok1["ЁЯШК leave it alone"]
    L -->|"no, several times"| restart["ЁЯФД RESTART container<br/>same pod, fresh process"]
    K -->|"GET /readyz"| R{"ready?"}
    R -->|"yes"| ok2["тЬЕ Service sends traffic"]
    R -->|"no"| skip["тП╕я╕П taken OUT of the Service list<br/>no traffic, NO restart"]

тЭУ рдХрд╛рдп

ЁЯдФ рдХрд╛

Probes рдирд╕рддреАрд▓ рддрд░ Kubernetes рд▓рд╛ рдлрдХреНрдд exit рд╣реЛрдгрд╛рд░рд╛ container рд▓рдХреНрд╖рд╛рдд рдпреЗрддреЛ. рдЬрд┐рд╡рдВрдд-рдкрдг-рдЧреЛрдард▓реЗрд▓реНрдпрд╛ process рд▓рд╛ рдХрд╛рдпрдо traffic рдорд┐рд│рдд рд░рд╛рд╣реАрд▓. Zero-downtime rollouts (рдзрдбрд╛ 11) рдкрдг probes рдореБрд│реЗрдЪ рдЪрд╛рд▓рддрд╛рдд: рдирд╡реНрдпрд╛ pod рд▓рд╛ traffic рдлрдХреНрдд /readyz рдиреЗ рд╣реЛ рдореНрд╣рдЯрд▓реНрдпрд╛рд╡рд░рдЪ рдорд┐рд│рддреЗ тАФ рдореНрд╣рдгреВрди рд╕реБрд░реВрдЪ рди рд╣реЛрдК рд╢рдХрдгрд╛рд▒реНрдпрд╛ рдЦрд░рд╛рдм build рд▓рд╛ рдПрдХрд╣реА request рдорд┐рд│рдд рдирд╛рд╣реА. Self-healing (рдзрдбрд╛ 03) + probes = cluster рд╕реНрд╡рддрдГрд▓рд╛ рд╕реНрд╡рддрдГ рдЪрд╛рд▓рд╡рддреЛ.

ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)

k8s/deployment.yaml рдордзреНрдпреЗ:

livenessProbe:
  httpGet: { path: /healthz, port: 3000 }
  initialDelaySeconds: 5     # let it boot before judging
  periodSeconds: 10          # ask every 10s
readinessProbe:
  httpGet: { path: /readyz, port: 3000 }
  initialDelaySeconds: 5
  periodSeconds: 5           # ask more often тАФ traffic depends on it

App рджреЛрдиреНрд╣реА endpoints apps/school-api/src/server.js рдордзреНрдпреЗ рд▓рд╛рдЧреВ рдХрд░рддреЗ: /healthz = "process рдкреНрд░рддрд┐рд╕рд╛рдж рджреЗрддреЗ рддрд░реА рдЖрд╣реЗ"; /readyz = "рдЖрдгрд┐ рдорд╛рдЭреЗ DB connection рдЪрд╛рд▓рддреЗ". Ingress (рдзрдбрд╛ 10) AWS load balancer рдЪреНрдпрд╛ checks рд╕рд╛рдареА /healthz рдЪ рдкреБрдиреНрд╣рд╛ рд╡рд╛рдкрд░рддреЛ.

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛

kubectl -n school describe pod -l app=school-api | grep -A3 -i liveness

# Watch readiness gate traffic:
kubectl -n school get pods -w    # READY column: 0/1 until /readyz passes, then 1/1

# See restarts caused by liveness (RESTARTS column):
kubectl -n school get pods
# Try it: kubectl exec into a pod and kill the node process тАФ
# the container restarts in place, pod name stays the same:
kubectl -n school exec deploy/school-api -- sh -c 'kill 1'
kubectl -n school get pods       # RESTARTS just went up by 1 ЁЯОЙ

ЁЯФз рдпрд╛ рдзрдбреНрдпрд╛рд╕рд╛рдареА kubectl

kubectl describe pod (Events) ┬╖ kubectl get pods -w

ЁЯФЧ рдпрд╛рд╡рд░ рдЖрдзрд╛рд░рд┐рдд: ЁЯкк AWS L15 (ALB health check = readiness)

тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ

/readyz рдмрд┐рдШрдбрд╡рд╛ тЖТ pod Running рд░рд╛рд╣рддреЛ рдкрдг Service рдЪреНрдпрд╛ endpoints рдордзреВрди рдмрд╛рд╣реЗрд░ рдЬрд╛рддреЛ; /healthz рдмрд┐рдШрдбрд╡рд╛ тЖТ RESTARTS рд╡рд╛рдврддреЛ.

ЁЯз╣ рд╕рд╛рдлрд╕рдлрд╛рдИ

local cluster: kubectl delete -f k8s/ (рдХрд┐рдВрд╡рд╛ рддреБрдореНрд╣реА apply рдХреЗрд▓реЗрд▓реА file) тАФ EKS рд╡рд░ рдЪрд╛рд▓реВ рд░рд╛рд╣рд┐рд▓реЗрд▓реНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рдЧреЛрд╖реНрдЯреАрдЪреЗ рддрд╛рд╕рд╛рдкреНрд░рдорд╛рдгреЗ рдмрд┐рд▓ рд▓рд╛рдЧрддреЗ

тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛

тПня╕П рдкреБрдвреЗ

рдирд┐рд░реЛрдЧреА pods, рдЫрд╛рди тАФ рдкрдг рдкреНрд░рддреНрдпреЗрдХ рдЬрдг рдХрд┐рддреА CPU рдЖрдгрд┐ memory рдЦрд╛рдК рд╢рдХрддреЛ? Requests рдЖрдгрд┐ limits тАФ рдЬреЗрд╡рдгрд╛рдЪреЗ рд╡рд╛рдЯреЗ.

git checkout lesson-08-resources

ЁЯЩЛ Lesson 07 тАФ Health probes: "Are you awake? Are you ready?"

ЁЯУН You are here: Lesson 07 of 13 ┬╖ Previous: lesson-06-configmaps-secrets ┬╖ Next: lesson-08-resources


ЁЯУж What's in this branch

Lessons 01тАУ06, plus: liveness and readiness probes тАФ how Kubernetes tells a healthy pod from a zombie. Real file:

ЁЯзТ Explain like I'm 5

The teacher walks around the class and asks each kid two different questions:

  1. "Are you awake?" ЁЯШ┤ тАФ If a kid fell asleep face-down on the desk and doesn't answer several times in a row, the teacher sends them to the nurse and brings in a fresh kid. (Harsh school. Very effective.) тЖТ That's the liveness probe: no answer = restart the container.

  2. "Are you ready to answer questions?" ЁЯЩЛ тАФ A kid who just came back from PE, still tying shoelaces, is awake but not ready. The teacher simply doesn't call on them until they raise their hand. тЖТ That's the readiness probe: not ready = no traffic for you (the Service from lesson 04 skips you), but no restart either.

Two questions, two very different consequences. Mixing them up is one of the most common Kubernetes mistakes!

ЁЯЧ║я╕П Diagram

flowchart TB
    K["kubelet - the teacher<br/>asks every few seconds"]
    K -->|"GET /healthz"| L{"alive?"}
    L -->|"yes"| ok1["ЁЯШК leave it alone"]
    L -->|"no, several times"| restart["ЁЯФД RESTART container<br/>same pod, fresh process"]
    K -->|"GET /readyz"| R{"ready?"}
    R -->|"yes"| ok2["тЬЕ Service sends traffic"]
    R -->|"no"| skip["тП╕я╕П taken OUT of the Service list<br/>no traffic, NO restart"]

тЭУ What

ЁЯдФ Why

Without probes, Kubernetes only notices a container that exits. A process that's alive-but-frozen would keep receiving traffic forever. Probes are also what makes zero-downtime rollouts (lesson 11) work: a new pod gets traffic only after /readyz says yes тАФ so a bad build that can't start never receives a single request. Self-healing (lesson 03) + probes = the cluster runs itself.

ЁЯФз How (in this repo)

In k8s/deployment.yaml:

livenessProbe:
  httpGet: { path: /healthz, port: 3000 }
  initialDelaySeconds: 5     # let it boot before judging
  periodSeconds: 10          # ask every 10s
readinessProbe:
  httpGet: { path: /readyz, port: 3000 }
  initialDelaySeconds: 5
  periodSeconds: 5           # ask more often тАФ traffic depends on it

The app implements both endpoints in apps/school-api/src/server.js: /healthz = "process responds at all"; /readyz = "and my DB connection works". The Ingress (lesson 10) reuses /healthz for the AWS load balancer's checks.

ЁЯзк Try it

kubectl -n school describe pod -l app=school-api | grep -A3 -i liveness

# Watch readiness gate traffic:
kubectl -n school get pods -w    # READY column: 0/1 until /readyz passes, then 1/1

# See restarts caused by liveness (RESTARTS column):
kubectl -n school get pods
# Try it: kubectl exec into a pod and kill the node process тАФ
# the container restarts in place, pod name stays the same:
kubectl -n school exec deploy/school-api -- sh -c 'kill 1'
kubectl -n school get pods       # RESTARTS just went up by 1 ЁЯОЙ

ЁЯФз kubectl for this lesson

kubectl describe pod (Events) ┬╖ kubectl get pods -w

ЁЯФЧ Builds on: ЁЯкк AWS L15 (ALB health check = readiness)

тЬЕ Verify тАФ what you should see

break /readyz тЖТ the pod stays Running but leaves the Service's endpoints; break /healthz тЖТ RESTARTS increments.

ЁЯз╣ Clean up

local cluster: kubectl delete -f k8s/ (or the file you applied) тАФ on EKS, anything left running bills by the hour

тЪая╕П Common mistakes

тПня╕П Next

Healthy pods, great тАФ but how much CPU and memory may each one eat? Requests & limits тАФ lunch portions.

git checkout lesson-08-resources
тЖР Previousconfigmaps secretsNext тЖТresources

This page is the lesson's README from the lesson-07-health-probes branch, shown here so the whole School stays on one site. Code files open on GitHub at the same branch.