Обновление кластера Kubernetes 1.27 → 1.28 с Kubespray: полное пошаговое руководство 2026 | AdminWiki

Обновление кластера Kubernetes 1.27 → 1.28 с Kubespray: полное пошаговое руководство 2026

06 августа 2026 8 мин. чтения

Это руководство описывает полный цикл обновления production-кластера Kubernetes с версии 1.27 на 1.28 с помощью Kubespray. Вы получите готовую последовательность команд для Ansible, параметры inventory-файла для миграции etcd и Containerd, а также решения типичных проблем, возникающих при апгрейде. Все шаги проверены на Ubuntu 22.04 и Debian 12 в 2026 году.

Обновление голого кластера (bare-metal) через Kubespray минимизирует ручной труд и риск ошибок. Вы можете выполнить апгрейд control plane и worker-узлов с контролируемым простоем, сохранив целостность данных и доступность сервисов. Если вы управляете кластером по модели «Инфраструктура как код», эта инструкция станет вашей шпаргалкой.

Что изменилось в Kubernetes 1.28 и зачем обновляться

Kubernetes 1.28 вышел с рядом критических изменений, которые напрямую влияют на безопасность и стабильность кластера. Главный стимул для апгрейда - завершение поддержки предыдущих версий и удаление устаревших API. Если вы пропустите это окно, следующее обновление станет значительно сложнее из-за накопившихся изменений в спецификациях.

Ключевые изменения в версии 1.28:

  • Переход на Containerd 1.7+. Старые версии runtime не поддерживают новые возможности CRI. Версия Containerd 1.7 включает улучшенную обработку sandbox-ов и исправления утечек памяти, что критично для долгоживущих кластеров.
  • Удаление API beta-версий. Ресурсы из групп autoscaling/v2beta2 и batch/v1beta1 удалены. Манифесты с этими версиями перестанут применяться после обновления API-сервера. Аудит перед апгрейдом обязателен.
  • Улучшения безопасности. Включена стабильная поддержка PodSecurity (замена PSP). Появились новые метрики для аудита и контроля доступа к секретам.
  • Изменения в etcd. Рекомендованная версия etcd для K8s 1.28 - 3.5.9+. Старые версии могут вызывать расхождение данных при интенсивной нагрузке на API-сервер.

Обновление именно сейчас гарантирует, что вы не столкнетесь с каскадными ошибками при будущих апгрейдах. Практика показывает: кластеры, которые обновляются регулярно, тратят на процедуру в 2-3 раза меньше времени, чем те, что прыгают через несколько версий. Подробнее о стратегиях управления развертываниями можно прочитать в руководстве по настройке Deployment.

Подготовка окружения: контрольная точка перед стартом

Перед запуском Ansible playbook вы обязаны создать резервную копию состояния кластера и проверить совместимость текущих манифестов. Пропуск этого этапа - основная причина неудачных обновлений, после которых приходится восстанавливать кластер из снапшотов.

Зафиксируйте текущие версии компонентов. Выполните на мастер-узле:

kubectl version --short
kubectl get nodes -o wide
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 endpoint health

Эта информация понадобится для отката, если что-то пойдет не так. Убедитесь, что все узлы в статусе Ready, а etcd отвечает на запросы. Если кластер работает под нагрузкой, выполните обновление в период минимальной активности. Для критичных сервисов настройте стратегию RollingUpdate с параметрами maxUnavailable и maxSurge, как описано в материале по управлению приложениями.

Резервное копирование etcd: снапшот и восстановление

Снапшот etcd - ваша страховка. Без него любая ошибка при миграции данных станет фатальной. Создайте копию на мастер-узле и сохраните её за пределами кластера.

ETCDCTL_API=3 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 /backup/etcd-snapshot-$(date +%Y%m%d).db

Проверьте целостность снапшота:

ETCDCTL_API=3 etcdctl --write-out=table snapshot status /backup/etcd-snapshot-20260806.db

Вывод покажет хеш, размер и количество ревизий. Скопируйте файл на отдельный хост или в облачное хранилище. Процедура восстановления из снапшота потребует остановки всех экземпляров etcd и запуска с флагом --data-dir, указывающим на новый каталог. Этот сценарий детально разобран в нашем руководстве по аварийному восстановлению.

Аудит манифестов на устаревшие API

Kubernetes 1.28 отказывается принимать манифесты с удаленными API-версиями. Запустите проверку до начала обновления. Самый быстрый способ - утилита kubent (kube-no-trouble):

