Модуль 16 / 19
Production-кластер: HA, upgrades, backup і security
Зміст
1. Цілі модуля
Ви навчитеся планувати production-обслуговування Kubernetes, перевіряти version skew, послідовно оновлювати kubeadm-кластер і створювати перевірювані резервні копії etcd.
- maintenance window та rollback criteria
- version skew і API compatibility
- cordon, drain, PDB і capacity
- kubeadm upgrade order
- etcd snapshot і restore drill
2. Теорія: безпечна зміна production
Upgrade починається не з команди, а з change plan: scope, owner, вікно, залежності, baseline SLI, критерії зупинки, комунікація та rollback. До роботи підтвердьте support matrix cloud provider, CNI, CSI, ingress/Gateway controller, operators, admission webhooks і observability stack.
Спочатку оновлюйтеся до останнього patch поточного minor, потім лише на наступний minor. Пропуск minor versions для kube-apiserver не підтримується. Release notes і API deprecation guide перевіряють до staging rehearsal.
3. Теорія: version skew Kubernetes 1.37
У HA-кластері найновіший і найстаріший kube-apiserver можуть відрізнятися максимум на один minor. kubelet і kube-proxy не мають бути новішими за kube-apiserver і можуть відставати максимум на три minor; фактичний діапазон звужується, поки API servers мають різні версії.
kubectl підтримується в межах одного minor від kube-apiserver. controller-manager і scheduler мають збігатися з API Server або відставати максимум на один minor. Для minor upgrade kubelet Node попередньо drain; in-place minor upgrade без drain не підтримується.
4. Теорія: порядок kubeadm upgrade
Порядок: перший control-plane → решта control-plane по одному → workers по одному. На першому вузлі kubeadm upgrade apply оновлює cluster configuration; на додаткових control-plane і workers використовується kubeadm upgrade node. Addons завершують upgrade після останнього control-plane.
Пакети kubeadm, kubelet і kubectl оновлюють за офіційною інструкцією конкретної ОС і репозиторію pkgs.k8s.io. У Kubernetes 1.37 kubelet типово відхиляє cgroups v1, тому сумісність ОС перевіряють до вікна.
5. Теорія: backup і відновлення etcd
etcd snapshot містить Kubernetes API state, але не дані application volumes. Snapshot виконують через один endpoint, шифрують і копіюють поза кластером; окремо зберігають PKI, static Pod manifests, kubeadm configuration та encryption-at-rest keys.
etcdctl створює online snapshot. В etcd 3.6 статус і restore виконує etcdutl: команду etcdctl snapshot status видалено. Backup є придатним лише після перевірки checksum/status і регулярного restore drill в ізольованому середовищі з виміряними RPO та RTO.
6. Методичні вказівки
- Не оновлюйте всі control-plane nodes одночасно
- Перед drain перевірте PDB, spare capacity, local storage та unmanaged Pods
- Не використовуйте --disable-eviction або --force без окремого рішення
- Знімайте baseline SLI та зберігайте audit trail команд
- Перевіряйте certificates, webhooks, deprecated APIs і CRDs
- Після кожного вузла перевіряйте API, system Pods, DNS, CNI та користувацький smoke test
- Snapshot і encryption keys зберігайте окремо з обмеженим доступом
- Rollback має бути відрепетирований, а не придуманий під час інциденту
7. Лабораторна робота: preflight inventory
На навчальному кластері зберіть стан без змін. Результат збережіть у журналі роботи з UTC timestamp.
kubectl version
kubectl get node -o custom-columns='NAME:.metadata.name,VERSION:.status.nodeInfo.kubeletVersion,RUNTIME:.status.nodeInfo.containerRuntimeVersion,OS:.status.nodeInfo.osImage'
kubectl get --raw='/readyz?verbose'
kubectl get --raw='/livez?verbose'
kubectl get apiservice
kubectl get validatingwebhookconfiguration,mutatingwebhookconfiguration
kubectl get poddisruptionbudget -A
kubectl get crd
kubectl api-resources
kubectl get event -A --sort-by=.metadata.creationTimestampЗафіксуйте версії, runtime, неготові APIService, webhooks, PDB, CRDs та останні Events. Це baseline для порівняння після обслуговування.
8. Лабораторна робота: cordon і dry-run drain
Збережіть manifest як operations-lab.yaml. Лабораторія cordon-ить worker, виконує лише server-side dry-run drain і повертає Node у schedulable state. Якщо відповідний worker не знайдено, змінна NODE буде порожньою — зупиніться й не підставляйте control-plane.
apiVersion: v1
kind: Namespace
metadata: {name: lab-operations}
---
apiVersion: apps/v1
kind: Deployment
metadata: {name: web, namespace: lab-operations}
spec:
replicas: 3
selector:
matchLabels: {app: web}
template:
metadata:
labels: {app: web}
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels: {app: web}
containers:
- name: web
image: nginx:1.29-alpine
readinessProbe:
httpGet: {path: /, port: 80}
resources:
requests: {cpu: 20m, memory: 32Mi}
limits: {memory: 64Mi}
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata: {name: web, namespace: lab-operations}
spec:
maxUnavailable: 1
selector:
matchLabels: {app: web}kubectl apply -f operations-lab.yaml
kubectl rollout status deployment/web -n lab-operations --timeout=120s
NODE="$(kubectl get node --selector='!node-role.kubernetes.io/control-plane' -o jsonpath='{.items[0].metadata.name}')"
kubectl cordon "$NODE"
kubectl drain "$NODE" --ignore-daemonsets --dry-run=server
kubectl get node "$NODE"
kubectl get poddisruptionbudget web -n lab-operations
kubectl uncordon "$NODE"
kubectl delete namespace lab-operationsКритерій: dry-run перелічує заплановані evictions, PDB залишається Healthy, Node після uncordon має SchedulingDisabled=false, namespace видалено.
9. Runbook: snapshot etcd 3.6
Команди виконуються на kubeadm control-plane з local stacked etcd і встановленими etcdctl/etcdutl. Шляхи TLS взято зі стандартної kubeadm PKI; для external etcd використовуйте його endpoints та credentials. Не виводьте ключі в logs.
SNAPSHOT="/var/backups/etcd/snapshot-$(date -u +%Y%m%dT%H%M%SZ).db"
sudo install -d -m 0700 /var/backups/etcd
sudo etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key endpoint health
sudo etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key snapshot save "$SNAPSHOT"
sudo etcdutl --write-out=table snapshot status "$SNAPSHOT"
sudo sha256sum "$SNAPSHOT"
sudo stat -c '%n %s bytes %a %U:%G' "$SNAPSHOT"Після виконання збережіть checksum в окремому захищеному журналі та перенесіть snapshot до off-cluster storage. Наявність файла на тому самому Node не є backup.
10. Лабораторія: ізольований restore drill
Не відновлюйте production data directory поверх робочого etcd. Скопіюйте перевірений snapshot на ізольований host і відновіть його в новий унікальний каталог. Команди нижче не перемикають kube-apiserver на відновлені дані.
SNAPSHOT=/var/backups/etcd/snapshot.db
RESTORE_BASE="$(mktemp -d /var/tmp/etcd-restore.XXXXXX)"
sudo etcdutl --data-dir "$RESTORE_BASE/data" snapshot restore "$SNAPSHOT"
sudo test -f "$RESTORE_BASE/data/member/snap/db"
sudo du -sh "$RESTORE_BASE/data"
sudo find "$RESTORE_BASE/data" -maxdepth 2 -type f -printf '%p %s bytes\n'Після перевірки каталог видаляють лише за затвердженою процедурою. Повний disaster-recovery drill додатково перевіряє member names, peer URLs, cluster token, static Pod manifest і запуск API Server.
11. Runbook: послідовний kubeadm upgrade
Приклади показують Kubernetes v1.37.0 як конкретну ціль. Перед виконанням оберіть останній доступний patch із kubeadm upgrade plan та встановіть відповідні пакети з репозиторію ОС. Перший control-plane:
sudo kubeadm upgrade plan
sudo kubeadm version
sudo kubeadm upgrade apply v1.37.0
kubectl get node
kubectl get pod -n kube-system -o wide
kubectl get --raw='/readyz?verbose'Додатковий control-plane, потім кожен worker по одному. Команди виконують з адміністративної станції та на цільовому вузлі відповідно до вашої операційної моделі.
NODE=control-plane-2
kubectl drain "$NODE" --ignore-daemonsets
sudo kubeadm upgrade node
sudo systemctl daemon-reload
sudo systemctl restart kubelet
sudo systemctl --no-pager --full status kubelet
kubectl uncordon "$NODE"
kubectl get node "$NODE"NODE=worker-1
kubectl drain "$NODE" --ignore-daemonsets
sudo kubeadm upgrade node
sudo systemctl daemon-reload
sudo systemctl restart kubelet
sudo systemctl --no-pager --full status kubelet
kubectl uncordon "$NODE"
kubectl get node "$NODE"Після кожного кроку перевіряйте доступність API, Nodes, CoreDNS, CNI/CSI, workloads, alerts і користувацький smoke test. За порушення stop criteria не переходьте до наступного вузла.
12. Контроль і шпаргалка
- Чому не можна пропускати minor versions?
- Як HA API Server із mixed versions звужує version skew?
- Що захищає PDB і чого він не гарантує?
- Чому etcd snapshot не зберігає дані PVC?
- Чому etcdutl потрібний для etcd 3.6?
- Чим restore drill відрізняється від перевірки checksum?
- Які компоненти перевіряють після кожного Node?
Модуль засвоєно, якщо ви складаєте виконуваний change plan, безпечно моделюєте drain, перевіряєте etcd snapshot через etcdutl і пояснюєте послідовність kubeadm upgrade зі stop/rollback criteria.
PDF для роботи офлайн
Завантажте оформлену версію модуля для читання без підключення до мережі.