Kube/Pythonproduction course
Курс · RU11-production-operations.md

11. Промышленная эксплуатация

Незнакомый термин? Откройте словарь Kubernetes и терминов курса.

Назначение, предварительные знания и результаты обучения

Нужны главы 00–10. Эта глава не превращает kind в промышленный кластер; она формирует эксплуатационный обзор для управляемого или самостоятельно эксплуатируемого кластера.

После главы вы сможете:

  • составить план обновления с поддерживаемой совместимостью и порядком версий;
  • найти устаревшие и удалённые API до изменения плоскости управления;
  • оценить совместимость admission, вебхуков, CRD, CNI и CSI;
  • разделить снимок etcd и резервную копию приложения;
  • определить ёмкость, запас, SLO и бюджет ошибок;
  • аргументировать выбор управляемого или самостоятельного кластера;
  • провести локальную репетицию совместимости с целевой версией.

Базовая версия на дату исследования

Дата: 2026-07-29. Последняя стабильная версия Kubernetes: v1.36.2, выпущена 2026-06-09. Поддерживаемые основные ветки: 1.36, 1.35, 1.34. Срок поддержки исправляющих версий — примерно 14 месяцев с фазой обслуживания; перед обновлением используйте текущие страницы выпусков и исправляющих версий, а не считайте эту строку вечной.

Учебный kind v0.32.0 по умолчанию использует образ узла v1.36.1 с закреплённым digest. Стабильная исправляющая версия Kubernetes v1.36.2 новее, но образы узлов kind выпускаются по собственному графику; не подставляйте произвольный тег без совместимого выпуска или сборки kind.

Правила совместимости версий

Для kube-apiserver версии 1.36:

КомпонентПоддерживаемое соотношение
Экземпляры HA kube-apiserverсамая новая и старая версии различаются не более чем на одну дополнительную ветку
kubeletне новее сервера API; до 3 версий старее
kube-proxyне новее сервера API; до трёх версий старее; дополнительные правила относительно локального kubelet
контроллер, scheduler и облачный контроллерне новее сервера API; ожидается та же версия, при обновлении допустима на одну версию старее
kubectl±1 версия от сервера API

При серверах API разных версий допустимое пересечение сужается. Промежуточные версии нельзя пропускать при обновлении плоскости управления. Инструмент развёртывания или провайдер может иметь более строгие требования, чем основная политика Kubernetes.

Безопасный общий порядок N → N+1:

  1. Прочитать примечания к выпуску, устареванию и известным проблемам, а также план провайдера.
  2. Довести N до последней исправляющей версии; создать резервную копию и проверить восстановление; проверить дополнения, вебхуки, CRD и клиентов.
  3. Обновить экземпляры kube-apiserver без нарушения совместимости HA.
  4. Обновить менеджеры контроллеров, scheduler и облачный контроллер.
  5. Выполнять drain и обновлять kubelet узлов постепенно; kubelet не должен быть новее сервера API.
  6. Обновить kube-proxy и компоненты плоскости данных по регламенту реализации.
  7. Проверить SLO, ошибки API, рабочие нагрузки, хранилище, сеть и аудит; только затем расширять волну.

Откат плоскости управления может быть ограничен миграциями хранилища и API; регламент провайдера является авторитетным. Резервная копия не является автоматическим откатом.

Жизненный цикл API и устаревание

Линия API: v1 — GA, v1beta* — beta, v1alpha* — alpha. Версия GA может стать устаревшей, но не удаляется в текущей основной версии; beta может перестать обслуживаться после окна политики; alpha может быть удалена без предварительного устаревания.

Проверка перед обновлением:

kubectl api-versions
kubectl api-resources
kubectl apply --dry-run=server -f /tmp/rendered-all.yaml
kubectl get --raw /metrics |
  rg 'apiserver_requested_deprecated_apis|apiserver_request_total'

