Kubernetes umí spustit cokoliv. To je jeho síla i jeho problém. Bez jasného produkčního checklistu se z orchestrátoru kontejnerů stane generátor incidentů. Tenhle článek je 15 bodů, které kontrolujeme na každém clusteru, než ho označíme za production-ready. Žádná teorie — konkrétní konfigurace, YAML snippety a vysvětlení, proč na každém bodu záleží.
Většina K8s incidentů, které řešíme, nesouvisí s chybou v Kubernetes samotném. Problém je téměř vždy v konfiguraci — v tom, co tým vynechal, protože to „nebylo nutné pro dev prostředí." Tři důvody dominují naší incident statistice.
Jeden pod bez limitů dokáže sežrat veškerou paměť nodu a shodit ostatní workloady. V dev prostředí to nevadí — v produkci to znamení 3 AM PagerDuty alert. Bez resource requestů scheduler neumí rozumně rozmístit pody a cluster se stane nepředvídatelným. Toto je příčina číslo jedna OOM kills, které vidíme u klientů.
Kubernetes bez liveness a readiness probů neví, jestli vaše aplikace běží nebo jen zabírá místo. Pod může viset v deadlocku, nevracet žádné requesty, ale Kubernetes ho považuje za zdravý, protože proces stále existuje. Výsledek: uživatelé dostávají 502 a vy nevíte proč — vždyť všechny pody jsou „Running."
Ve výchozím stavu může v Kubernetes každý pod komunikovat s každým jiným podem. To je pohodlné pro vývoj a katastrofální pro bezpečnost. Kompromitovaný pod v jednom namespace má volný přístup k databázi v jiném namespace. Bez network policies je celý cluster jedna velká flat síť s nulovou segmentací.
Tyto tři problémy mají společného jmenovatele: vznikají, protože konfigurace, která funguje ve vývoji, se zkopíruje do produkce bez úprav. Náš checklist existuje proto, aby tento gap systematicky odstranil.
Jeden control plane node znamená single point of failure pro celý cluster. V produkci provozujeme minimálně 3 master nody rozprostřené přes availability zóny. Etcd quorum vyžaduje lichý počet členů — 3 nody tolerují výpadek jednoho, 5 nodů toleruje výpadek dvou. Na managed službách (EKS, AKS, GKE) to řeší provider, ale u self-managed clusterů je to první věc, kterou kontrolujeme.
Cluster autoscaler musí mít nastavené minimum i maximum nodů. Bez horního limitu může runaway deployment vytočit desítky nodů a astronomický cloud bill. Bez dolního limitu může autoscaler zmenšit cluster natolik, že zbývající nody nezvládnou ani baseline traffic. Definujeme oboje a přidáváme billing alerty.
Etcd je mozek clusteru — obsahuje veškerý stav. Pravidelné snapshoty etcd databáze jsou nepominutelné. Automatizujeme backup každých 30 minut do externího storage (S3, GCS) a každý kvartál testujeme restore proceduru. Backup, který nikdo netestoval, není backup — je to přání.
Kubernetes vydává minor verzi každé 4 měsíce a podporuje poslední 3 verze. Kdo přeskočí dvě verze, čeká ho bolestivý upgrade s breaking changes. Udržujeme clustery maximálně jednu verzi za aktuální stable, upgradujeme rolling strategií node po nodu a vždy nejdřív staging, pak produkci.
Každý kontejner musí deklarovat, kolik CPU a paměti potřebuje (request) a kolik smí maximálně spotřebovat (limit). Request určuje scheduling — Kubernetes umístí pod na node, který má dostatek volných prostředků. Limit chrání ostatní workloady — překročení paměťového limitu vede k OOM kill, ne k sestřelení sousedů.
# Resource requests & limits — realistické hodnoty
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "1000m"
memory: "512Mi"
Tři typy probů, tři různé účely. Liveness detekuje deadlocky — pokud selže, Kubernetes kontejner restartuje. Readiness řídí traffic — pokud selže, pod je odebrán z Service endpointů. Startup chrání pomalé aplikace při startu. Bez nich Kubernetes nevidí rozdíl mezi zdravým a mrtvým podem.
# Probes — HTTP check s rozumnými timeouty
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
periodSeconds: 5
failureThreshold: 2
startupProbe:
httpGet:
path: /healthz
port: 8080
failureThreshold: 30
periodSeconds: 5
PDB definuje, kolik podů musí zůstat dostupných během dobrovolných disrupcí (node drain,
cluster upgrade, autoscaling). Bez PDB může upgrade srazit všechny repliky najednou.
Pro kritické služby nastavujeme minAvailable: 50% nebo maxUnavailable: 1 —
zajistí, že minimálně polovina podů obsluhuje traffic i během údržby.
Všechny repliky na jednom nodu = jeden hardware failure shodí celou službu. Pod anti-affinity pravidla rozloží repliky přes nody, topology spread constraints je rozloží přes zóny. Je to pojistka proti korelovaným výpadkům — a stojí přesně nula korun navíc.
Bez metrik létáte poslepu. Prometheus scrapuje metriky z kubelet, kube-state-metrics a vašich aplikací. Grafana je vizualizuje. Minimální dashboard: CPU/memory per node a pod, request rate, error rate, latence (RED metriky). Kube-prometheus-stack toto dá za jeden Helm install — není důvod to nemít.
kubectl logs nefunguje, když pod neexistuje. V produkci potřebujete logy
přežít životnost podu — odesíláme je do centrálního systému (Loki, Elasticsearch, CloudWatch).
Strukturované logy (JSON) s korelačními ID umožňují trasovat request napříč službami.
Bez toho je debugging distribuované aplikace detektivní práce bez důkazů.
V microservices architektuře jeden request prochází desítkami služeb. Když latence vzroste, potřebujete vědět kde. OpenTelemetry je dnes standard — instrumentujete aplikace jednou a posíláte traces do Jaegeru, Tempa nebo Datadog. Propojení traces s logy a metrikami (tři pilíře observability) je to, co dělá rozdíl mezi „asi je to pomalé" a „vím přesně proč."
Alert bez runbooku je šum. Každý alert v Alertmanageru musí mít odkaz na runbook — dokument, který říká, co alert znamená, jak ověřit příčinu a jak problém vyřešit. Alertujeme na symptomy (error rate > 1 %), ne na příčiny (CPU > 80 %). A severity máme tři: critical (probudit lidi), warning (vyřešit do rána), info (podívat se v pracovní době).
Default-deny příchozí traffic a explicitně povolte jen komunikaci, která je potřeba. Databáze by měla přijímat spojení jen od backend podů, ne od čehokoliv v clusteru. Network policies jsou Kubernetes verze firewall pravidel — a měly by být stejně striktní.
# Network Policy — default deny + povolení pro backend
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-allow-backend-only
namespace: production
spec:
podSelector:
matchLabels:
app: postgres
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: backend
ports:
- port: 5432
Každá aplikace běží pod vlastním ServiceAccount s minimálními oprávněními. Žádné cluster-admin
pro CI/CD pipeline, žádné wildcard permissions. Role a ClusterRole definujeme granulárně —
aplikace, která čte ConfigMaps, nepotřebuje právo mazat Secrety. Pravidelně auditujeme
oprávnění pomocí kubectl auth can-i --list a odstraňujeme nepoužívané role.
Kontejnery neběží jako root, nemají privilegovaný mód a nemůžou eskalovat oprávnění. Pod Security Admission (nástupce PodSecurityPolicy) vynucuje tyto standardy na úrovni namespace. K tomu image scanning v CI/CD — Trivy nebo Grype kontrolují CVE v base images před deployem, ne po incidentu. Supply chain security začíná u obrazu.
Checklist říká, co dělat. Stejně důležité je vědět, co nedělat. Tyto anti-patterny vidíme u klientů opakovaně — a vždy stojí čas, peníze nebo oboje.
Tag :latest je proměnlivý — dnešní latest je jiný než zítřejší. Výsledek: dva pody se
stejným deployment manifestem běží jiné verze kódu. Vždy používejte immutable tagy — SHA digest
nebo sémantické verze.
Manuální deploye obcházejí code review, audit trail a rollback mechanismy. Vše do produkce jde přes GitOps (ArgoCD, Flux) — Git je single source of truth, nikdo nedeplojuje z CLI.
Env vars jsou viditelné v kubectl describe pod, v lozích a v crash dumpech.
Secrets patří do Kubernetes Secrets (minimálně), ideálně do externího secrets manageru
(Vault, AWS Secrets Manager) s rotací.
Namespace je bezpečnostní a organizační hranice. Produkce, staging a vývoj v jednom namespace znamená sdílené RBAC, resource quotas a network policies. Oddělte prostředí, oddělte týmy, oddělte riziko.
Kubernetes provozujeme pro klienty v bankovnictví, logistice a retailu — prostředí, kde výpadek stojí reálné peníze a regulátor se ptá na důkazy. Náš přístup ke K8s production readiness má tři fáze.
Audit. Začínáme automatizovaným skenem stávající konfigurace nástrojem, který kontroluje všech 15 bodů tohoto checklistu plus dalších 30+ pravidel specifických pro danou vertikálu. Výstupem je report s prioritizovaným seznamem nálezů — ne obecný PDF, ale konkrétní YAML patche, které můžete rovnou aplikovat.
Implementace. Opravy implementujeme formou merge requestů do GitOps repozitáře klienta. Každá změna prochází code review, je testovaná na staging clusteru a nasazená přes ArgoCD s automatickým rollbackem při selhání health checků. Žádné ruční zásahy, plná auditovatelnost.
Provoz. Po hardening fázi nabízíme kontinuální monitoring — dashboardy, alerting a měsíční compliance report. Cluster drift (odchylka od definovaného stavu) detekujeme automaticky a opravujeme dřív, než se projeví jako incident. Protože nejlevnější incident je ten, který se nestane.
15 bodů v tomto checklistu není jednorázový úkol, který odškrtnete a zapomenete. Je to živý standard, který se vyvíjí s vaší aplikací, týmem a infrastrukturou. Cluster, který byl production-ready před rokem, nemusí být production-ready dnes — přibyla nová služba, změnily se traffic patterny, vyšla nová verze K8s.
Klíč je automatizace. Kontroly v CI/CD pipeline, policy enforcement přes OPA/Kyverno, automatické alerty na drift od baseline. Člověk by neměl manuálně kontrolovat, jestli má deployment resource limity — to je práce pro stroj. Člověk by měl přemýšlet o architektuře, kapacitním plánování a tom, jak systém škálovat na další řád.