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

Модуль 5 / 19

ReplicaSet і Deployment: rollout, rollback та доступність

KUBERNETES

Зміст
01

1. Цілі та результат модуля

Після модуля ви зможете пояснити ланцюжок Deployment → ReplicaSet → Pod, розрахувати межі RollingUpdate, відрізнити scale від нової revision, зупинити й продовжити rollout та відновити доступність після невдалого релізу.

  • ReplicaSet підтримує кількість відповідних Pods
  • Deployment керує ReplicaSets і декларативними rollout
  • Нова revision виникає за зміни Pod template
  • readiness визначає участь Pod в available capacity
  • rollback повертає збережений Pod template, але не всі зовнішні залежності
02

2. Теорія: ReplicaSet і reconciliation

ReplicaSet порівнює spec.replicas із кількістю Pods, що відповідають selector, і створює або видаляє Pods. Він пов’язує створені Pods через ownerReferences. Зазвичай ReplicaSet не створюють вручну: Deployment додає керування revisions і стратегією оновлення.

Selector ReplicaSet не означає ексклюзивне володіння будь-яким відповідним Pod. Adoption можливий лише за дотримання умов ownership; selectors різних controllers, що перетинаються, створюють небезпечну поведінку.

03

3. Теорія: Deployment, template і revisions

Deployment зберігає selector і Pod template. Зміна spec.template створює новий ReplicaSet та збільшує deployment.kubernetes.io/revision. Scale змінює capacity наявної revision і сам по собі нову revision не створює.

pod-template-hash обчислюється controller і додається до ReplicaSet/Pods, щоб різні templates не перетиналися. Не задавайте й не змінюйте цей label вручну.

revisionHistoryLimit обмежує кількість старих ReplicaSets для rollback. Нульова історія економить об’єкти, але позбавляє вбудованого відкату. Історія не замінює Git і release metadata.

04

4. Теорія: RollingUpdate і доступність

RollingUpdate поступово масштабує новий ReplicaSet вгору, старий униз. maxSurge обмежує кількість Pods понад desired replicas, maxUnavailable — допустиму кількість недоступних відносно desired. Значення бувають цілими або відсотками; відсотки округлюються за правилами controller.

За replicas=3, maxSurge=1 і maxUnavailable=1 під час rollout допускається до 4 створених Pods і потрібно щонайменше 2 available. На одному Node це не HA: стратегія зберігає логічну capacity лише доки працює сам Node.

minReadySeconds вимагає, щоб Ready Pod залишався готовим заданий час до Available. progressDeadlineSeconds позначає відсутність прогресу умовою Progressing=False/ProgressDeadlineExceeded, але автоматично rollback не виконує.

05

5. Теорія: status, Conditions і спостереження rollout

replicas — загальна кількість Pods, updatedReplicas — Pods поточного template, readyReplicas — Ready зараз, availableReplicas — Ready не менше minReadySeconds, unavailableReplicas — відсутня available capacity. observedGeneration показує, чи обробив controller актуальний spec.

kubectl rollout status спостерігає controller status, а не виконує оновлення. Успішний rollout підтверджує стан workload, але не замінює HTTP smoke test, метрики та перевірку користувацького шляху.

06

6. Теорія: pause, resume і rollback

Pause дає змогу накопичити кілька змін Pod template без запуску проміжних revisions. Поки Deployment paused, controller не завершує rollout; після resume формується узгоджена revision.

Rollback відновлює template обраної збереженої revision. ConfigMap, Secret, schema бази, зовнішній API та mutable image tag могли вже змінитися, тому технічна можливість undo не гарантує сумісність даних і поведінки.

07

7. Методичні вказівки

  • Зберігайте Deployment manifest у Git і фіксуйте immutable image digest для production
  • Перед apply використовуйте server dry-run і diff
  • Розраховуйте surge з урахуванням requests та вільної capacity
  • Спостерігайте Deployment, обидва ReplicaSets, Pods і Events
  • Не змінюйте ReplicaSet, яким володіє Deployment
  • Не вважайте ProgressDeadlineExceeded автоматичним rollback
  • Після rollout виконуйте smoke test і дивіться SLI
  • Для rollback заздалегідь перевіряйте сумісність конфігурації та даних
08

8. Лабораторна робота: перший Deployment

Створіть Deployment із трьох replicas та явною стратегією. Readiness probe тут потрібна для правильного поняття Available; докладно probes розглядаються в модулі 11.

terminal
mkdir -p /tmp/k8s-m05
cat > /tmp/k8s-m05/deployment.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: k8s-m05
  labels:
    app.kubernetes.io/name: storefront
    app.kubernetes.io/component: web
  annotations:
    kubernetes.io/change-cause: "initial nginx 1.29"
spec:
  replicas: 3
  revisionHistoryLimit: 5
  progressDeadlineSeconds: 120
  minReadySeconds: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: storefront
      app.kubernetes.io/component: web
  template:
    metadata:
      labels:
        app.kubernetes.io/name: storefront
        app.kubernetes.io/component: web
    spec:
      containers:
        - name: nginx
          image: nginx:1.29-alpine
          ports:
            - name: http
              containerPort: 80
          readinessProbe:
            httpGet:
              path: /
              port: http
            periodSeconds: 2
            failureThreshold: 3
EOF

