в каком направлении двигаться, если что-то идет не так / Блог компании Mail.ru Group / Хабр

Источник

Команда 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.

Source link

Добавить комментарий

Ваш адрес email не будет опубликован.