Источник Команда Kubernetes as a Service в Mail.ru Cloud Solutions перевела статью, в которой автор помогает найти причины ошибок в Kubernetes, если вы совсем не понимаете, куда нужно смотреть. Далее текст от лица автора. Kubernetes — непростая платформа, особенно когда что-то пошло не так и нужно срочно найти и устранить возникшую проблему. В основном трудности объясняются сложностью самой системы и отсутствием подробных сообщений об ошибках. Ситуация усугубляется еще и огромным количеством «шестеренок» в потоке оркестрации контейнеров — при том что для представления этого потока используется всего лишь несколько состояний. Например, есть как минимум шесть возможных причин, по которым под может зависнуть в состоянии ContainerCreating или CrashLoppBackOff. Мы активно работаем с Kubernetes уже более трех лет и за это время составили длинный список сложных и в то же время трудно диагностируемых проблем. Большинство из них можно отнести к одной из трех категорий: Причины этих сбоев могут быть совершенно разными, и в этой статье мы поможем вам понять, что происходит и почему. Мы не ставим перед собой цель выдать вам список команд и узкоспециализированных инструментов на все случаи жизни. Скорее, мы хотели бы расширить ваше понимание и помочь развить интуицию, на которую вы в дальнейшем сможете опираться, если Kubernetes будет работать не так, как надо. Когда что-то идет не так, в первую очередь нужно заглянуть в лог Kubernetes (kubectl get events -n <NAMESPACE>). В нем подробно записаны все шаги оркестрации, а это самое главное в любой диагностике. Ключ к пониманию ContainerCreating (как, впрочем, и любого другого состояния пода) — это четкое представление, где именно он находится в оркестрации Kubernetes. Эта информация поможет нам определить и исключить другие компоненты стека.  Например, ContainerCreating подразумевает, что kube-scheduler назначил контейнеру рабочий узел и дал демону Docker инструкцию запустить рабочую нагрузку, но на этом этапе еще не выделены сетевые ресурсы — то есть у рабочей нагрузки нет IP-адреса. Давайте рассмотрим некоторые типовые причины, вызывающие зависание пода на этапе ContainerCreating: KubeControlPlane запрашивает IP-адрес у CNI (например, Calico), а если выделить IP-адрес не удается, ControlPlane просто ждет до бесконечности. При этом «на поверхности» в журнале нет ни ошибок, ни трассировки, и команда kubectl тоже не выдает никакой информации. Эта проблема фиксируется только в логах kubelet/system. Причины: Configmaps содержат файлы, которые монтируются в (виртуализированную) файловую систему контейнера в среде исполнения. Этот этап оркестрации фиксируется в логах. Причины: Контейнеры, хранящие данные о состоянии, например, базы данных или платформы обмена сообщениями, тоже могут застрять на этапе ContainerCreating, если им не удается смонтировать PersistentVolume через PersistentVolumeClaim. Эта ситуация регистрируется в журналах событий; более подробную информацию можно найти в системных логах. Причины: Ошибка CrashLoopBackOff часто объясняется сбоями в коде контейнера или в самой программе. Это происходит, когда после запуска в контейнере команда entrypoint завершается с ошибкой. Причин у такой ошибки может быть множество, но прежде всего следует обратить внимание на следующие: Помимо программных ошибок в самом контейнере, к сбою запуска могут привести и внешние сбои при вводе переменных среды, параметры монтирования, секреты или обращение к другим объектам Kubernetes. Если контейнер превышает лимиты памяти, установленные для пода, Kubernetes подает сигнал о прерывании выполняющегося процесса. Если такое случается часто, скорее всего, количество перезапусков пода будет возрастать. К сбою контейнера на узле может привести нехватка места для хранения в двух местах: Механизм проверки работоспособности (liveness probe) в Kubernetes позволяет ControlPlane автоматически перезапускать вышедшие из строя контейнеры и таким образом восстанавливать работу. В то же время, если такие проверки проводятся слишком часто или просто настроены неправильно, без учета отложенных запусков восстановления, это может сказаться на стабильности работы: При высокой частоте liveness probe Kubernetes часто выполняет проверки. Но, например, если контейнер находится в середине критического события GC (в случае Java), скорее всего, проверка работоспособности покажет отрицательный результат — и все закончится перезагрузкой контейнера. Измененный/отсроченный запуск при восстановлении: иногда время запуска контейнера увеличивается из-за попыток исправить сбои, возникшие в результате аварийного завершения. Это часто видно по stateful-приложениям, которые запускают процедуры восстановления, чтобы справиться с разными неисправностями вроде поврежденной файловой системы. Так что если в настройках проверки работоспособности для этого недостаточно люфта, контейнер может застрять в цикле бесконечных перезапусков. Программно-определяемая сеть Kubernetes — сама по себе вещь достаточно сложная, а поиск и устранение проблем в ее сетевых настройках и вовсе отдельный квест. Например, проблемы с подключением в кластере может создать сбой одного компонента, особенно в сетевом стеке. В конечном счете вам придется искать проблему в разных местах. Так что в этой ситуации имеет смысл начать со стратегических точек и постепенно сужать круг поиска. Если перед вами встает задача отладить работу внутренней сети Kubernetes, разумно сосредоточиться прежде всего на следующих областях. Основное назначение kube-proxy — установить связь между Service IP и конечными точками его бэкэнда (Pod IP). Так что если ваш под находится на узле, который не может подключиться к service IP и при этом система выводит сообщения об ошибках «тайм-аут подключения» или «в подключении отказано», то в большинстве случаев проблему можно решить, просто перезапустив kube-proxy. Ведь, как и с любой другой рабочей нагрузкой, ваш контейнер kube-proxy мог просто выйти из строя на этом узле. Таблица IP-адресов — это ключевой компонент маршрутизации трафика между сервисами (service) и подами, включая связь через NodePorts. Kube-proxy использует таблицу IP-адресов для настройки правил, которые помогают балансировать и маскировать нагрузку. Так что если поды могут связываться с IP-адресами других подов, но не с Service IP, то ответ на вопрос можно найти именно в таблице IP-адресов. Первое, на что нужно смотреть в случае проблем с разрешением имен, это внутренние настройки DNS в кластере Kubernetes (служба DNS по умолчанию — kubedns). Убедитесь, что служба доступна через IP-адрес кластера или пода. Во-вторых, проверьте, содержит ли resolv.conf в ваших подах и рабочих узлах необходимые домены DNS и сервер доменных имен для поиска. Проблемы в Conntrack могут привести к обрыву связи или несоответствиям в сетевом трафике. Вкратце: с помощью conntrack ядро Linux поддерживает состояния связи и логические потоки в системе. То есть, скажем, если ваше приложение использует внешний IP, к которому выполняются миллионы подключений, то состояние этих подключений и логические потоки отслеживаются в таблице ядра conntrack. Само собой, для таких таблиц conntrack установлены жесткие лимиты, и в случае превышения в сети начинаются неполадки. В RHEL лимиты подключения conntrack можно проверить следующим образом: Когда ваш daemonset CNI (например, Calico) выходит из строя на любом узле, это приводит к сбою маршрутизации и сетевого подключения в кластере Kubernetes, часто только на узлах, в которых случился сбой. По аналогии с kube-proxy проблему может решить перезапуск контейнера Calico на этом узле или контроллера Calico. Поды CNI подвержены сбоям так же, как и любые другие рабочие нагрузки в кластере. Kubernetes — это сложная платформа, и устранение ее неисправностей — задача нетривиальная. Например, к одному зависшему состоянию ContainerCreating могут привести совершенно разные причины, от сбоя при распределении IP-адресов до проблем с монтированием диска. Прежде всего, эти сложности объясняются большим количеством динамических компонентов платформы и разнообразием взаимосвязей между ними. Мы рассмотрели три категории неисправностей и несколько проблем, которые стоят за ними: Мы ненадолго заглянули на внутреннюю кухню Kubernetes и сделали первые шаги на пути к развитию интуиции, которая подскажет вам, где искать причину неисправностей, которые случаются здесь не так уж редко. Что еще почитать: ИТ-переводчик