Обновление Kubernetes с 1.28 до 1.29 через kubeadm: полное пошаговое руководство | AdminWiki

Обновление Kubernetes с 1.28 до 1.29 через kubeadm: полное пошаговое руководство

07 августа 2026 7 мин. чтения

Обновление кластера Kubernetes с версии 1.28 до 1.29 через kubeadm - это контролируемая процедура, которая при правильной подготовке выполняется без потери данных и с минимальным влиянием на рабочие нагрузки. Это руководство содержит точную последовательность команд, проверенную на bare-metal кластере Ubuntu 22.04. Вы выполните резервное копирование etcd, обновите control-plane, поочередно прокатите апдейт по worker-узлам и приведете в соответствие версии CNI и CoreDNS.

Процесс обновления занимает от 30 до 60 минут в зависимости от размера кластера. Главный принцип - строгая последовательность: сначала control-plane, затем worker-ноды. Нарушение порядка или пропуск проверки совместимости - основная причина сбоев, с которыми сталкиваются администраторы. Если вы управляете кластером через подход «Инфраструктура как код», обратите внимание на автоматизацию обновления Kubernetes на bare metal с Ansible - это сокращает время операции с часов до минут.

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

Релиз 1.29 принес несколько критичных изменений, которые напрямую влияют на эксплуатацию. Во-первых, API версии flowcontrol.apiserver.k8s.io/v1beta2 удален - если ваши манифесты или операторы его используют, обновление заблокирует их работу. Во-вторых, прекращена поддержка insecure-режима в kubelet (флаг --pod-infra-container-image удален полностью). В-третьих, улучшена производительность etcd за счет оптимизации снапшотов.

Своевременный апгрейд закрывает векторы уязвимостей, исправленные в патчах 1.28.x, и дает доступ к новым возможностям планировщика. Главный практический стимул - политика поддержки Kubernetes: версия 1.28 получает исправления безопасности только до выхода 1.31. После этого кластер остается без патчей. Если вы еще не знакомы с альтернативными подходами к обновлению, изучите стратегии обновления Kubernetes: Rolling, Blue-Green и Canary - это поможет выбрать оптимальный сценарий для вашей среды.

Подготовка к обновлению: контрольный список

Перед запуском kubeadm upgrade выполните пять обязательных проверок. Пропуск любого из пунктов этого списка - прямой путь к длительной диагностике и потенциальной потере данных.

Резервное копирование etcd и конфигураций

Снапшот etcd - единственный гарантированный способ отката при фатальном сбое. Выполните команду на control-plane узле:

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 snapshot status /backup/etcd-snapshot-20260807.db

Сохраните манифесты статических подов и конфигурацию kubeadm:

cp -r /etc/kubernetes /backup/kubernetes-config-$(date +%Y%m%d)
cp /var/lib/kubelet/config.yaml /backup/kubelet-config.yaml

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

Убедитесь, что текущая версия kubeadm - 1.28.x. Пропускать минорные версии нельзя: обновление с 1.27 сразу на 1.29 не поддерживается.

kubeadm version
kubectl version --short

Запросите план обновления. kubeadm проанализирует кластер и покажет доступные целевые версии:

kubeadm upgrade plan

Вывод покажет версии kubeadm, kubelet, etcd и CoreDNS, которые будут обновлены. Обратите внимание на строки с предупреждениями о deprecated API - их нужно устранить до начала процедуры.

Проверьте использование устаревших API в текущих ресурсах:

kubectl get apiservices | grep -v Available
kubectl api-resources --api-group=flowcontrol.apiserver.k8s.io

Если обнаружены ресурсы с API v1beta2 flowcontrol, обновите их манифесты до v1beta3 до запуска kubeadm upgrade. Игнорирование этого шага приведет к ошибкам при обновлении control-plane.

Пошаговое обновление control-plane узла

Control-plane обновляется первым. На время обновления API-сервер будет недоступен, поэтому запланируйте окно на 10-15 минут. Рабочие нагрузки на worker-узлах продолжат работу.