Последняя метрика требует административного доступа к метрикам и корректного разбора Prometheus; используйте долгосрочные метрики и аудит плоскости управления, а не один мгновенный образец. Ищите устаревшие API во всех манифестах, выпусках Helm, CRDs, контроллерах, сохранённых объектах и фактических запросах API. Предупреждение сервера — задача миграции.

Примеры v1.36: драйвер тома gitRepo окончательно отключён; .spec.externalIPs Service объявлен устаревшим из-за модели безопасности. Курс не использует ни один из них. Всегда сверяйте следующий целевой выпуск, а не только текущий.

Манифест политики admission

ValidatingAdmissionPolicy на основе CEL, доступный в GA с v1.30, позволяет выполнять простую проверку внутри процесса без сетевого перехода к вебхуку. Полный пример с ограниченной областью запрещает :latest только в явно помеченных namespaces:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: course-no-latest
spec:
  failurePolicy: Fail
  matchConstraints:
    resourceRules:
      - apiGroups: ["apps"]
        apiVersions: ["v1"]
        operations: ["CREATE", "UPDATE"]
        resources: ["deployments"]
  validations:
    - expression: >-
        object.spec.template.spec.containers.all(
          c, !c.image.endsWith(':latest')
        )
      message: "container images must not use the latest tag"
      reason: Invalid
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: course-no-latest
spec:
  policyName: course-no-latest
  validationActions: ["Deny"]
  matchResources:
    namespaceSelector:
      matchLabels:
        course.example.com/image-policy: enforced

Поэтапное включение:

  1. Проверить CEL и типы и выполнить серверный dry-run в целевой версии.
  2. Применить Binding Warn/Audit к контрольным namespaces.
  3. Измерить нарушения и ложные срабатывания, задокументировать исключения.
  4. Включить Deny для малой области, затем расширять.
  5. Отдельно подготовить политику аварийного доступа и откат.

Политика проверяет тег, но не подпись, уязвимости и происхождение. Вебхук нужен для внешнего поиска, однако становится зависимостью плоскости управления. Проверьте failurePolicy, тайм-аут, область сопоставления, HA, ротацию сертификатов и совместимость версий.

Границы резервного копирования и восстановления

etcd

Снимок etcd содержит состояние Kubernetes API: Deployments, Secrets, RBAC, CRDs и другие объекты. Он не содержит байты приложения в PVC, состояние внешних LB и БД и образы реестра. Критичны шифрование снимка, доступ к нему и срок хранения.

Иллюстративная команда для узла kind в стиле kubeadm (выполняйте только в одноразовом кластере, проверяя точные пути сертификатов):

docker exec kube-course-control-plane \
  etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  snapshot save /var/lib/etcd/course-snapshot.db
docker exec kube-course-control-plane \
  etcdutl snapshot status /var/lib/etcd/course-snapshot.db --write-out=table

Наличие исполняемых файлов и путей зависит от образа. Восстановление снимка меняет состояние плоскости управления и не выполняется в основной лаборатории: репетируйте в изолированном кластере по официальной процедуре etcd и инструмента развёртывания. Проверка snapshot status не заменяет тренировку восстановления.

Данные приложения

Для БД, объектов и PVC нужны согласованная с приложением резервная копия, независимая область отказа, шифрование, срок хранения, неизменяемая или отключённая копия там, где это необходимо, и периодическое восстановление с измерением RPO/RTO. Согласуйте манифесты, секреты и конфигурацию Kubernetes с версией данных. Регламент аварийного восстановления включает зависимости DNS, LB, идентичности и KMS.

Ресурсы кластера и SLO

План ёмкости учитывает:

  • запросы ресурсов, резервирование для системных процессов и maxSurge rollout;
  • потерю одного узла или зоны и размещение с PDB;
  • максимум HPA и задержку выделения узла;
  • ограничение CPU и лимиты памяти, временного хранилища, Pods, томов и IP;
  • масштабирование плоскости управления, API, etcd и дополнений;
  • квоту и всплеск арендатора;
  • рост, сезонность и верхнюю границу стоимости.

