Модуль 5 / 19
ReplicaSet и Deployment: rollout, rollback и доступность
Содержание
1. Цели и результат модуля
После модуля вы сможете объяснить цепочку Deployment → ReplicaSet → Pod, рассчитать границы RollingUpdate, отличить scale от новой revision, остановить и продолжить rollout и восстановить доступность после неудачного релиза.
- ReplicaSet поддерживает число подходящих Pods
- Deployment управляет ReplicaSets и декларативными rollout
- Новая revision возникает при изменении Pod template
- readiness определяет участие Pod в available capacity
- rollback возвращает сохранённый Pod template, но не все внешние зависимости
2. Теория: ReplicaSet и reconciliation
ReplicaSet сравнивает spec.replicas с числом Pods, совпадающих с selector, и создаёт или удаляет Pods. Он связывает созданные Pods через ownerReferences. Обычно ReplicaSet не создают вручную: Deployment добавляет управление revisions и стратегией обновления.
Selector ReplicaSet не означает эксклюзивное владение любым совпавшим Pod. Adoption возможен только при соблюдении условий ownership; пересекающиеся selectors разных controllers создают неочевидное и опасное поведение.
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.
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 не выполняет.
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, метрики и проверку пользовательского пути.
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 не гарантирует совместимость данных и поведения.
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 заранее проверяйте совместимость конфигурации и данных
8. Лабораторная работа: первый Deployment
Создайте Deployment из трёх replicas с явной стратегией. Readiness probe здесь нужна для корректного понятия Available; подробно probes рассматриваются в модуле 11.
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=120skubectl -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"}'9. Лабораторная работа: revision и RollingUpdate
Измените image в manifest, сначала изучите diff, затем наблюдайте создание нового ReplicaSet. Старый ReplicaSet остаётся с нулём replicas для возможного rollback.
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/web10. Лабораторная работа: scale, pause и resume
Scale до пяти Pods не меняет template и revision. Затем pause объединяет изменение image и env в один rollout после resume.
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,podkubectl -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/web11. Диагностика: застрявший rollout и rollback
Несуществующий image создаёт новый ReplicaSet, но новые Pods не становятся Ready. При maxUnavailable=1 старые available Pods сохраняют сервисную capacity. После deadline Deployment сообщает отсутствие прогресса, но остаётся сломанным до действия оператора.
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. Контроль, критерии освоения и cleanup
- Что поддерживает ReplicaSet?
- Какое изменение создаёт новую revision?
- Зачем нужен pod-template-hash?
- Сколько Pods допустимо при replicas=3 и maxSurge=1?
- Чем Ready отличается от Available?
- Создаёт ли scale новую revision?
- Что происходит во время pause?
- Выполняет ли progressDeadline автоматический rollback?
- Почему undo не гарантирует совместимость данных?
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.