Обновление пакетов kubeadm, kubelet, kubectl

Добавьте репозиторий Kubernetes 1.29. Для Ubuntu 22.04:

echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update

Удерживайте kubelet от автоматического обновления до завершения процедуры:

sudo apt-mark hold kubelet kubectl

Установите kubeadm версии 1.29.x:

sudo apt install -y kubeadm=1.29.8-1.1

Проверьте версию:

kubeadm version

Выполнение kubeadm upgrade apply

Выведите control-plane узел из планирования - новые поды не будут на него назначаться:

kubectl drain <control-plane-node> --ignore-daemonsets --delete-emptydir-data

Запустите обновление с указанием целевой версии:

sudo kubeadm upgrade apply v1.29.8

kubeadm выведет подтверждение версии и запросит согласие. Внимательно прочитайте вывод - если есть предупреждения о deprecated API, прервите процедуру (Ctrl+C) и устраните их. При успешном выполнении вы увидите сообщение [upgrade/successful] SUCCESS! Your cluster was upgraded to "v1.29.8".

Обновление kubelet и возврат узла в работу

Снимите блокировку с kubelet и kubectl, установите новые версии:

sudo apt-mark unhold kubelet kubectl
sudo apt install -y kubelet=1.29.8-1.1 kubectl=1.29.8-1.1
sudo systemctl daemon-reload
sudo systemctl restart kubelet

Верните узел в планирование:

kubectl uncordon <control-plane-node>

Проверьте статус узла и версии компонентов:

kubectl get nodes
kubectl version --short

Control-plane должен отображаться как Ready, версия 1.29.8. Если статус NotReady, проверьте логи kubelet: journalctl -u kubelet -f.

Обновление worker-узлов

Worker-ноды обновляются последовательно, по одной. Это сохраняет доступность приложений при настроенных репликах и PodDisruptionBudget. Для каждого worker-узла выполните одинаковую процедуру.

Поочередное обновление: drain, upgrade, uncordon

Шаг 1 - выведите узел из планирования и эвакуируйте поды:

kubectl drain <worker-node> --ignore-daemonsets --delete-emptydir-data --grace-period=60

Флаг --grace-period=60 дает контейнерам 60 секунд на корректное завершение. Увеличьте значение для тяжелых нагрузок.

Шаг 2 - обновите kubeadm на worker-узле (подключитесь к нему по SSH):

sudo apt update
sudo apt install -y kubeadm=1.29.8-1.1

Шаг 3 - выполните обновление конфигурации узла:

sudo kubeadm upgrade node

Шаг 4 - обновите kubelet и перезапустите его:

sudo apt install -y kubelet=1.29.8-1.1
sudo systemctl daemon-reload
sudo systemctl restart kubelet

Шаг 5 - верните узел в кластер:

kubectl uncordon <worker-node>

Дождитесь перехода узла в статус Ready, затем переходите к следующему. Параллельное обновление нескольких worker-узлов допустимо, если количество реплик ваших сервисов гарантирует доступность при временном сокращении пула нод.

Обновление плагинов CNI и CoreDNS

После обновления всех узлов приведите версии сетевого плагина и CoreDNS в соответствие с рекомендациями для Kubernetes 1.29.

Обновление сетевого плагина (CNI)

Проверьте текущую версию CNI. Для Calico:

kubectl get deployment -n kube-system calico-kube-controllers -o jsonpath='{.spec.template.spec.containers[0].image}'

Для Flannel:

kubectl get daemonset -n kube-flannel kube-flannel-ds -o jsonpath='{.spec.template.spec.containers[0].image}'

Сверьтесь с матрицей совместимости вашего CNI. Calico 3.27+ и Flannel 0.24+ поддерживают Kubernetes 1.29. Загрузите актуальный манифест и примените его:

# Для Calico
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calico.yaml

# Для Flannel
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/v0.24.0/Documentation/kube-flannel.yml

Проверьте перезапуск подов CNI и отсутствие ошибок в логах.

