← К программе курса

Модуль 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.