← Back to notes

ReplicaSet и
Deployment


ReplicaSet и Deployment — два уровня абстракции для управления Pod. ReplicaSet поддерживает заданное количество реплик. Deployment управляет ReplicaSet и добавляет declarative updates: rolling update, откат, история ревизий. На практике Deployment — основной рабочий объект; ReplicaSet создаётся Deployment автоматически.

[source: kubernetes.io/docs/concepts/workloads/controllers/deployment/]

ReplicaSet

ReplicaSet гарантирует, что в кластере работает заданное количество реплик Pod. Если Pod падает — ReplicaSet создаёт новый. Если Pod лишний — удаляет.

[source: kubernetes.io/docs/concepts/workloads/controllers/replicaset/]

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
        - name: nginx
          image: nginx:1.27
          ports:
            - containerPort: 80

Ключевое правило: spec.selector.matchLabels должен совпадать с spec.template.metadata.labels. API Server отклонит манифест при несовпадении.

# Масштабирование ReplicaSet (императивно)
kubectl scale replicaset frontend --replicas=5

# Декларативно  изменить replicas в манифесте и применить
kubectl apply -f replicaset.yaml

На практике ReplicaSet напрямую не создают — используют Deployment.

Deployment

Deployment — абстракция уровнем выше ReplicaSet. Управляет ReplicaSet и предоставляет декларативные обновления Pod.

Что Deployment даёт поверх ReplicaSet:

  • Rolling update с контролем процесса (maxUnavailable, maxSurge)
  • Откат к предыдущей ревизии
  • История ревизий
  • Пауза и возобновление развёртывания
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.27
          ports:
            - containerPort: 80
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 250m
              memory: 256Mi

Стратегии обновления

RollingUpdate (по умолчанию)

Постепенная замена Pod старой версии на новую. В любой момент доступна минимум часть Pod.

[source: kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-update-deployment]

Пример: replicas=3, maxUnavailable=1, maxSurge=1 — в процессе обновления одновременно от 2 до 4 Pod.

Recreate

Убивает все существующие Pod, затем создаёт новые. Приводит к даунтайму. Используется когда приложение не поддерживает одновременную работу двух версий (например, несовместимая схема БД).

spec:
  strategy:
    type: Recreate

Обновление Deployment

Способ 1: изменение манифеста (рекомендуется)

# Изменить image в YAML-файле, затем:
kubectl apply -f deployment.yaml

Способ 2: kubectl set image

kubectl set image deployment/nginx-deployment nginx=nginx:1.28

Способ 3: kubectl edit

kubectl edit deployment nginx-deployment

Как Deployment управляет ReplicaSet

При каждом изменении spec.template Deployment создаёт новый ReplicaSet и постепенно увеличивает в нём количество Pod, одновременно уменьшая в старом.

Deployment
  ├── ReplicaSet (v1)  replicas: 0  (старый, сохранён для отката)
  ├── ReplicaSet (v2)  replicas: 0  (старый)
  └── ReplicaSet (v3)  replicas: 3  (текущий)

Старые ReplicaSet сохраняются (с 0 реплик) для возможности отката. Количество хранимых ревизий — spec.revisionHistoryLimit (по умолчанию 10).

Rollout: управление развёртыванием

# Статус текущего обновления
kubectl rollout status deployment/nginx-deployment

# История ревизий
kubectl rollout history deployment/nginx-deployment

# Детали конкретной ревизии
kubectl rollout history deployment/nginx-deployment --revision=2

# Откат к предыдущей ревизии
kubectl rollout undo deployment/nginx-deployment

# Откат к конкретной ревизии
kubectl rollout undo deployment/nginx-deployment --to-revision=1

# Пауза (для batched изменений  несколько изменений в одном rollout)
kubectl rollout pause deployment/nginx-deployment

# Возобновление
kubectl rollout resume deployment/nginx-deployment

# Перезапуск всех Pod (rolling restart без изменения образа)
kubectl rollout restart deployment/nginx-deployment

Основные команды

# Создание
kubectl create deployment nginx --image=nginx:1.27 --replicas=3
kubectl apply -f deployment.yaml

# Список
kubectl get deployments
kubectl get deploy

# Подробности
kubectl describe deployment nginx-deployment

# Масштабирование
kubectl scale deployment nginx-deployment --replicas=5

# Автомасштабирование (HPA)
kubectl autoscale deployment nginx-deployment --min=2 --max=10 --cpu-percent=70

# Связанные ReplicaSet
kubectl get replicasets
kubectl get rs

# Удаление
kubectl delete deployment nginx-deployment

Типичные ошибки

Не указывать --record и потом не понимать историю ревизий. Флаг --record deprecated, не используй. Для понятной истории ревизий используй kubectl annotate deployment nginx-deployment kubernetes.io/change-cause="update image to 1.28" перед или после изменения.

maxUnavailable=0 и maxSurge=0 одновременно. API Server отклонит такую конфигурацию — обновление невозможно если оба параметра нулевые.

Не дожидаться завершения rollout. В CI/CD после kubectl apply нужно ждать kubectl rollout status — без этого пайплайн может считать деплой успешным при фактически сломанном Pod.

Изменить selector существующего Deployment. Selector у Deployment immutable после создания. Попытка изменить через kubectl apply получит ошибку field is immutable. Нужно удалить Deployment и создать заново.

Слишком маленький revisionHistoryLimit. При значении 0 или 1 откат невозможен — нет сохранённых ReplicaSet. Разумный минимум для production — 3-5.

OOMKilled и бесконечный CrashLoopBackOff при rolling update. Если новая версия OOMKilled с первого запуска, Deployment не завершит rolling update (новые Pod не становятся Ready). Deployment остановится на полпути, старые Pod продолжат работать. Диагностика: kubectl rollout status + kubectl describe pod.

Альтернативы

StatefulSet — для stateful приложений, где Pod нужна стабильная идентичность и отдельный persistent storage (глава 11).

DaemonSet — когда нужен ровно один Pod на каждом узле (глава 11).

Argo Rollouts — расширение поверх Deployment с canary и blue/green стратегиями, traffic splitting и автоматическим анализом метрик. Не встроено в Kubernetes, устанавливается отдельно.

Helm — управление набором ресурсов (Deployment + Service + ConfigMap + ...) как единым пакетом с версионированием. Не замена Deployment, а инструмент доставки.


04: Namespaces

06: Services

ReplicaSet и Deployment | Aleksandr Suprun