Устранение ошибок обновления kubeadm: etcd, kubelet и CNI (2026) | AdminWiki

Устранение ошибок обновления kubeadm: etcd, kubelet и CNI (2026)

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

Диагностика состояния кластера после сбоя обновления

Обновление кластера Kubernetes через kubeadm прервалось ошибкой. Узлы в статусе NotReady, поды не стартуют, сеть не работает. Первые минуты определяют, как быстро вы восстановите управление. Начните с трёх команд, которые покажут масштаб проблемы.

kubectl get nodes

Вывод покажет статус узлов. NotReady - сигнал, что kubelet не может связаться с control plane или есть проблемы с CNI. Узел может быть Ready, но часть подов виснет - это указывает на сетевые ошибки.

kubectl get pods -n kube-system

Системные поды - индикатор здоровья кластера. Статусы CrashLoopBackOff, Error или ContainerCreating для etcd, kube-apiserver, kube-controller-manager или coredns требуют немедленного анализа. Запишите имена проблемных подов и узлы, на которых они запущены.

Если kubectl недоступен, проверьте контейнеры напрямую на мастер-узле. Это частая ситуация при отказе API-сервера. Переходите к анализу логов kubelet и состоянию контейнеров через CRI.

Для комплексной диагностики сетевых проблем на уровне подов и узлов используйте метрики мониторинга. В статье Kubernetes Troubleshooting: диагностика Pods и узлов через метрики мониторинга разобраны PromQL-запросы и критерии отличия утечки памяти от нехватки ресурсов.

Использование journalctl для анализа логов kubelet

Kubelet - агент, который запускает поды на узле. Его логи - первая точка проверки. Ошибки сертификатов, конфигурации, сетевых плагинов фиксируются здесь.

journalctl -u kubelet --since "1 hour ago" | grep -i error

Эта команда извлекает ошибки за последний час. Если обновление выполнялось раньше, увеличьте интервал. Для поиска конкретных проблем фильтруйте вывод.

Ошибки сертификатов:

journalctl -u kubelet | grep -i certificate

Типичная запись: Failed to load certificate: certificate has expired или x509: certificate signed by unknown authority. Это означает, что сертификат kubelet просрочен или не соответствует сертификату CA.

Ошибки конфигурации:

journalctl -u kubelet | grep -i config

Вывод вида failed to load Kubelet config file или unknown flag: --network-plugin указывает на неверные параметры в /var/lib/kubelet/config.yaml или устаревшие флаги запуска.

Ошибки CNI:

journalctl -u kubelet | grep -i cni

Запись cni plugin not initialized или failed to find plugin "loopback" сигнализирует о проблемах с сетевыми плагинами. Причина - отсутствие конфигурации в /etc/cni/net.d/ или конфликт плагинов.

Проверка контейнеров через crictl

Когда kubelet не может запустить поды, проверьте состояние контейнеров напрямую через Container Runtime Interface. crictl работает с containerd и CRI-O.

crictl ps -a

Вывод покажет все контейнеры, включая остановленные. Статус Exited с кодом возврата, отличным от 0, указывает на аварийное завершение. Обратите внимание на контейнеры etcd, kube-apiserver, kube-controller-manager и kube-scheduler.

Чтобы найти ID контейнера etcd:

crictl ps -a | grep etcd

Просмотрите логи конкретного контейнера:

crictl logs <container-id>

Для etcd характерны сообщения etcd: leader lost, etcd: version mismatch, connection refused. Эти записи подтверждают потерю лидера или несовместимость версий членов кластера.

Если контейнер kube-apiserver в статусе Exited, проверьте его логи:

crictl logs $(crictl ps -a | grep kube-apiserver | awk '{print $1}')

Ошибки вида etcd cluster is unavailable или tls: bad certificate сужают круг поиска до etcd или проблем с сертификатами.

Восстановление etcd: потеря лидера и несовместимость версий