Не планируйте использовать 100% allocatable: тогда для maxSurge: 1, drain узла или отказа не останется запаса.

SLI — измерение пользовательского результата, например доля успешных учитываемых запросов или перцентиль задержки. SLO — цель за окно времени, например 99,9% за 30 дней. Бюджет ошибок — допустимые плохое время или запросы; он связывает скорость выпусков и надёжность. Kubernetes Ready replicas — внутренний сигнал, а не пользовательский SLI. Наблюдайте за успехом и задержкой запросов, исчерпанием ресурсов, здоровьем зависимостей и сигналами плоскости управления; сигналы тревоги должны требовать действия и вести к регламенту.

Управляемый и самостоятельно эксплуатируемый кластер

АспектУправляемая плоскость управленияСамостоятельная эксплуатация
Обновления и HA плоскости управлениячасть работы выполняет провайдерваша дежурная ответственность
Гибкостьограничения и график провайдерабольше возможностей настройки
Разделённая ответственностьузлы, дополнения и рабочие нагрузки всё ещё вашипочти весь стек ваш
Стоимостьплата за сервис и облачные ресурсыинфраструктура и высокая стоимость инженеров и дежурств
ИнтеграцияIAM, LB и хранилище лучше подготовленынужно выбирать и эксплуатировать
ПереносимостьAPI и ограничения провайдерасобственный выбор тоже создаёт зависимость

Управляемый сервис не означает отсутствие эксплуатации: CNI/CSI, пулы узлов, дополнения, политики, ёмкость, резервные копии, рабочие нагрузки и устаревания провайдера остаются.

Практическое упражнение: репетиция целевой версии

kind не предназначен для обновления промышленного кластера на месте. Вместо фальшивой репетиции создайте отдельный кластер совместимости:

kind create cluster \
  --name kube-course-upgrade \
  --image kindest/node:v1.35.5@sha256:ce977ae6d65918d0b58a5f8b5e940429c2ce42fa3a5619ec2bbc60b949c0ac95 \
  --wait 5m
kubectl config use-context kind-kube-course-upgrade
kubectl version
kubectl apply --dry-run=server -k manifests/overlays/prod

Secret намеренно не входит в Kustomization, поэтому это только репетиция API, а не развёртывание промышленного кластера. Затем удалите и пересоздайте цель:

kind delete cluster --name kube-course-upgrade
kind create cluster \
  --name kube-course-upgrade \
  --image kindest/node:v1.36.1@sha256:3489c7674813ba5d8b1a9977baea8a6e553784dab7b84759d1014dbd78f7ebd5 \
  --wait 5m
kubectl config use-context kind-kube-course-upgrade
kubectl apply --dry-run=server -k manifests/overlays/prod
kubectl api-resources

Ожидается успех обеих проверок; различия обнаружения API и примечания к выпуску фиксируются. Это проверяет манифесты относительно API, но не обновление системы с состоянием на месте, преобразование CRD и реальные CNI, CSI, провайдера и вебхуков.

Очистка и восстановление контекста:

kind delete cluster --name kube-course-upgrade
kubectl config use-context kind-kube-course
test "$(kubectl config current-context)" = "kind-kube-course"

Самостоятельная задача

Напишите одностраничный план обновления 1.35 → 1.36: инвентаризация, матрица совместимости, владельцы дополнений и вебхуков, доказательства использования API, резервные копии и доказательства восстановления, PDB и ёмкость, контрольная группа и волны, пороги остановки по SLO, откат и эскалация. Критерий приёмки: ни одного шага «обновить всё» и ни одного непроверенного заявления о резервной копии.

Сломанный сценарий: rollout с политикой admission

Применение Deny сразу ко всем namespaces может заблокировать системные дополнения. Смоделируйте безопасно:

