Источник


Команда Kubernetes as a Service в Mail.ru Cloud Solutions перевела статью, в которой автор помогает найти причины ошибок в Kubernetes, если вы совсем не понимаете, куда нужно смотреть. Далее текст от лица автора.


Kubernetes — непростая платформа, особенно когда что-то пошло не так и нужно срочно найти и устранить возникшую проблему. В основном трудности объясняются сложностью самой системы и отсутствием подробных сообщений об ошибках. Ситуация усугубляется еще и огромным количеством «шестеренок» в потоке оркестрации контейнеров — при том что для представления этого потока используется всего лишь несколько состояний. Например, есть как минимум шесть возможных причин, по которым под может зависнуть в состоянии ContainerCreating или CrashLoppBackOff.


Мы активно работаем с Kubernetes уже более трех лет и за это время составили длинный список сложных и в то же время трудно диагностируемых проблем. Большинство из них можно отнести к одной из трех категорий:


  1. Зависание пода в состоянии ContainerCreating.
  2. Ошибка CrashLoopBackOff и периодический перезапуск контейнера.
  3. Проблемы с сетью.

Причины этих сбоев могут быть совершенно разными, и в этой статье мы поможем вам понять, что происходит и почему. Мы не ставим перед собой цель выдать вам список команд и узкоспециализированных инструментов на все случаи жизни. Скорее, мы хотели бы расширить ваше понимание и помочь развить интуицию, на которую вы в дальнейшем сможете опираться, если Kubernetes будет работать не так, как надо.


Когда что-то идет не так, в первую очередь нужно заглянуть в лог Kubernetes (kubectl get events -n <NAMESPACE>). В нем подробно записаны все шаги оркестрации, а это самое главное в любой диагностике.


1. Поды зависают в состоянии ContainerCreating


Ключ к пониманию ContainerCreating (как, впрочем, и любого другого состояния пода) — это четкое представление, где именно он находится в оркестрации Kubernetes. Эта информация поможет нам определить и исключить другие компоненты стека.


Например, ContainerCreating подразумевает, что kube-scheduler назначил контейнеру рабочий узел и дал демону Docker инструкцию запустить рабочую нагрузку, но на этом этапе еще не выделены сетевые ресурсы — то есть у рабочей нагрузки нет IP-адреса.


Давайте рассмотрим некоторые типовые причины, вызывающие зависание пода на этапе ContainerCreating:


1.1 Сбой при выделении IP-адреса


KubeControlPlane запрашивает IP-адрес у CNI (например, Calico), а если выделить IP-адрес не удается, ControlPlane просто ждет до бесконечности. При этом «на поверхности» в журнале нет ни ошибок, ни трассировки, и команда kubectl тоже не выдает никакой информации. Эта проблема фиксируется только в логах kubelet/system.


Причины:


  1. Нехватка IP-адресов в IPPool, настроенном в вашем CNI.
  2. Ошибки связи между kubelet и CNI.
  3. Ошибки конфигурации в CNI.

1.2 Ошибка монтирования Configmap


Configmaps содержат файлы, которые монтируются в (виртуализированную) файловую систему контейнера в среде исполнения. Этот этап оркестрации фиксируется в логах.


Причины:


  1. /var/lib/docker на узле переполнен: из-за этого демон Docker на узле не может работать нормально.
  2. Ошибки или опечатки в имени Configmap, на который ссылается деплоймент пода.

1.3 Сбой при запросе Persistent Volumes


Контейнеры, хранящие данные о состоянии, например, базы данных или платформы обмена сообщениями, тоже могут застрять на этапе ContainerCreating, если им не удается смонтировать PersistentVolume через PersistentVolumeClaim. Эта ситуация регистрируется в журналах событий; более подробную информацию можно найти в системных логах.


Причины:


  1. Ошибка связи между плагином Kubernetes CSI и облачным провайдером.
  2. ControlPlane выполняет процедуры attach и detach для перемещения дисков, когда рабочие нагрузки проходят через узлы в кластере. И иногда этот процесс занимает больше времени, чем обычно, из-за тайм-аутов при выполнении операций mount и umount.

2. CrashLoopBackOff и периодические перезапуски


Ошибка CrashLoopBackOff часто объясняется сбоями в коде контейнера или в самой программе. Это происходит, когда после запуска в контейнере команда entrypoint завершается с ошибкой. Причин у такой ошибки может быть множество, но прежде всего следует обратить внимание на следующие:


2.1 Ошибки в скрипте Startup или InitContainers


Помимо программных ошибок в самом контейнере, к сбою запуска могут привести и внешние сбои при вводе переменных среды, параметры монтирования, секреты или обращение к другим объектам Kubernetes.


2.2 Превышение лимитов памяти


Если контейнер превышает лимиты памяти, установленные для пода, Kubernetes подает сигнал о прерывании выполняющегося процесса. Если такое случается часто, скорее всего, количество перезапусков пода будет возрастать.


2.3 Нехватка места на диске или в хранилище


К сбою контейнера на узле может привести нехватка места для хранения в двух местах:


  1. PersistentVolume самого пода, который влияет на процессы контейнера.
  2. /var/lib/docker (OverlayFS Docker) на рабочем узле, на котором запланирован под.

2.4 Проверка работоспособности


