← До програми курсу

Модуль 16 / 19

Production-кластер: HA, upgrades, backup і security

KUBERNETES

Зміст
01

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
02

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.

03

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 не підтримується.

04

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, тому сумісність ОС перевіряють до вікна.

05

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.

06

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 має бути відрепетирований, а не придуманий під час інциденту
07

7. Лабораторна робота: preflight inventory

На навчальному кластері зберіть стан без змін. Результат збережіть у журналі роботи з UTC timestamp.

terminal
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 для порівняння після обслуговування.

08

8. Лабораторна робота: cordon і dry-run drain

Збережіть manifest як operations-lab.yaml. Лабораторія cordon-ить worker, виконує лише server-side dry-run drain і повертає Node у schedulable state. Якщо відповідний worker не знайдено, змінна NODE буде порожньою — зупиніться й не підставляйте control-plane.

terminal
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}
terminal
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 видалено.

09

9. Runbook: snapshot etcd 3.6

Команди виконуються на kubeadm control-plane з local stacked etcd і встановленими etcdctl/etcdutl. Шляхи TLS взято зі стандартної kubeadm PKI; для external etcd використовуйте його endpoints та credentials. Не виводьте ключі в logs.

terminal
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

10. Лабораторія: ізольований restore drill

Не відновлюйте production data directory поверх робочого etcd. Скопіюйте перевірений snapshot на ізольований host і відновіть його в новий унікальний каталог. Команди нижче не перемикають kube-apiserver на відновлені дані.

terminal
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

11. Runbook: послідовний kubeadm upgrade

Приклади показують Kubernetes v1.37.0 як конкретну ціль. Перед виконанням оберіть останній доступний patch із kubeadm upgrade plan та встановіть відповідні пакети з репозиторію ОС. Перший control-plane:

terminal
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 по одному. Команди виконують з адміністративної станції та на цільовому вузлі відповідно до вашої операційної моделі.

terminal
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"
terminal
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

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 для роботи офлайн

Завантажте оформлену версію модуля для читання без підключення до мережі.

Завантажити PDFPDF