kubectl wait --for=condition=Ready node --all --timeout=120s
kubectl create namespace k8s-m05
kubectl apply --dry-run=server -f /tmp/k8s-m05/deployment.yaml
kubectl apply --server-side --field-manager=course-lab -f /tmp/k8s-m05/deployment.yaml
kubectl -n k8s-m05 rollout status deployment/web --timeout=120s
terminal
kubectl -n k8s-m05 get deployment,replicaset,pod -o wide
kubectl -n k8s-m05 get pods --show-labels
kubectl -n k8s-m05 describe deployment web
kubectl -n k8s-m05 rollout history deployment/web
kubectl -n k8s-m05 get deployment web -o jsonpath='generation={.metadata.generation}{"\n"}observedGeneration={.status.observedGeneration}{"\n"}replicas={.status.replicas}{"\n"}updated={.status.updatedReplicas}{"\n"}ready={.status.readyReplicas}{"\n"}available={.status.availableReplicas}{"\n"}'
09

9. Лабораторна робота: revision і RollingUpdate

Змініть image у manifest, спочатку дослідіть diff, потім спостерігайте створення нового ReplicaSet. Старий ReplicaSet залишається з нулем replicas для можливого rollback.

terminal
sed -i 's/nginx:1.29-alpine/nginx:1.28-alpine/' /tmp/k8s-m05/deployment.yaml
sed -i 's/initial nginx 1.29/update to nginx 1.28/' /tmp/k8s-m05/deployment.yaml
kubectl diff -f /tmp/k8s-m05/deployment.yaml || [ "$?" -eq 1 ]
kubectl apply --server-side --field-manager=course-lab -f /tmp/k8s-m05/deployment.yaml
kubectl -n k8s-m05 rollout status deployment/web --timeout=120s
kubectl -n k8s-m05 get replicasets
kubectl -n k8s-m05 rollout history deployment/web
10

10. Лабораторна робота: scale, pause і resume

Scale до п’яти Pods не змінює template і revision. Потім pause об’єднує зміну image та env в один rollout після resume.

terminal
revision_before=$(kubectl -n k8s-m05 get deployment web -o jsonpath='{.metadata.annotations.deployment\.kubernetes\.io/revision}')
kubectl -n k8s-m05 scale deployment/web --replicas=5
kubectl -n k8s-m05 rollout status deployment/web --timeout=120s
revision_after=$(kubectl -n k8s-m05 get deployment web -o jsonpath='{.metadata.annotations.deployment\.kubernetes\.io/revision}')
printf 'revision before=%s after=%s\n' "$revision_before" "$revision_after"
kubectl -n k8s-m05 get deployment,replicaset,pod
terminal
kubectl -n k8s-m05 rollout pause deployment/web
kubectl -n k8s-m05 set image deployment/web nginx=nginx:1.29-alpine
kubectl -n k8s-m05 set env deployment/web RELEASE_STAGE=verified
kubectl -n k8s-m05 rollout status deployment/web --timeout=5s || true
kubectl -n k8s-m05 get deployment web -o jsonpath='paused={.spec.paused}{"\n"}generation={.metadata.generation}{"\n"}observed={.status.observedGeneration}{"\n"}'
kubectl -n k8s-m05 rollout resume deployment/web
kubectl -n k8s-m05 rollout status deployment/web --timeout=120s
kubectl -n k8s-m05 rollout history deployment/web
11

11. Діагностика: завислий rollout і rollback

Неіснуючий image створює новий ReplicaSet, але нові Pods не стають Ready. За maxUnavailable=1 старі available Pods зберігають сервісну capacity. Після deadline Deployment повідомляє про відсутність прогресу, але лишається зламаним до дії оператора.

terminal
kubectl -n k8s-m05 patch deployment web --type=merge -p '{"spec":{"progressDeadlineSeconds":30}}'
kubectl -n k8s-m05 annotate deployment web kubernetes.io/change-cause='intentional broken image' --overwrite
kubectl -n k8s-m05 set image deployment/web nginx=nginx:does-not-exist
kubectl -n k8s-m05 rollout status deployment/web --timeout=35s || true

kubectl -n k8s-m05 get deployment,replicaset,pod
kubectl -n k8s-m05 describe deployment web
kubectl -n k8s-m05 get pods -l app.kubernetes.io/component=web -o jsonpath='{range .items[*]}{.metadata.name}{" image="}{.spec.containers[0].image}{" ready="}{.status.containerStatuses[0].ready}{" waiting="}{.status.containerStatuses[0].state.waiting.reason}{"\n"}{end}'
kubectl -n k8s-m05 get events --sort-by=.metadata.creationTimestamp
kubectl -n k8s-m05 rollout history deployment/web

kubectl -n k8s-m05 annotate deployment web kubernetes.io/change-cause='rollback after broken image' --overwrite
kubectl -n k8s-m05 rollout undo deployment/web
kubectl -n k8s-m05 rollout status deployment/web --timeout=120s
kubectl -n k8s-m05 get deployment web -o jsonpath='image={.spec.template.spec.containers[0].image}{"\n"}ready={.status.readyReplicas}{"\n"}available={.status.availableReplicas}{"\n"}'

Діагностичний порядок: Conditions і counts Deployment → нові/старі ReplicaSets → Pod states та Events → точний image/config → рішення roll forward або rollback → smoke test.

12

12. Контроль, критерії засвоєння та cleanup

  • Що підтримує ReplicaSet?
  • Яка зміна створює нову revision?
  • Навіщо потрібен pod-template-hash?
  • Скільки Pods дозволено за replicas=3 і maxSurge=1?
  • Чим Ready відрізняється від Available?
  • Чи створює scale нову revision?
  • Що відбувається під час pause?
  • Чи виконує progressDeadline автоматичний rollback?
  • Чому undo не гарантує сумісність даних?
terminal
kubectl delete namespace k8s-m05 --wait=true
rm -rf /tmp/k8s-m05
kubectl get namespace k8s-m05 2>&1 || true

Модуль засвоєно, якщо ви прогнозуєте кількість Pods під час rollout, читаєте status без здогадок, доводите відсутність нової revision за scale та відновлюєте workload після невдалого image update.