Etcd - распределённое хранилище ключ-значение, в котором Kubernetes хранит всё состояние кластера. Без работающего etcd API-сервер не может обслуживать запросы, а кластер становится неуправляемым. Две типовые проблемы при обновлении: потеря лидера и несовместимость версий членов кластера.

Потеря лидера возникает, когда узел-лидер etcd перестаёт отвечать, а остальные члены не могут провести выборы. Причина - сетевой разрыв, недостаток ресурсов или аварийная остановка контейнера etcd во время обновления. Несовместимость версий появляется, если часть узлов etcd обновилась, а часть осталась на старой версии. Протокол raft, на котором основан etcd, требует идентичных версий для корректной работы.

Перед любыми операциями с etcd сделайте резервную копию. Инструкции по полному аварийному восстановлению кластера, включая восстановление из бэкапа etcd, описаны в статье Обновление кластера Kubernetes 1.27 → 1.28 с помощью Kubespray.

Диагностика потери лидера etcd

Проверьте состояние членов кластера etcd:

etcdctl member list

Работающий кластер покажет список всех членов. Если команда зависает или возвращает connection refused, etcd недоступен.

Проверьте статус конечных точек:

etcdctl endpoint status

Вывод для здорового кластера содержит RAFT_INDEX и RAFT_TERM с близкими значениями на всех членах. При потере лидера часть узлов покажет RAFT_INDEX значительно меньше остальных, а поле RAFT_LEADER будет пустым.

Анализ логов etcd-контейнера:

crictl logs $(crictl ps -a | grep etcd | awk '{print $1}') | grep -E "leader|lost|election"

Характерные записи:

  • etcd: leader lost - узел был лидером и потерял связь с остальными.
  • etcd: no leader - кластер не может выбрать лидера.
  • rafthttp: failed to send message - сетевые проблемы между членами etcd.

Для восстановления кворума выполните принудительное пересоздание кластера etcd на уцелевшем узле. Остановите etcd на всех узлах, кроме одного с наиболее актуальными данными. На этом узле запустите:

etcd --force-new-cluster

После старта добавьте остальные узлы командой etcdctl member add. Этот метод рискован и требует точного определения узла с последними данными. Ошибка приведёт к потере состояния кластера.

Исправление несовместимости версий etcd

Проверьте версии etcd на всех узлах:

etcdctl version

Вывод покажет версию клиента и сервера. Если версии различаются, обновление прошло частично. Протокол raft блокирует запись при расхождении версий, что вызывает отказы API-сервера.

Варианты решения:

  1. Понижение версии на обновлённом узле. Остановите etcd, замените бинарный файл на предыдущую версию, запустите etcd. Этот способ требует, чтобы формат данных был обратно совместим. Проверьте документацию etcd к вашей версии.
  2. Принудительное обновление остальных узлов. Если формат данных изменился и обратная совместимость не поддерживается, обновите etcd на всех оставшихся узлах до той же версии. Используйте пакетный менеджер или замените бинарные файлы вручную.

После выравнивания версий перезапустите etcd на всех узлах и проверьте состояние кластера:

etcdctl endpoint status

Все члены должны показывать одинаковую версию и наличие лидера.

Устранение сбоев kubelet после обновления

Kubelet обновлён, но узел в статусе NotReady. Поды не запускаются, в логах ошибки. Две основные причины: неверная конфигурация и проблемы с сертификатами.

Проверьте статус kubelet:

systemctl status kubelet

Состояние active (running) не гарантирует корректной работы. Kubelet может быть запущен, но не способен зарегистрировать узел в API-сервере. Анализируйте логи.

Для быстрой диагностики ошибок kubelet, связанных с конфигурацией и сертификатами, используйте фильтрацию:

journalctl -u kubelet | grep -E "config|error"

Исправление конфигурации kubelet

Файл конфигурации /var/lib/kubelet/config.yaml управляет поведением kubelet. После обновления kubeadm может изменить структуру этого файла или ожидать другие параметры.

