Modul 8 — Orchestrace: Kubernetes

40. Škálování, health checks a self-healing

Jak Kubernetes automaticky škáluje počet replik podle zátěže a jak pomocí health checks detekuje a opravuje nezdravé Pody.

Odhadovaná délka studia: 55 minut · Stav: nehotovo

Technologie: Kubernetes

Úvod a kontext

Jednou z klíčových slibů orchestrace je, že se aplikace sama "postará
sama o sebe" — přežije pád jednoho Podu, přizpůsobí se nárůstu zátěže a
nepropustí provoz na instanci, která zamrzla nebo se ještě nestihla
nastartovat. Kubernetes tohle nedělá magicky, ale na základě dvou
konkrétních mechanismů, které musí administrátor správně nakonfigurovat:
health checks (aby cluster vůbec věděl, co je "zdravé") a
škálování (aby uměl reagovat na změnu zátěže). Bez nich Kubernetes
sice Pody spustí, ale neumí spolehlivě poznat, že jeden z nich přestal
fungovat.

Teorie

Liveness a readiness probes

Kubernetes standardně pozná jen to, jestli proces v kontejneru běží —
ne jestli aplikace uvnitř skutečně funguje (např. aplikace může běžet,
ale mít zaseklé spojení s databází a nevracet žádné odpovědi). Proto
existují dva typy probe (sond), které si administrátor definuje
podle konkrétní aplikace:

  • livenessProbe — periodicky ověřuje, jestli je aplikace naživu. Když
    selže opakovaně (podle failureThreshold), kubelet kontejner
    restartuje — předpoklad je, že restart pomůže (např. u zaseklého
    procesu).
  • readinessProbe — ověřuje, jestli je Pod připravený přijímat
    provoz. Když selže, Pod se dočasně odebere z endpointů Service (viz
    předchozí lekce o Services) — provoz na něj přestane chodit, ale Pod
    se nerestartuje. Typicky se používá při startu (aplikace se ještě
    připojuje k databázi) nebo při dočasném přetížení.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: myregistry.example.com/web:1.4.0
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /healthz/ready
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /healthz/live
              port: 8080
            initialDelaySeconds: 15
            periodSeconds: 20
            failureThreshold: 3

Kromě httpGet podporují probes i tcpSocket (jen ověří, že port
přijímá spojení) a exec (spuštění příkazu uvnitř kontejneru, úspěch =
návratový kód 0) — vhodné pro aplikace bez HTTP endpointu.

Self-healing v praxi

"Self-healing" v Kubernetes není jedna funkce, ale součet chování
několika kontrolérů reagujících na probes a na stav uzlů:

  • Pod, jehož livenessProbe opakovaně selže, je restartován na místě.
  • Pod na uzlu, který přestal odpovídat (node not ready), je po
    vypršení tolerance přeplánován na jiný zdravý uzel.
  • ReplicaSet neustále hlídá, že běží přesně požadovaný počet replik —
    pokud jeden Pod zmizí (crash, evikce, smazání uzlu), okamžitě vytvoří
    náhradní.

Tohle vše se děje bez zásahu člověka — administrátor jen musí správně
nastavit probes, jinak Kubernetes "neví", že je něco v nepořádku.

Horizontal Pod Autoscaler (HPA)

HorizontalPodAutoscaler automaticky mění počet replik Deploymentu
podle naměřené metriky (nejčastěji využití CPU, případně paměti nebo
vlastní metriky z Prometheus):

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70

Tato konfigurace udržuje průměrné využití CPU napříč replikami kolem
70 % — při nárůstu zátěže HPA přidá repliky (až do 10), při poklesu je
zase uvolní (minimálně 2 zůstanou vždy běžet kvůli dostupnosti).
Předpokladem fungování je, že má cluster nasazený metrics-server
(nebo Prometheus adapter), který HPA metriky dodává.

Rozdíl oproti vertikálnímu škálování

Horizontální škálování (víc replik) je v Kubernetes výchozí přístup,
protože kombinuje se self-healing a rolling update. Vertical Pod
Autoscaler
(méně používaný, existuje jako samostatný doplněk) místo
toho mění requesty/limity CPU a paměti jednotlivého Podu — má smysl u
aplikací, které se neumí horizontálně škálovat (např. jednoduchá
neškálovatelná stavová služba).

Praktický příklad

kubectl apply -f deployment.yaml
kubectl apply -f hpa.yaml

kubectl get hpa
# NAME      REFERENCE      TARGETS   MINPODS   MAXPODS   REPLICAS
# web-hpa   Deployment/web  15%/70%   2         10        2

# vygenerování zátěže (např. testovacím nástrojem) a sledování reakce
kubectl get hpa web-hpa --watch
# TARGETS postupně stoupne nad 70 %, REPLICAS se automaticky zvýší

# ověření, že nezdravý Pod je automaticky nahrazen
kubectl delete pod web-abc123
kubectl get pods
# nový Pod se objeví během několika sekund se jménem web-xyz789

Shrnutí

Health checks (readinessProbe, livenessProbe) dávají Kubernetes
informaci o skutečném stavu aplikace nad rámec pouhého běhu procesu —
readiness řídí, zda Pod dostává provoz, liveness řídí, zda se má
restartovat. Na tomto základu staví self-healing (automatická náhrada
nezdravých Podů) a HorizontalPodAutoscaler, který podle metrik (typicky
CPU) automaticky mění počet replik mezi nastaveným minimem a maximem.
Bez správně nastavených probes Kubernetes neumí spolehlivě poznat, že
je aplikace v problému.

Kontrolní otázky

  1. Jaký je rozdíl mezi readinessProbe a livenessProbe a co se stane
    při selhání každé z nich?
  2. Proč potřebuje HorizontalPodAutoscaler ke svému fungování
    metrics-server nebo podobný zdroj metrik?
  3. Co se stane, když je uzel, na kterém běží Pod, označen jako
    NotReady?
  4. Mini cvičení: k existujícímu Deploymentu přidejte livenessProbe
    typu httpGet na endpoint, který úmyslně vždy vrací chybu, a
    pozorujte příkazem kubectl get pods --watch, jak Kubernetes
    kontejner opakovaně restartuje.

Lekce na sebe nejsou zamčené — libovolnou lekci můžete otevřít i označit jako hotovou v jakémkoliv pořadí.