ЁЯЩЛ рдзрдбрд╛ 07 тАФ Health probes: "рдЬрд╛рдЧреА рдЖрд╣реЗрд╕ рдХрд╛? рддрдпрд╛рд░ рдЖрд╣реЗрд╕ рдХрд╛?"
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 13 рдкреИрдХреА рдзрдбрд╛ 07 ┬╖ рдорд╛рдЧрдЪрд╛: lesson-06-configmaps-secrets ┬╖ рдкреБрдврдЪрд╛: lesson-08-resources
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ06, рдЖрдгрд┐: liveness рдЖрдгрд┐ readiness probes тАФ Kubernetes рдирд┐рд░реЛрдЧреА pod рдЖрдгрд┐ zombie рдпрд╛рддрд▓рд╛ рдлрд░рдХ рдХрд╕рд╛ рдУрд│рдЦрддреЛ. рдЦрд░реА file:
- k8s/deployment.yaml тАФ
livenessProbe(/healthz) рдЖрдгрд┐readinessProbe(/readyz)
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рд╢рд┐рдХреНрд╖рд┐рдХрд╛ рд╡рд░реНрдЧрд╛рдд рдлрд┐рд░рддрд╛рдд рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ рдореБрд▓рд╛рд▓рд╛ рджреЛрди рд╡реЗрдЧрд╡реЗрдЧрд│реЗ рдкреНрд░рд╢реНрди рд╡рд┐рдЪрд╛рд░рддрд╛рдд:
"рдЬрд╛рдЧрд╛ рдЖрд╣реЗрд╕ рдХрд╛?" ЁЯШ┤ тАФ рдПрдЦрд╛рджреЗ рдореВрд▓ рдмрд╛рдХрд╛рд╡рд░ рдбреЛрдХреЗ рдЯреЗрдХреВрди рдЭреЛрдкрд▓реЗ рдЕрд╕реЗрд▓ рдЖрдгрд┐ рд▓рд╛рдЧреЛрдкрд╛рда рдЕрдиреЗрдХ рд╡реЗрд│рд╛ рдЙрддреНрддрд░ рджреЗрдд рдирд╕реЗрд▓, рддрд░ рд╢рд┐рдХреНрд╖рд┐рдХрд╛ рддреНрдпрд╛рд▓рд╛ рдирд░реНрд╕рдХрдбреЗ рдкрд╛рдард╡рддрд╛рдд рдЖрдгрд┐ рддрд╛рдЬреЗрддрд╡рд╛рдиреЗ рдореВрд▓ рдЖрдгрддрд╛рдд. (рдХрдбрдХ рд╢рд╛рд│рд╛. рдкрдг рдЦреВрдк рдкрд░рд┐рдгрд╛рдордХрд╛рд░рдХ.) тЖТ рд╣рд╛ liveness probe: рдЙрддреНрддрд░ рдирд╛рд╣реА = container restart рдХрд░рд╛.
"рдкреНрд░рд╢реНрдирд╛рдВрдЪреА рдЙрддреНрддрд░реЗ рджреНрдпрд╛рдпрд▓рд╛ рддрдпрд╛рд░ рдЖрд╣реЗрд╕ рдХрд╛?" ЁЯЩЛ тАФ 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"]
тЭУ рдХрд╛рдп
- Liveness probe тАФ "process рд╡рд╛рдЪрд╡рддрд╛ рдпреЗрдгрд╛рд░ рдирд╛рд╣реА рдЗрддрдХреА рдЕрдбрдХрд▓реА рдЖрд╣реЗ рдХрд╛?" рдкреБрдиреНрд╣рд╛ рдкреБрдиреНрд╣рд╛ fail рдЭрд╛рд▓рд╛ тЖТ kubelet container restart рдХрд░рддреЛ. Deadlocks рдЖрдгрд┐ рдЧреЛрдард▓реЗрд▓реНрдпрд╛ apps рд╡рд░рдЪрд╛ рдЙрдкрд╛рдп.
- Readiness probe тАФ "рддреВ рдЖрддреНрддрд╛ requests рдирд╛ рд╕реЗрд╡рд╛ рджреЗрдК рд╢рдХрддреЛрд╕ рдХрд╛?" Fail рдЭрд╛рд▓рд╛ тЖТ рддреЛ рдкреБрдиреНрд╣рд╛ рдкрд╛рд╕ рд╣реЛрдИрдкрд░реНрдпрдВрдд pod рд▓рд╛ Service рдЪреНрдпрд╛ endpoint рдпрд╛рджреАрддреВрди рдХрд╛рдврд▓реЗ рдЬрд╛рддреЗ. "рдЕрдЬреВрди рд╕реБрд░реВ рд╣реЛрдд рдЖрд╣реЗ" рдЖрдгрд┐ "рдорд╛рдЭрд╛ database рдереЛрдбреНрдпрд╛ рд╡реЗрд│рд╛рд╕рд╛рдареА рдкреЛрд╣реЛрдЪрдд рдирд╛рд╣реА" рдпрд╛рд╡рд░рдЪрд╛ рдЙрдкрд╛рдп.
- Probes
httpGet(рдЖрдкрд▓рд╛),tcpSocket, рдХрд┐рдВрд╡рд╛ commandexecрдХрд░рдгрд╛рд░реЗ рдЕрд╕реВ рд╢рдХрддрд╛рдд. Knobs:initialDelaySeconds(рд╕реБрд░реВ рдЭрд╛рд▓реНрдпрд╛рдирдВрддрд░рдЪрд╛ рд╕рд╡рд▓рддреАрдЪрд╛ рд╡реЗрд│),periodSeconds(рдХрд┐рддреА рд╡реЗрд│рд╛рдиреЗ),failureThreshold(рдХреГрддреА рдХрд░рдгреНрдпрд╛рдЖрдзреА рдХрд┐рддреА рд╡реЗрд│рд╛ рдЪреБрдХреВ рджреНрдпрд╛рдпрдЪреЗ). - рдЦреВрдк рд╣рд│реВ рд╕реБрд░реВ рд╣реЛрдгрд╛рд▒реНрдпрд╛рдВрд╕рд╛рдареА startup probe рдкрдг рдЕрд╕рддреЛ тАФ рдЗрдереЗ рддреНрдпрд╛рдЪреА рдЧрд░рдЬ рдирд╛рд╣реА.
ЁЯдФ рдХрд╛
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 рд╡рд░ рдЪрд╛рд▓реВ рд░рд╛рд╣рд┐рд▓реЗрд▓реНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рдЧреЛрд╖реНрдЯреАрдЪреЗ рддрд╛рд╕рд╛рдкреНрд░рдорд╛рдгреЗ рдмрд┐рд▓ рд▓рд╛рдЧрддреЗ
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- рдПрдХрд╛рдЪ probe рдХрдбреВрди рджреЛрдиреНрд╣реА рдХрд╛рдореЗ рдХрд░рд╡реВрди рдШреЗрдгреЗ тАФ readiness traffic рдЕрдбрд╡рддреЛ, liveness restart рдХрд░рддреЛ
initialDelaySeconds/startup probe рд╢рд┐рд╡рд╛рдп рд╣рд│реВ рд╕реБрд░реВ рд╣реЛрдгрд╛рд▒реНрдпрд╛ app рд╡рд░ liveness probe тЖТ restart рдЪреЗ рдЪрдХреНрд░
тПня╕П рдкреБрдвреЗ
рдирд┐рд░реЛрдЧреА pods, рдЫрд╛рди тАФ рдкрдг рдкреНрд░рддреНрдпреЗрдХ рдЬрдг рдХрд┐рддреА CPU рдЖрдгрд┐ memory рдЦрд╛рдК рд╢рдХрддреЛ? Requests рдЖрдгрд┐ limits тАФ рдЬреЗрд╡рдгрд╛рдЪреЗ рд╡рд╛рдЯреЗ.
git checkout lesson-08-resources