Типичные ошибки конфигурации:

  • Неверный путь к CNI-плагинам. Параметр cniBinDir должен указывать на директорию с бинарными файлами CNI. Значение по умолчанию: /opt/cni/bin.
  • Устаревшие флаги. Флаги --network-plugin и --network-plugin-dir удалены в новых версиях. Их наличие вызывает ошибку unknown flag.
  • Неверный endpoint CRI. Параметр containerRuntimeEndpoint должен указывать на сокет вашего контейнерного рантайма. Для containerd: unix:///run/containerd/containerd.sock.

Проверьте конфигурацию на синтаксические ошибки:

kubelet --config=/var/lib/kubelet/config.yaml --dry-run

Команда выведет предупреждения о неизвестных полях или неверных значениях. Исправьте ошибки в файле и перезапустите kubelet:

systemctl restart kubelet

Решение проблем с сертификатами kubelet

Сертификаты kubelet используются для аутентификации на API-сервере. После обновления срок действия сертификата может истечь, или CA-сертификат может измениться.

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

openssl x509 -in /var/lib/kubelet/pki/kubelet.crt -noout -dates

Если сертификат просрочен, в логах появится запись certificate has expired.

Проверьте соответствие сертификата kubelet и CA:

openssl verify -CAfile /etc/kubernetes/pki/ca.crt /var/lib/kubelet/pki/kubelet.crt

Ошибка certificate signed by unknown authority означает, что сертификат kubelet подписан другим CA. Это случается при переносе узла между кластерами или ручной замене сертификатов.

Для обновления сертификатов kubelet используйте kubeadm:

kubeadm certs renew kubelet

Команда перегенерирует сертификаты kubelet на узле. После обновления перезапустите kubelet:

systemctl restart kubelet

Если kubeadm недоступен, удалите старые сертификаты и перезапустите kubelet. Kubelet автоматически сгенерирует новый сертификат и отправит запрос на подпись в API-сервер. Этот метод работает, если включён контроллер csrapproving.

Разрешение конфликтов CNI: Calico и Flannel

В кластере Kubernetes должен работать один сетевой плагин. Два плагина одновременно создают конфликтующие сетевые интерфейсы и правила маршрутизации. Поды зависают в статусе ContainerCreating, сетевые политики не применяются, сервисы недоступны.

Проверьте, какие CNI-плагины установлены:

kubectl get pods -n kube-system | grep -E "calico|flannel"

Наличие подов обоих плагинов - прямой признак конфликта. Даже если один из плагинов не активен, его конфигурационные файлы в /etc/cni/net.d/ могут мешать работе другого.

Диагностика конфликта CNI-плагинов

Анализируйте логи kubelet на предмет ошибок CNI:

journalctl -u kubelet | grep -i cni

Записи cni plugin not initialized, failed to find plugin или conflicting network configuration указывают на проблему.

Проверьте директорию конфигурации CNI:

ls -la /etc/cni/net.d/

Наличие файлов 10-calico.conflist и 10-flannel.conflist одновременно - причина конфликта. Kubelet читает все файлы в этой директории и пытается применить каждый.

Проверьте сетевые интерфейсы на узле:

ip a

Интерфейсы cali* принадлежат Calico, flannel.* - Flannel. Одновременное присутствие интерфейсов обоих типов подтверждает конфликт.

Удаление и переустановка CNI-плагина

Определите, какой плагин вы хотите оставить. Calico обеспечивает сетевые политики и высокую производительность. Flannel проще в настройке и подходит для небольших кластеров.

Удаление Calico:

kubectl delete -f calico.yaml
rm -f /etc/cni/net.d/10-calico.conflist

Удаление Flannel:

kubectl delete -f kube-flannel.yml
rm -f /etc/cni/net.d/10-flannel.conflist

Очистите сетевые интерфейсы удалённого плагина на каждом узле. Для Calico:

ip link delete caliXXXX

Для Flannel:

ip link delete flannel.1

Перезапустите kubelet на всех узлах:

systemctl restart kubelet

Установите выбранный плагин заново. Для Calico:

kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.28/manifests/calico.yaml

Для Flannel:

kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

Проверьте, что поды CNI запустились:

kubectl get pods -n kube-system | grep -E "calico|flannel"

Проверьте сетевую связность тестовым подом:

kubectl run test --image=busybox --rm -it --restart=Never -- ping 8.8.8.8

Если вы управляете кластером с Windows-нодами, учтите ограничения CNI-плагинов для Windows. В статье Обновление Kubernetes с Windows-нодами разобраны специфические параметры конфигурации Kubelet и ContainerD для смешанных кластеров.

Шпаргалка: ключевые команды для диагностики обновления kubeadm

Сводка команд для быстрого копирования. Сгруппированы по компонентам.

Компонент Команда Назначение
Общее состояние kubectl get nodes Статус узлов
Общее состояние kubectl get pods -n kube-system Состояние системных подов
Общее состояние kubectl describe node <node-name> Детализация проблем узла
Kubelet journalctl -u kubelet --since "1 hour ago" Логи kubelet за период
Kubelet journalctl -u kubelet -f Логи kubelet в реальном времени
Kubelet systemctl status kubelet Статус службы kubelet
Контейнеры crictl ps -a Все контейнеры, включая остановленные
Контейнеры crictl logs <container-id> Логи конкретного контейнера
Etcd etcdctl member list Список членов кластера etcd
Etcd etcdctl endpoint status Статус и версии членов etcd
Etcd etcdctl version Версия etcd
Сертификаты openssl x509 -in /var/lib/kubelet/pki/kubelet.crt -noout -dates Срок действия сертификата kubelet
Сертификаты kubeadm certs renew kubelet Обновление сертификатов kubelet
CNI ls -la /etc/cni/net.d/ Конфигурационные файлы CNI
CNI kubectl get pods -n kube-system | grep -E "calico|flannel" Обнаружение CNI-плагинов

Профилактика: как избежать ошибок при следующем обновлении

Предотвращение проблем экономит часы восстановления. Пять обязательных шагов перед каждым обновлением kubeadm.

1. Бэкап etcd. Полный бэкап состояния кластера - страховка от любых сбоев. Выполните перед обновлением:

etcdctl snapshot save /backup/etcd-$(date +%Y%m%d).db

Храните бэкап вне кластера. При отказе etcd восстановление из снапшота - единственный способ вернуть состояние без потерь.

2. Проверка совместимости версий. Kubeadm имеет встроенную проверку:

kubeadm upgrade plan

Вывод покажет доступные версии и предупреждения о несовместимости. Не пропускайте минорные версии. Обновление 1.28 → 1.30 требует промежуточного шага 1.29.

3. Правильный порядок обновления. Последовательность: kubeadm, kubelet, kubectl. Сначала обновите kubeadm на мастер-узле, выполните kubeadm upgrade apply, затем обновите kubelet и kubectl. На worker-узлах используйте kubeadm upgrade node.

4. Тестирование на staging-среде. Воспроизведите конфигурацию продуктивного кластера в изолированном окружении. Выполните обновление, проверьте работу приложений, сетевую связность и доступность сервисов. Это выявит проблемы до того, как они затронут пользователей.

5. Мониторинг анонсов CNI-плагинов. Calico и Flannel выпускают версии, совместимые с конкретными версиями Kubernetes. Перед обновлением кластера проверьте матрицу совместимости вашего CNI-плагина. Установите версию плагина, которая поддерживает целевую версию Kubernetes.

Для настройки автоматического восстановления после сбоев используйте Pod Disruption Budget и probes. В статье Типичные проблемы с инфраструктурным кодом на мероприятиях описаны практические чек-листы и методы профилактики, применимые к плановым обновлениям.

Если ваш кластер развёрнут в облаке, рассмотрите использование управляемых сервисов. Timeweb Cloud предоставляет облачную инфраструктуру с поддержкой Kubernetes, что снимает часть задач по обслуживанию control plane.

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