Lab 19 – StatefulSets
Lab 19 – StatefulSets
Cíl: stabilní jména, úložiště na každý pod, řízené pořadí – a překvapení při úklidu. Kapitola: StatefulSets
Lab potřebuje tři PV z
labu 18.
Ověřte, že jsou Available:
kubectl get pv
kubectl patch pv pv-storage1 -p '{"spec":{"claimRef":null}}' 2>/dev/null
kubectl get pv
Nejdřív headless Service
# 1 –
cd ~
cat > web-headless.yaml <<'YAML'
apiVersion: v1
kind: Service
metadata:
name: web-headless
spec:
clusterIP: None # headless – žádná virtuální IP
selector:
app: web-sts
ports:
- port: 80
YAML
kubectl apply -f web-headless.yaml
kubectl get svc web-headless # CLUSTER-IP je "None"
Normální Service pody schová za jednu IP. Headless Service dělá opak: DNS vrátí adresy jednotlivých podů, takže je každá replika adresovatelná jménem. StatefulSet ji vyžaduje.
StatefulSet
# 2 –
cat > web-sts.yaml <<'YAML'
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: web-headless
replicas: 3
selector:
matchLabels:
app: web-sts
template:
metadata:
labels:
app: web-sts
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 80
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
resources:
requests: { cpu: "20m", memory: "32Mi" }
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteMany"]
storageClassName: ""
resources:
requests:
storage: 500Mi
YAML
kubectl apply -f web-sts.yaml
kubectl get pods -l app=web-sts -w # Ctrl-C až všechny tři poběží
Sledujte pořadí: web-0 je Ready dřív, než vznikne web-1, a web-1 dřív než
web-2. Deployment by spustil všechny tři naráz; StatefulSet je záměrně
sekvenční, protože replika databáze se nemůže připojit ke clusteru, který ještě
neběží.
# 3 – jména a úložiště
kubectl get pods -l app=web-sts -o wide
kubectl get pvc
kubectl get pv
Všimněte si jmen PVC: data-web-0, data-web-1, data-web-2 – jméno šablony
plus jméno podu. Jeden PVC na repliku, každý navázaný na jeden z vašich NFS PV.
Proto tři repliky potřebovaly tři PV.
# 4 – stabilní identita
kubectl exec web-0 -- sh -c 'echo "I am web-0" > /usr/share/nginx/html/index.html'
kubectl exec web-1 -- sh -c 'echo "I am web-1" > /usr/share/nginx/html/index.html'
kubectl delete pod web-0
kubectl get pods -l app=web-sts # web-0 se vrátí se STEJNÝM jménem
kubectl exec web-0 -- cat /usr/share/nginx/html/index.html # a stejnými daty
Deployment by vytvořil web-7d9f...-xk2p s prázdným volume. StatefulSet znovu
vytvořil web-0 a připojil mu data-web-0.
# 5 – DNS jméno každého podu
kubectl run tmp --image busybox --restart=Never -it --rm -- \
sh -c 'nslookup web-0.web-headless.default.svc.cluster.local; wget -qO- web-1.web-headless'
<pod>.<service>.<namespace>.svc.cluster.local míří na jednu konkrétní repliku.
Takhle se členové databáze hledají navzájem.
# 6 – zmenšení probíhá v opačném pořadí
kubectl scale sts web --replicas=1
kubectl get pods -l app=web-sts # nejdřív web-2, pak web-1
kubectl get pvc # PVC tu pořád jsou
Zmenšení úložiště nemaže. Naškálujte zpátky a web-1 najde svá stará data.
# 7 –
kubectl scale sts web --replicas=2
kubectl exec web-1 -- cat /usr/share/nginx/html/index.html # "I am web-1"
Úklid – to překvapení
# 8 –
kubectl delete -f web-sts.yaml
kubectl get pvc # pořád tady!
kubectl delete pvc data-web-0 data-web-1 data-web-2
kubectl delete -f web-headless.yaml
for p in pv-storage1 pv-storage2 pv-storage3; do
kubectl patch pv $p -p '{"spec":{"claimRef":null}}'
done
kubectl get pv
Smazání StatefulSetu smaže pody a PVC nechá být. Je to záměr – data jsou smyslem toho objektu – a znamená to, že úklid je vždy ruční druhý krok.