Обновление CoreDNS

Проверьте текущую версию CoreDNS:

kubectl get deployment -n kube-system coredns -o jsonpath='{.spec.template.spec.containers[0].image}'

Kubernetes 1.29 рекомендует CoreDNS 1.11.1. Обновите через kubeadm:

kubeadm upgrade apply v1.29.8 --feature-gates=CoreDNS=true

Либо вручную отредактируйте deployment:

kubectl set image deployment/coredns -n kube-system coredns=registry.k8s.io/coredns/coredns:v1.11.1

Убедитесь, что все поды CoreDNS перезапустились и находятся в статусе Running.

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

За годы эксплуатации кластеров мы собрали повторяющиеся сценарии сбоев. Вот конкретные сообщения об ошибках и команды для их устранения.

Ошибка: сертификаты истекли или не обновляются

Симптом: после kubeadm upgrade apply узлы не подключаются к API-серверу, в логах kubelet ошибка x509: certificate has expired.

Причина: сертификаты control-plane не обновились в процессе апгрейда. Решение - принудительное обновление:

sudo kubeadm certs renew all
sudo systemctl restart kubelet

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

sudo kubeadm certs check-expiration

Поды не запускаются после обновления узла

Симптом: после drain и uncordon поды висят в статусе Pending или CrashLoopBackOff.

Причина 1 - kubelet не перезапустился корректно. Проверьте логи:

journalctl -u kubelet -n 50 --no-pager

Причина 2 - CNI не совместим с новой версией kubelet. Проверьте логи сетевых подов:

kubectl logs -n kube-system <cni-pod>

Решение: перезапустите kubelet, при необходимости обновите CNI до совместимой версии.

Причина 3 - устаревшие сетевые политики блокируют трафик. Временно отключите их для диагностики:

kubectl delete networkpolicy --all -n <namespace>

Стратегии минимизации downtime при обновлении

Downtime приложений при обновлении kubeadm - не обязательное зло, а результат планирования. Три механизма сводят его к нулю.

Первый - PodDisruptionBudget. Настройте PDB для каждого критичного deployment:

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: app-pdb
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: critical-app

PDB блокирует drain узла, если эвакуация нарушит минимальное количество доступных реплик. kubeadm будет ждать, пока условие не выполнится.

Второй - правильная настройка drain. Флаг --grace-period задает время на graceful shutdown контейнеров. Флаг --ignore-daemonsets обязателен, так как DaemonSet-поды не эвакуируются. Для stateful-приложений с длительным завершением увеличьте grace period до 300 секунд.

Третий - очередность обновления узлов. Начинайте с узлов, на которых нет критичных нагрузок. Если приложение развернуто с тремя репликами на трех разных worker-узлах, обновляйте узлы последовательно, дожидаясь полной готовности реплик после каждого uncordon. Мониторинг во время процесса ведите через kubectl get pods -o wide -w в отдельном терминале.

Заключение: проверка кластера после обновления

Финальный аудит подтверждает, что кластер полностью функционален. Выполните пять проверок.

Первая - версии всех узлов:

kubectl get nodes -o wide

Все узлы должны показывать VERSION v1.29.8 и STATUS Ready.

Вторая - статус системных подов:

kubectl get pods -n kube-system

Все поды в статусе Running, количество перезапусков не увеличивается.

Третья - работоспособность DNS:

kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup kubernetes.default

Четвертая - создание и удаление тестового пода:

kubectl run test-pod --image=nginx --restart=Never
kubectl get pod test-pod
kubectl delete pod test-pod

Пятая - проверка сертификатов:

sudo kubeadm certs check-expiration

Все сертификаты должны иметь срок действия более 30 дней. Если какие-то истекают раньше, обновите их командой kubeadm certs renew all. Обновите внутреннюю документацию, зафиксировав новую версию кластера и дату апгрейда. Проведите тестирование отказоустойчивости - отключите один worker-узел и убедитесь, что сервисы переезжают на оставшиеся.

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