Модуль 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 для работы офлайн
Скачайте оформленную версию модуля для чтения без подключения к сети.