Механизм проверки работоспособности (liveness probe) в Kubernetes позволяет ControlPlane автоматически перезапускать вышедшие из строя контейнеры и таким образом восстанавливать работу. В то же время, если такие проверки проводятся слишком часто или просто настроены неправильно, без учета отложенных запусков восстановления, это может сказаться на стабильности работы:


  1. При высокой частоте liveness probe Kubernetes часто выполняет проверки. Но, например, если контейнер находится в середине критического события GC (в случае Java), скорее всего, проверка работоспособности покажет отрицательный результат — и все закончится перезагрузкой контейнера.


  2. Измененный/отсроченный запуск при восстановлении: иногда время запуска контейнера увеличивается из-за попыток исправить сбои, возникшие в результате аварийного завершения. Это часто видно по stateful-приложениям, которые запускают процедуры восстановления, чтобы справиться с разными неисправностями вроде поврежденной файловой системы. Так что если в настройках проверки работоспособности для этого недостаточно люфта, контейнер может застрять в цикле бесконечных перезапусков.



3. Проблемы с сетью


Программно-определяемая сеть Kubernetes — сама по себе вещь достаточно сложная, а поиск и устранение проблем в ее сетевых настройках и вовсе отдельный квест. Например, проблемы с подключением в кластере может создать сбой одного компонента, особенно в сетевом стеке. В конечном счете вам придется искать проблему в разных местах. Так что в этой ситуации имеет смысл начать со стратегических точек и постепенно сужать круг поиска.


Если перед вами встает задача отладить работу внутренней сети Kubernetes, разумно сосредоточиться прежде всего на следующих областях.


3.1 Kube-proxy и таблицы IP-адресов


Основное назначение kube-proxy — установить связь между Service IP и конечными точками его бэкэнда (Pod IP). Так что если ваш под находится на узле, который не может подключиться к service IP и при этом система выводит сообщения об ошибках «тайм-аут подключения» или «в подключении отказано», то в большинстве случаев проблему можно решить, просто перезапустив kube-proxy. Ведь, как и с любой другой рабочей нагрузкой, ваш контейнер kube-proxy мог просто выйти из строя на этом узле.


Таблица IP-адресов — это ключевой компонент маршрутизации трафика между сервисами (service) и подами, включая связь через NodePorts. Kube-proxy использует таблицу IP-адресов для настройки правил, которые помогают балансировать и маскировать нагрузку. Так что если поды могут связываться с IP-адресами других подов, но не с Service IP, то ответ на вопрос можно найти именно в таблице IP-адресов.


3.2 Kube-DNS


Первое, на что нужно смотреть в случае проблем с разрешением имен, это внутренние настройки DNS в кластере Kubernetes (служба DNS по умолчанию — kubedns). Убедитесь, что служба доступна через IP-адрес кластера или пода.


Во-вторых, проверьте, содержит ли resolv.conf в ваших подах и рабочих узлах необходимые домены DNS и сервер доменных имен для поиска.


3.3 Conntrack


Проблемы в Conntrack могут привести к обрыву связи или несоответствиям в сетевом трафике. Вкратце: с помощью conntrack ядро Linux поддерживает состояния связи и логические потоки в системе. То есть, скажем, если ваше приложение использует внешний IP, к которому выполняются миллионы подключений, то состояние этих подключений и логические потоки отслеживаются в таблице ядра conntrack. Само собой, для таких таблиц conntrack установлены жесткие лимиты, и в случае превышения в сети начинаются неполадки.


В RHEL лимиты подключения conntrack можно проверить следующим образом:


$  sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_maxnet.netfilter.nf_conntrack_count = 167012

net.netfilter.nf_conntrack_max = 262144

3.5 CNI и таблица маршрутизации


Когда ваш daemonset CNI (например, Calico) выходит из строя на любом узле, это приводит к сбою маршрутизации и сетевого подключения в кластере Kubernetes, часто только на узлах, в которых случился сбой.


По аналогии с kube-proxy проблему может решить перезапуск контейнера Calico на этом узле или контроллера Calico. Поды CNI подвержены сбоям так же, как и любые другие рабочие нагрузки в кластере.


Заключение


Kubernetes — это сложная платформа, и устранение ее неисправностей — задача нетривиальная. Например, к одному зависшему состоянию ContainerCreating могут привести совершенно разные причины, от сбоя при распределении IP-адресов до проблем с монтированием диска. Прежде всего, эти сложности объясняются большим количеством динамических компонентов платформы и разнообразием взаимосвязей между ними.


Мы рассмотрели три категории неисправностей и несколько проблем, которые стоят за ними:


  1. Зависание подов в состоянии ContainerCreating.
  2. Ошибка CrashLoopBackOff и периодический перезапуск контейнера.
  3. Проблемы с сетью.

Мы ненадолго заглянули на внутреннюю кухню Kubernetes и сделали первые шаги на пути к развитию интуиции, которая подскажет вам, где искать причину неисправностей, которые случаются здесь не так уж редко.


На платформе Mail.ru Cloud Solutions вы можете подключить Kubernetes as a Service. Новые пользователи при регистрации получают 3000 бонусных рублей, которые можно потратить на тестирование и ознакомление с платформой.

А в этой статье мы рассказываем, как устроен наш Kubernetes aaS, что у него под капотом и какие есть дополнительные функции.

Что еще почитать:


  1. Деплоим проект на Kubernetes в Mail.ru Cloud Solutions. Часть 1.
  2. Как работать с Big Data быстрее и эффективнее: Kubernetes для Data Science.
  3. Телеграм-канал Вокруг Kubernetes.

Комментарии (0)