kubectl apply --dry-run=server -f /tmp/course-no-latest-policy.yaml
kubectl apply -f /tmp/course-no-latest-policy.yaml
kubectl label namespace kube-course \
  course.example.com/image-policy=enforced --overwrite
kubectl apply --dry-run=server -f /tmp/deployment-using-latest.yaml

Ожидается, что Deployment с latest будет отклонён. Если отклонена сама CEL-политика, не переходите к Binding: проверьте тип выражения, схему и целевую версию. Восстановление:

kubectl label namespace kube-course course.example.com/image-policy-
kubectl delete validatingadmissionpolicybinding course-no-latest
kubectl delete validatingadmissionpolicy course-no-latest

Удаление или ослабление политики — изменение безопасности; в эксплуатационной среде оно требует аварийного доступа и аудита, а не обычного исправления разработчиком.

Дерево диагностических решений

Готовность к обновлению
├─ неподдерживаемая разница версий/инструмент/провайдер → остановиться, выбрать поддерживаемую промежуточную версию
├─ фактические запросы используют устаревший API → перенести клиентов/контроллеры/манифесты
├─ серверный dry-run целевой версии завершается ошибкой → миграция API/схемы/admission
├─ совместимость дополнений/вебхуков неизвестна → тест владельца/canary, не начинать rollout
├─ восстановление не продемонстрировано → проверка резервной копии не пройдена
└─ нет порога остановки по ёмкости/SLO → эксплуатационная проверка не пройдена

Симптом после обновления
├─ ошибки API/admission → apiserver/аудит/вебхук/версия
├─ Pods Pending → ёмкость/taints/CSI/топология
├─ массовый сбой сети/хранилища → версия CNI/CSI/DaemonSets
├─ корреляция с узлом → kubelet/среда исполнения/разница версий
└─ только приложение → rollout/конфигурация нагрузки; не откатывать сначала плоскость управления

Типичные ошибки: пропуск промежуточной версии; обновление kubelet до сервера API; поиск устаревших API только в Git; резервная копия без восстановления; одновременное обновление всех узлов; игнорирование PDB и ёмкости; отказоустойчивый вебхук с одной репликой; тег stable без digest; приравнивание SLO к Pod Running; предположение, что в управляемом сервисе провайдер отвечает за всё.

Эксплуатационные компромиссы, безопасность и стоимость

Поддержание актуальной версии снижает риски конца поддержки и безопасности; слишком быстрые обновления без контрольной группы повышают риск изменений. Несколько поддерживаемых версий и окружений расходуют ёмкость, но дают доказательства отката. Admission, KMS, аудит и резервное копирование добавляют задержку и стоимость хранения и эксплуатации, зато ограничивают радиус поражения. Плата за управляемый сервис часто дешевле самостоятельных дежурств плоскости управления; сравнивайте полную стоимость и ограничения. Удаляйте простаивающие ресурсы осторожно: снимки, LB, PV и IP могут сохраниться и содержать чувствительные данные.

Самопроверка

  1. Может ли kubelet быть новее сервера API?
  2. Какова поддерживаемая разница версий kubectl?
  3. Можно ли пропустить промежуточную версию плоскости управления?
  4. Что не входит в снимок etcd?
  5. Почему серверный dry-run целевой версии недостаточен?
  6. Что такое бюджет ошибок?
  7. Какой риск у admission-вебхука?

Ответы: 1) нет; 2) ±1 версия; 3) нет; 4) байты томов и приложения, внешние системы и образы; 5) не проверяет среду исполнения, CNI/CSI, преобразование состояния и пользовательский путь; 6) допустимый объём плохих результатов относительно SLO; 7) зависимость плоскости управления и риски fail-open/fail-closed, версии, сертификата и доступности.

Резюме и источники

Готовность к промышленной эксплуатации — непрерывные обновление, восстановление, управление ёмкостью, политиками, SLO и дисциплина стоимости. Далее выполните лабораторные работы с kubectl и итоговый проект.