Модуль 34. Обновления и миграции Kubernetes
Цель: научиться обновлять кластер и всё вокруг (CNI/CSI/Ingress/операторы/CRD/ворклоады) без даунтайма и с прозрачным откатом.
Что будет на выходе:
- Понимание политики версий и деприкаций (GA/β/α, сроки удаления).
- Процесс pre-flight-проверок: инвентаризация API, бэкапы etcd/PV, тестовый апгрейд на стенде.
- Две стратегии: in-place и blue/green (параллельный «новый» кластер + миграция).
- Чёткая последовательность обновления: control plane → CNI/CSI/Ingress → CRD/операторы → ноды → приложения.
- Автоматизация и «ворота качества»: GitOps, скан deprecated-ресурсов, admission-политики.
- Runbook’и отката: restore etcd / rollback выпуска приложений / drain-петли.
Политика версий и совместимость
Семантика API и сроки деприкаций
- GA (stable): обратная совместимость максимально гарантирована; удаление/ломающие изменения — только после длительного периода деприкации (ориентируйтесь на ≥12 месяцев и ≥3 минорных релиза).
- β (beta): интерфейс ещё может меняться; deprecated β-API обычно удаляют не ранее, чем через ~3 минорных релиза (ориентир ~9–12 мес).
- α (alpha): может меняться/исчезнуть в любой версии; не используем в проде.
Практика: если у вас в манифестах extensions/v1beta1 или любые */v1beta1, это красный флаг — готовьтесь к миграции на .../v1.
Версионный «скью» (кто с кем совместим)
- kube-apiserver ↔ kubelet: допускается разница в одну минорную версию (kubelet обычно не новее apiserver).
- kubectl: как правило, −1…+1 к apiserver по минорной версии.
- Компоненты control plane (scheduler/controller-manager) — обычно той же версии, что и apiserver (или на −1).
Следствие: обновляем control plane → затем по очереди ноды/ kubelet, а не наоборот.
Подготовка апгрейда: «ноль инцидентов начинается здесь»
-
Инвентаризация API и CRD
- Прогон манифестов и живых объектов на deprecated-схемы (см. §6: pluto/kubent/kubeconform).
- Список операторов/CRD + их совместимые версии (матрицы от вендоров/опенсорс-проектов).
- Freeze на изменения
- Заморозить новые релизы приложений/операторов на период апгрейда (кроме фикс-релизов).
- etcd snapshot (managed-кластеры — штатный снапшот/по инструкции облака).
- Velero/снапшоты PV/бэкапы БД (PITR), если есть риск разрушения данных.
- Клон манифестов (GitOps branch) → развёртывание на staging/kind/k3d; e2e-тесты и «дымовые» проверки SLO.
- Для больших кластеров — canary-пул нод: обновляем небольшой пул, прогоняем трафик, смотрим SLO.
- Зафиксировать «что считается инцидентом», SLA бэкофиса, on-call, план отката и точки контроля.
- Бэкапы
- Стенд / canary
- Окно изменений и коммуникации
Стратегии апгрейда
In-place (типовая)
- Обновляем control plane по шагам → плагины (CNI/CSI/Ingress) → CRD/операторы → ноды батчами (cordon/drain/upgrade/uncordon) → в конце — ворклоады (если нужен пересоздание).
- Плюсы: дешевле, привычно. Минусы: нужен строгий порядок и дисциплина.
Blue/Green кластер
- Поднимаем новый кластер нужной версии, реплицируем секреты/конфиги/операторы, мигрируем трафик/данные по сервисам (Ingress/внешний LB/ServiceMesh).
- Плюсы: чистая среда, быстрый rollback (вернуться на старый). Минусы: дороже, нужна сетево-данная обвязка.
Когда выбирать blue/green: крупные «скачки» версии, много сторонних CRD, жёсткие SLA, сильная зависимость от CNI/CSI.
Порядок обновления (шпаргалка)
-
Control plane
- kube-apiserver → controller-manager → scheduler → (если kubeadm — kubeadm upgrade plan/apply).
- Если etcd управляется отдельно — его версия и совместимость проверены заранее.
- Сетевые/хранилищные плагины
- CNI (Calico/Cilium/…): убедиться, что версия поддерживает целевой k8s; возможна миграция CRD (NetworkPolicy/ClusterCIDR-расширения).
- CSI-драйверы: обновить контроллер/ноды-плагины, проверить StorageClass, снапшоттеры.
- Ingress-контроллер (nginx/traefik/HAProxy) и cert-manager (часто завязаны на CRD-версии).
- Поднять CRD-версии (при необходимости включить conversion webhook); обновить операторы (Zalando PGO, ClickHouse Operator, Strimzi, Argo, Flux и т. п.).
- Убедиться, что storageVersion объектов конвертируется (для больших массивов — StorageVersionMigration).
- По группам: cordon → drain (учитывая PDB) → обновить kubelet/kube-runtime → uncordon.
- Следить за DaemonSet (логирование/мониторинг/ServiceMesh-sidecar), rollout стратегиями и affinity.
- Манифесты переведены на актуальные API; GitOps промо на прод; дымовые тесты и SLO.
- CRD и операторы
- Node Pools
- Приложения
Миграция манифестов и «болевые точки»
- Ingress: от extensions/v1beta1 → networking.k8s.io/v1, обязателен pathType, менялись семантики аннотаций/IngressClass.
- CronJob: от batch/v1beta1 → batch/v1.
- PodSecurityPolicy (PSP): удалён; замена — Pod Security Admission (Namespace-уровень) и/или Kyverno/Gatekeeper правила.
- In-tree volume/CCM → CSI/внешний CCM: проверьте миграцию драйверов/плагинов и параметры StorageClass.
- Admission/Mutating Webhooks: версия API, таймауты/перерывы. На апгрейде не допустите «зависания» из-за недоступных вебхуков (режимы failurePolicy).
- API-варианты CRD: храните 2 версии (v1beta1 + v1) с conversion webhook → постепенно мигрируйте storageVersion.
Инструменты и «ворота качества»
-
Поиск устаревших API:
- Pluto (Fairwinds): находит deprecated/removed API в файлах и в кластере.
- kubent / kube-no-trouble: детектор устаревших ресурсов и советов по миграции.
- kubeconform / kubeval: валидация схем.
- Datree / kube-linter: политики качества манифестов.
- Admission-политики:
- Kyverno/Gatekeeper — запретить apply устаревших apiVersion, отсутствие requests/limits, запрет :latest и т. п.
- Pod Security уровни (baseline/restricted) — включить и валидировать на staging.
- GitOps-защиты: PR-проверки (линтеры/валидация), «промо через PR» Dev→Stage→Prod, прогрев образов.
Проверки после обновления
- Кластерные: состояние control plane, etcd, CNI/CSI/Ingress, webhooks (latency/ошибки).
- Прикладные: SLO дашборд (p95 latency/ошибки), подключение к БД/кешу, фоновые джобы и алерты (CronJob не «застряли»).
- Служебные: логгирование/мониторинг (Prometheus scrape/alertmanager маршруты), права RBAC/SA.
- Наблюдаемость отклонений: всплеск 4xx/5xx, рост Evicted/OOM, сетевые DENY после обновления политик.
Риски и анти-паттерны
|
Риск |
Как проявляется |
Как избежать |
|---|---|---|
|
Устаревшие API в манифестах |
apply/синхрон Argo ломается |
Скан Pluto/kubent, миграция на .../v1, PR-гейт |
|
Поломка webhooks на апгрейде |
apply «висит»/ошибки admission |
Проверить версии webhook’ов, failurePolicy=Ignore на время окна (если допустимо) |
|
PSP удалили — политики пропали |
«Дыры» в безопасности |
Заранее перевести на Pod Security Admission + Kyverno/Gatekeeper |
|
CNI/CSI несовместимы |
Подов нет/нет сети/томов |
Совместимые версии, порядок обновления: control plane → CNI/CSI → ноды |
|
PDB отсутствуют |
drain «роняет» сервис |
Ввести PDB до апгрейда, проверить maxUnavailable |
|
Неправильный порядок |
Зависшие DaemonSet/операторы |
Следовать порядку §4, читать release notes к каждому компоненту |
|
Нет бэкапов etcd/данных |
Нет отката |
etcd snapshot + Velero/бэкапы БД, rehearsal restore |
|
Слишком большой скачок версий |
Массовые несовместимости |
Обновлять по шагу (N→N+1), blue/green при больших изменениях |
Практика (лабораторка за 1–2 дня)
- Скан манифестов: прогнать Git-репо через Pluto/kubent, завести PR с фиксом Ingress/CronJob/PSP.
- Staging-апгрейд: поднять стенд (kind/k3d/managed), обновить control plane → CNI → CSI → ingress → CRD/операторы → ноды.
- GitOps-промо: переключить ветку окружения на новую версию манифестов, прогнать дымовые тесты и SLO.
- Canary-ноды: обновить 10–20% воркер-пула, check SLO/алерты → докат до 100%.
- Откат-дрилл: эмулировать фейл webhook/Ingress, откатить релиз через Git/Argo; проверить restore etcd на стенде.
- Admission-гейт: включить политику «запрет устаревших apiVersion» на staging.
Чек-лист «готово к продакшен-апгрейду»
- Полн. инвентаризация API/CRD/операторов; матрица совместимости собрана.
- Pluto/kubent чисто; PR-гейт на устаревшие API включён.
- Бэкапы: etcd snapshot, Velero/БД (PITR), rehearsal-restore пройден.
- План и порядок обновления согласованы; on-call/окно изменений подтверждены.
- PDB/пробы/ресурсы у приложений заданы; readiness действительно проверяет «готовность».
- Стенд/канареечный пул нод обкатан; SLO/алерты — зелёные.
- Документы: runbook «drain без даунтайма», «webhook завис», «Ingress не поднимается», «restore/rollback».
Вопрос-ответ
В: Можно ли «перепрыгнуть» через несколько минорных версий?
О: Теоретически да, но риск резко возрастает (несовместимости API/плагинов). Практика — обновляться по одному минорному шагу; для больших скачков — blue/green.
В: Как быстро понять, сломаются ли манифесты?
О: Прогнать репозиторий и живой кластер через Pluto/kubent, включить в CI политику «запрет устаревших API», сделать kubectl apply --dry-run=server на staging.
В: Что обновлять первым — control plane или ноды?
О: Control plane (apiserver), затем CNI/CSI/Ingress/операторы, затем ноды батчами, потом — приложения (если есть миграции).
В: Как минимизировать даунтайм?
О: PDB + корректные readiness/startup-пробы, maxUnavailable/maxSurge у контроллеров, поэтапный drain, canary-ноды, окно низкой нагрузки.
В: Что делать с удалённым PSP?
О: Заранее перевести на Pod Security Admission (уровни baseline/restricted) + описать тонкие правила в Kyverno/Gatekeeper.
В: Когда нужен новый кластер вместо in-place?
О: Много CRD/операторов, большой скачок версий, смена CNI/CSI/сетевой сетки, жёсткие SLA. Blue/green даст безопасный откат.
В: Как откатываться, если control plane уже обновили и «поехало»?
О: На собственных кластерах — restore etcd на предыдущий снапшот (понимая последствия). В managed — предусмотренные механизмы отката/поддержки + возврат трафика в старый кластер (если blue/green).
В: Что с kubelet/kubectl версиями?
О: Держите разницу в пределах одной минорной. kubectl допустимо −1…+1 к apiserver, kubelet обычно не новее apiserver.
Успешный апгрейд Kubernetes — это процесс, а не «кнопка»: инвентаризация API и плагинов, стенд/canary, строгий порядок (control plane → плагины → CRD → ноды), «ворота качества» в GitOps и готовый план отката. Если вы закрыли «болевые точки» (Ingress/PSP/CRD/webhooks), то обновления перестают быть «стрессом» и становятся штатной рутиной — именно так и должно быть в зрелой BI/DWH-платформе.