kubent --cluster-context production --output json

Вы получите список ресурсов с deprecated API, например:

{
  "kind": "HorizontalPodAutoscaler",
  "namespace": "default",
  "name": "web-autoscaler",
  "apiVersion": "autoscaling/v2beta2",
  "replacement": "autoscaling/v2"
}

Обновите эти манифесты до актуальных версий API и заново примените их. Альтернативный метод - встроенная команда kubectl api-versions, но она не показывает привязку к конкретным ресурсам. Для крупных кластеров с сотнями деплойментов автоматизированный аудит обязателен.

Настройка Kubespray: inventory и переменные для обновления

Клонируйте репозиторий Kubespray версии 2.23 или новее - только эта ветка гарантирует совместимость с Kubernetes 1.28. Используйте существующий inventory-каталог вашего кластера. Если вы разворачивали кластер через Kubespray, структура уже готова.

git clone --branch release-2.23 https://github.com/kubernetes-sigs/kubespray.git
cd kubespray
cp -r inventory/mycluster inventory/mycluster-upgrade

Основные переменные, которые нужно изменить в файле inventory/mycluster-upgrade/group_vars/k8s_cluster/k8s-cluster.yml:

kube_version: v1.28.6
container_manager: containerd
etcd_version: v3.5.9

Kubespray сам обработает зависимости и выкачает нужные бинарные файлы. Не меняйте параметры сети и DNS, если они работают стабильно.

Ключевые переменные для обновления etcd

Миграция etcd - самый чувствительный этап. Kubespray обновляет etcd поочередно на каждом узле, сохраняя кворум. За это отвечают переменные в group_vars/etcd.yml:

etcd_version: v3.5.9
etcd_binary_checksum: sha256:a1b2c3...
etcd_compaction_retention: 8

Параметр etcd_compaction_retention определяет, сколько часов хранить историю ревизий. Значение 8 часов достаточно для большинства production-сред. Если вы не укажете контрольную сумму (etcd_binary_checksum), Kubespray вычислит её автоматически, но явное указание исключает риск подмены бинарника.

Процесс обновления etcd через Kubespray устроен так: Ansible останавливает экземпляр etcd на первом узле, заменяет бинарный файл, запускает сервис и ждет восстановления синхронизации. Затем переходит к следующему. При трех мастер-узлах кворум сохраняется на каждом шаге.

Настройка Containerd для Kubernetes 1.28

Containerd 1.7 требует явного указания cgroup driver. Несовпадение драйвера между kubelet и containerd - частая причина, по которой поды зависают в статусе ContainerCreating. В файле group_vars/all/containerd.yml установите:

containerd_version: 1.7.13
containerd_default_runtime: "io.containerd.runc.v2"
containerd_config:
  grpc:
    max_recv_message_size: 16777216
    max_send_message_size: 16777216
  plugins:
    io.containerd.grpc.v1.cri:
      sandbox_image: "registry.k8s.io/pause:3.9"
      containerd:
        default_runtime_name: "runc"
        runc:
          SystemdCgroup: true

Параметр SystemdCgroup: true синхронизирует cgroup driver с kubelet. После обновления containerd перезапустится на каждом узле, но запущенные контейнеры не прервутся - runtime подхватит их после перезапуска.

Пошаговое выполнение обновления кластера

Запуск обновления выполняется одной командой Ansible с тегом upgrade. Но для контроля процесса мы разобьем его на этапы. Это позволит локализовать проблему, если она возникнет.

Сначала проверьте доступность всех узлов и корректность inventory:

ansible -i inventory/mycluster-upgrade/hosts.yml all -m ping

Затем запустите playbook с ограничением по группам. Kubespray использует теги для выборочного выполнения задач.

Обновление control plane узлов

Мастер-узлы обновляются первыми. Команда ограничивает выполнение группой etcd и kube_control_plane, не затрагивая worker-ы:

ansible-playbook -i inventory/mycluster-upgrade/hosts.yml cluster.yml \
  --tags=upgrade \
  --limit=etcd,kube_control_plane \
  -e serial=1

Флаг serial=1 гарантирует, что Ansible обрабатывает мастер-узлы строго по одному. После обновления первого мастера проверьте здоровье etcd:

etcdctl endpoint health --cluster

Вывод должен показать все endpoints в статусе healthy. Проверьте, что API-сервер отвечает:

kubectl get --raw /healthz

Ответ ok означает, что control plane функционирует. Повторите проверку после каждого мастер-узла. Если на каком-то шаге etcd теряет кворум, остановите процесс и восстановите узел из снапшота.

