Диагностика состояния кластера после сбоя обновления
Обновление кластера 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-сервера.
Варианты решения:
- Понижение версии на обновлённом узле. Остановите etcd, замените бинарный файл на предыдущую версию, запустите etcd. Этот способ требует, чтобы формат данных был обратно совместим. Проверьте документацию etcd к вашей версии.
- Принудительное обновление остальных узлов. Если формат данных изменился и обратная совместимость не поддерживается, обновите 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.