Обновление worker-узлов и пересоздание подов

Worker-узлы обновляются после стабилизации control plane. Kubespray автоматически выполняет cordon и drain для каждого узла перед обновлением. Настройте параметры в group_vars/k8s_cluster/k8s-cluster.yml:

upgrade_node_serial: 2
drain_grace_period: 300
drain_timeout: 360s

Значение upgrade_node_serial: 2 означает, что одновременно будут обновляться не более двух worker-узлов. Это сохраняет доступность приложений, если у вас настроены реплики и anti-affinity правила.

Запустите обновление worker-ов:

ansible-playbook -i inventory/mycluster-upgrade/hosts.yml cluster.yml \
  --tags=upgrade \
  --limit=kube_node

Во время выполнения команды отслеживайте пересоздание подов:

watch -n 2 kubectl get pods --all-namespaces -o wide

Поды с одного узла будут эвакуированы и запущены на других. После завершения обновления узел автоматически снимается с cordon. Если под «застрял» в статусе Terminating, проверьте логи kubelet на этом узле - возможно, приложение игнорирует SIGTERM.

Типичные ошибки при обновлении и их решение

За годы эксплуатации мы собрали базу повторяющихся проблем. Ниже - три самые частые ошибки с симптомами и способами исправления. Более обширный список с детальным разбором логов вы найдете в руководстве по устранению ошибок kubeadm.

Ошибка: несовместимость версии CNI плагина

Симптомы. После обновления worker-узла новые поды зависают в статусе ContainerCreating или Pending. В логах kubelet появляется запись: failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox.

Причина. Версия CNI-плагина (Calico, Flannel, Cilium) несовместима с Containerd 1.7 или новым API Kubernetes. Плагин не может создать сетевой интерфейс для пода.

Решение. Обновите CNI через Kubespray. В файле group_vars/k8s_cluster/k8s-net-calico.yml (или аналог для вашего плагина) укажите актуальную версию:

calico_version: v3.26.1

Запустите playbook только для сетевого компонента:

ansible-playbook -i inventory/mycluster-upgrade/hosts.yml cluster.yml --tags=network

После обновления пересоздайте зависшие поды. Если проблема сохраняется, проверьте, не конфликтует ли CNI с настройками cgroup в Containerd.

Проблемы с сертификатами после обновления

Симптомы. kubectl возвращает ошибку Unable to connect to the server: x509: certificate has expired or is not yet valid. Компоненты кластера не могут аутентифицироваться друг с другом.

Причина. При обновлении Kubespray может перегенерировать сертификаты, если обнаружит несоответствие сроков действия или алгоритмов. Старые сертификаты в конфигурации локального kubectl становятся невалидными.

Решение. Обновите локальный kubeconfig:

cp /etc/kubernetes/admin.conf ~/.kube/config

Если сертификаты кластера действительно истекли, принудительно перегенерируйте их через Kubespray:

ansible-playbook -i inventory/mycluster-upgrade/hosts.yml cluster.yml --tags=certs

Проверьте сроки действия новых сертификатов:

kubeadm certs check-expiration

Верификация кластера и завершающие шаги

После обновления всех узлов убедитесь, что кластер работает в штатном режиме. Начните с проверки версий:

kubectl get nodes

Столбец VERSION должен показывать v1.28.6 для всех узлов. Запустите тестовый под, чтобы проверить полный цикл создания контейнера:

kubectl run test-pod --image=nginx:alpine --restart=Never
kubectl get pod test-pod -w

Когда под перейдет в статус Running, удалите его:

kubectl delete pod test-pod

Проверьте работу ingress-контроллера и сервисов. Выполните curl к внешнему endpoint одного из приложений. Если используется мониторинг (Prometheus, Grafana), убедитесь, что метрики собираются и дашборды отображают данные. Инструменты мониторинга часто привязаны к конкретным версиям API - их тоже нужно обновить.

Обновите kubectl на локальной машине до версии, соответствующей кластеру. Разрыв в одну минорную версию допустим, но лучше синхронизировать:

kubectl version --client

Кластер готов к работе на Kubernetes 1.28. Рекомендуем настроить регулярное резервное копирование etcd и манифестов, чтобы следующее обновление прошло так же гладко. Если вы планируете расширять кластер или мигрировать на микросервисную архитектуру, обратите внимание на практический план перехода от монолита к микросервисам.

Поделиться:
Сохранить гайд? В закладки браузера