что такое pod kubernetes
Знакомство с Kubernetes. Часть 3: Поды (Pods)
May 14, 2018 06:17 · 776 words · 4 minute read kubernetes pod
Чаще всего в Pod’ ах используются docker-контейнеры (что и не удивительно), но можно использовать и другие контейнеры (например, rkt от CoreOS).
Важно Kubernetes управляет Pod’ ами, а не контейнерами напрямую.
В кластере Kubernetes Pod’ ы используются двумя способами:
Pod’ ы спроектированы для поддержки множества взаимодействующих процессов (например, контейнеров), которые образуют отдельный сервис (единицу обслуживания). Контейнеры внутри Pod’ а автоматически размещаются и управляются на одной и той же физической (или виртуальной) ноде кластера. Контейнеры в Pod’ е могут совместно использовать ресурсы и зависимости, взаимодействовать друг с другом и определять, когда и как они будут завершаться.
К слову, группировка и запуск нескольких контейнеров в Pod’ е считается “продвинутым” вариантом использования, и применять этот шаблон нужно только при реальной необходимости. Например, у вас может быть контейнер с web-сервером, использующий файлы из общего (относительно Pod’ а) хранилища, и отдельный контейнер, который обновляет эти файлы из удаленного источника.
Pod’ ы предоставляют запущенным внутри контейнерам два типа общих ресурсов: сеть и хранилище.
Сеть
Каждому Pod’ у присваивается уникальный IP-адрес. Внутри Pod’ а каждый контейнер использует общее пространство имен (namespace) сети, включая IP-адрес и сетевые порты. Между собой внутри Pod’ а контейнеры взаимодействуют через localhost. При взаимодействии с объектами, находящимися за пределами Pod’ а, контейнеры “договариваются” между собой и координируют использование общих сетевых ресурсов (таких как порты).
Хранилище
Pod может определить набор общих томов (volumes) для хранения данных. Контейнеры внутри Pod’ а могут работать с этими томами и, таким образом, обмениваться данными между собой. Благодаря использованию томов, можно сохранить данные, если один из контейнеров Pod’ а (которому нужны эти данные для корректной работы) должен быть перезапущен. Время жизни томов совпадает с временем жизни самого Pod’ а.
Примечание Перезапуск контейнера внутри Pod’ а не следует путать с перезапуском самого Pod’ а.
Предложенный манифест (спецификацию) можно сохранить в файле single-example-pod.yml и запустить Pod с помощью утилиты командной строки kubectl :
Сети Kubernetes: поды
Материал, перевод которого мы сегодня публикуем, посвящён особенностям сетевого взаимодействия подов Kubernetes. Он предназначен для тех, у кого уже есть некоторый опыт работы с Kubernetes. Если вы пока не очень хорошо разбираетесь в Kubernetes, то вам, вероятно, прежде чем читать этот материал, полезно будет взглянуть на это руководство по Kubernetes, где работа с данной платформой рассматривается в расчёте на начинающих.
Контейнер Docker, запущенный на локальной машине
Два контейнера Docker, запущенные на локальной машине
Всё это хорошо, но это не описывает пока то, что мы, в применении к подам Kubernetes, называем «разделяемым сетевым стеком». К счастью, пространства имён отличаются большой гибкостью. Docker может запустить контейнер, и, вместо того, чтобы создавать для него новый виртуальный сетевой интерфейс, сделать так, чтобы он использовал бы, совместно с другими контейнерами, существующий интерфейс. При таком подходе нам придётся изменить вышеприведённую схему так, как показано ниже.
Контейнеры используют общий сетевой интерфейс
Контейнеры в гипотетическом поде
Сеть подов
Один под, полный контейнеров, это строительный блок некоей системы, но пока ещё не сама эта система. В основе архитектуры Kubernetes лежит требование, в соответствии с которым у подов должна быть возможность взаимодействовать с другими подами вне зависимости от того, выполняются ли они на одном и том же компьютере или на разных машинах. Для того чтобы узнать о том, как всё это устроено, нам нужно перейти на более высокий уровень абстракции и поговорить о том, как в кластере Kubernetes работают узлы. Здесь мы затронем тему сетевой маршрутизации и маршрутов. Данной темы в материалах, подобных этому, нередко избегают, считая её слишком сложной. Непросто найти понятное и не слишком длинное руководство по IP-маршрутизации, но если вам хочется взглянуть на краткий обзор этой проблемы — можете взглянуть на этот материал.
Кластер Kubernetes состоит из одного узла или из большего количества узлов. Узел — это хост-система, физическая или виртуальная, которая содержит разные программные средства и их зависимости (речь идёт, в основном, о Docker), а также несколько системных компонентов Kubernetes. Узел подключён к сети, что позволяет ему обмениваться данными с другими узлами кластера. Вот как может выглядеть простой кластер, состоящий из двух узлов.
Простой кластер, состоящий из двух узлов
В целом же можно отметить, что вам, обычно, не придётся размышлять о том, как именно работает сеть подов. Когда под обменивается данными с другим подом, чаще всего это происходит посредством сервисов Kubernetes. Это — нечто вроде программно определяемых прокси. Но сетевые адреса подов появляются в логах. В некоторых ситуациях, в частности, при отладке, вам может понадобиться явным образом задавать правила маршрутизации в сетях подов. Например, трафик, покидающий под Kubernetes, привязанный к любому адресу в диапазоне 10.0.0.0/8, не обрабатывается по умолчанию с помощью NAT. Поэтому если вы взаимодействуете с сервисами, находящимися в другой частной сети, имеющей тот же диапазон адресов, вам может понадобиться настроить правила маршрутизации, которые позволят организовать правильную доставку пакетов.
Итоги
Сегодня мы поговорили о подах Kubernetes и об особенностях их сетевого взаимодействия. Надеемся, этот материал поможет вам сделать правильные шаги в направлении реализации сложных сценариев взаимодействия подов в сетях Kubernetes.
Уважаемые читатели! Эта статья является первым материалом цикла, посвящённого сетям Kubernetes. Вторая часть этого цикла уже переведена. Мы размышляем о том, нужно ли переводить третью часть. Просим вас высказаться об этом в комментариях.
Так что же такое pod в Kubernetes?
Прим. перев.: Эта статья продолжает цикл материалов от технического писателя из Google, работающего над документацией для Kubernetes (Andrew Chen), и директора по software engineering из SAP (Dominik Tornow). Их цель — доступно и наглядно объяснить основы организации Kubernetes. В прошлый раз мы переводили статью про high availability, а теперь речь пойдет про такое базовое понятие в Kubernetes, как pod.
Kubernetes — движок оркестровки контейнеров, созданный для запуска контейнеризированных приложений на множестве узлов, которые обычно называют кластером. В этих публикациях мы используем подход системного моделирования с целью улучшить понимание Kubernetes и его нижележащих концепций. Читающим рекомендуется уже иметь базовое представление о Kubernetes.
Pods (Поды) — базовые строительные блоки Kubernetes, однако даже опытные пользователи Kubernetes не всегда могут объяснить, что же это такое.
Данная публикация предлагает лаконичную мысленную модель, которая проливает свет на определяющие характеристики pod’ов Kubernetes. Ради этой краткости пришлось опустить некоторые другие особенности Pod’ов, такие как liveness и readiness probes, разделение ресурсов (включая появившееся недавно namespace sharing — прим. перев.), работу с сетью.
Определение
Pod представляет собой запрос на запуск одного или более контейнеров на одном узле.
Pod определяется представлением запроса на запуск (execute) одного или более контейнеров на одном узле, и эти контейнеры разделяют доступ к таким ресурсам, как тома хранилища и сетевой стек.
Однако в обиходе термин «pod» может употребляться и в смысле этого запроса, и в смысле совокупности контейнеров, которые запускаются в ответ на запрос. Поэтому в публикации мы будем использовать слово «pod», когда говорим о запросе, а для второго случая — употреблять выражение «набор контейнеров».
Pod’ы считаются базовыми строительными блоками Kubernetes, потому что все рабочие нагрузки в Kubernetes — например, Deployments, ReplicaSets и Jobs — могут быть выражены в виде pod’ов.
Pod — это один и единственный объект в Kubernetes, который приводит к запуску контейнеров. Нет pod’а — нет контейнера!
Схема 1. Deployment, ReplicaSet, pod и контейнеры
Архитектура Kubernetes
Схема 2. Pod’ы, планировщик (Scheduler) и Kubelet
На этой иллюстрации выделены соответствующие объекты и компоненты. Pod’ы представлены как Kubernetes Pod Objects, а работой с ними занимаются:
Объекты Kubernetes
Схема 3. Объекты Kubernetes
На этой иллюстрации показаны объекты Kubernetes, ответственные за работу с pod’ом:
Binding Object привязывает Pod Object к Node Object, т.е. назначает pod на узел для последующего запуска.
Node Object представляет узел в кластере Kubernetes.
Обработка pod’а
Схема 4. Обработка pod’а
Когда pod создан пользователем или контроллером вроде ReplicaSet Controller или Job Controller, Kubernetes обрабатывает pod в два этапа:
Планирование pod’а
Схема 5. Управляющий цикл планировщика Kubernetes
Задача планировщика (Scheduler) в Kubernetes — запланировать pod, то есть назначить ему подходящий узел в кластере Kubernetes для последующего запуска.
Связывание объекта pod’а с объектом узла
Pod назначается узлу (или связывается с ним) тогда и только тогда, когда есть объект связывания (binding), у которого:
Запуск pod’а
Схема 6. Управляющий цикл Kubelet
Задача Kubelet — запустить pod, что по сути означает запуск набора контейнеров pod’а. Запуск pod’а Kubelet’ом происходит в две фазы: инициализацию и основную стадию.
Как правило, набор контейнеров на фазе инициализации осуществляет подготовительные работы, такие как подготовку необходимой структуры директорий и файлов. А набор контейнеров на основной фазе выполняет уже «самые главные» задачи.
В обиходе же, хотя это и не совсем корректно, термин «pod» зачастую подразумевает набор контейнеров на основной фазе или же ещё более узкое значение «самого главного» контейнера основной фазы.
Схема 7.1. Запуск pod’а, фаза инициализации (init) и основная фаза (main)
Схема 7.2. Запуск pod’а, подробности этого процесса
У политики рестарта pod’а различная семантика для init-контейнеров и основных контейнеров: если запуск init-контейнеров обязан привести к завершению, то основные контейнеры могут и не завершаться.
Политика рестарта для init-контейнера
Init-контейнер будет перезапущен (т.е. повлечёт за собой запуск нового контейнера с такой же спецификацией) при завершении своей работы только при выполнении следующих условий:
Основной контейнер будет перезапущен (т.е. повлечёт за собой запуск нового контейнера с такой же спецификацией) при завершении своей работы только при выполнении следующих условий:
На иллюстрации показана возможная временная шкала запуска pod’а с двумя спецификациями init-контейнеров и двумя спецификациями основных контейнеров. Также она показывает создание (в соответствии с политикой рестарта) нового контейнера Main Container 1.2 после проблемы с запуском Main Container 1.1.
Фазы pod’а
Схема 9. Взаимодействие Kubelet с объектом pod’а и исполняемой средой контейнера (container runtime)
Фаза pod’а — это проекция состояния контейнеров из набора контейнеров, она зависит от:
Ожидание (Pending)
Фаза Pending
Pod находится в фазе ожидания тогда и только тогда, когда:
Работает (Running)
Фаза Running
Pod находится в фазе работы тогда и только тогда, когда:
Успех (Success)
Фаза Success
Pod находится в фазе успеха тогда и только тогда, когда:
Отказ (Failure)
Фаза Failure
Pod находится в фазе отказа тогда и только тогда, когда:
Неизвестно (Unknown)
В дополнение к описанным выше фазам pod может находиться в неизвестной фазе, что свидетельствует о невозможности определить его текущую фазу.
Сбор мусора для pod’ов
Схема 11. Управляющий цикл сборщика мусора для pod’ов (Pod Garbage Collector)
После того, как pod был запланирован и запущен, специальный контроллер в Kubernetes — Pod Garbage Collector Controller — отвечает за удаление объектов pod’ов из хранилища объектов Kubernetes Object Store.
Заключение
Pod — базовый строительный блок Kubernetes: pod определяется как представление запроса на запуск одного или более контейнеров на одном узле. После того, как pod создан, Kubernetes обрабатывает его в два этапа: сначала планировщик (Scheduler) планирует pod, а затем — Kubelet запускает его. На протяжении своего жизненного цикла pod проходит через разные фазы, сообщая о состоянии — или, точнее говоря, о состоянии своего набора контейнеров — пользователю и системе.
Настройка Pod’ов и контейнеров
На этой странице рассказывается, как настраивать запрос памяти и её лимит для контейнеров. Контейнеру гарантируется столько памяти, сколько он запросит, но не больше установленных ограничений.
Подготовка к работе
Вам нужен Kubernetes кластер и инструмент командной строки kubectl должен быть настроен на связь с вашим кластером. Если у вас ещё нет кластера, вы можете создать, его используя Minikube, или вы можете использовать одну из песочниц Kubernetes:
Каждая нода вашего кластера должна располагать хотя бы 300 Мб памяти.
Некоторые операции на этой странице предполагают работу сервера метрик на вашем кластере. Если сервер метрик у вас уже запущен, следующие действия можно пропустить.
Если вы используете Minikube, выполните следующую команду, чтобы запустить сервер метрик:
Чтобы проверить работу сервера меток или другого провайдера API ресурсов метрик ( metrics.k8s.io ), запустите команду:
Создание пространства имён
Создадим пространство имён, чтобы ресурсы, которыми будем пользоваться в данном упражнении, были изолированы от остального кластера:
Установка запроса памяти и лимита памяти
В этом упражнении создаётся Pod, содержащий один контейнер. Зададим контейнеру запрос памяти в 100 Мб и её ограничение в 200 Мб. Конфигурационный файл для Pod’а:
Раздел args конфигурационного файла содержит аргументы для контейнера в момент старта. Аргументы «—vm-bytes», «150M» указывают контейнеру попытаться занять 150 Мб памяти.
Убедимся, что контейнер Pod’a запущен:
Посмотрим подробную информацию о Pod’е:
В выводе мы видим, что для контейнера в Pod’е зарезервировано 100 Мб памяти и выставлено 200 Мб ограничения.
Превышение контейнером лимита памяти
Контейнер может превысить величину запроса памяти, если нода имеет достаточно ресурсов памяти. Но превышение заданного ограничения памяти не допускается. Если контейнер запрашивает больше памяти, чем ему разрешено использовать, то он становится кандидатом на удаление. Если превышение лимита памяти продолжится, контейнер удаляется. Если удалённый контейнер может быть перезапущен, то kubelet перезапускает его, как и в случае любой другой неполадки в работе.
В этом упражнении создадим Pod, который попытается занять больше памяти, чем для него ограничено. Ниже представлен конфигурационный файл для Pod’a с одним контейнером, имеющим 50 Мб на запрос памяти и 100 Мб лимита памяти:
Посмотрим подробную информацию о Pod’е:
В этот момент контейнер уже либо запущен, либо убит. Будем повторять предыдущую команду, пока контейнер не окажется убитым:
Посмотрим ещё более подробный вид статуса контейнера:
В выводе показано, что контейнер был убит по причине недостатка памяти (OOM):
В данном упражнении контейнер может быть перезапущен, поэтому kubelet стартует его. Выполните следующую команду несколько раз, чтобы увидеть, как контейнер раз за разом убивается и запускается снова:
Вывод показывает, что контейнер убит, перезапущен, снова убит, перезапущен, и т.д.:
Посмотрим подробную информацию об истории Pod’a:
Вывод показывает, что контейнер постоянно запускается и падает:
Посмотрим детальную информацию о нодах на кластере:
В выводе содержится запись о том, что контейнер убивается по причине нехватки памяти:
Установка слишком большого для нод запроса памяти
Запросы и ограничения памяти связаны с контейнерами, но полезно также рассматривать эти параметры и для Pod’а. Запросом памяти для Pod’a будет сумма всех запросов памяти контейнеров, имеющихся в Pod’е. Также и лимитом памяти будет сумма всех ограничений, установленных для контейнеров.
Планирование Pod’a основано на запросах. Pod запускается на ноде лишь в случае, если нода может удовлетворить запрос памяти Pod’a.
В данном упражнении мы создадим Pod, чей запрос памяти будет превышать ёмкость любой ноды в кластере. Ниже представлен конфигурационный файл для Pod’a с одним контейнером, имеющим запрос памяти в 1000 Гб (что наверняка превышает ёмкость любой имеющейся ноды):
Проверим статус Pod’a:
Вывод показывает, что Pod имеет статус PENDING. Это значит, что он не запланирован ни на одной ноде, и такой статус будет сохраняться всё время:
Посмотрим подробную информацию о Pod’е, включающую события:
Вывод показывает невозможность запуска контейнера из-за нехватки памяти на нодах:
Единицы измерения памяти
Ресурсы памяти измеряются в байтах. Их можно задавать просто целым числом либо целым числом с одним из следующих окончаний: E, P, T, G, M, K, Ei, Pi, Ti, Gi, Mi, Ki. Например, представленные здесь варианты задают приблизительно одну и ту же величину:
Если лимит памяти не задан
Если вы не задали ограничение памяти для контейнера, возможны следующие варианты:
У контейнера отсутствует верхняя граница для памяти, которую он может использовать. Такой контейнер может занять всю память, доступную на ноде, где он запущен, что, в свою очередь, может вызвать OOM Killer. Также контейнеры без ограничений по ресурсам имеют более высокие шансы быть убитыми в случае вызова OOM Kill.
Контейнер запущен в пространстве имён, в котором настроена величина ограничений по умолчанию. Тогда контейнеру автоматически присваивается это стандартное значение лимита. Администраторы кластера могут использовать LimitRange для задания стандартной величины ограничений по памяти.
Мотивация для использования запросов и ограничений памяти
При помощи задания величины запросов и лимитов памяти для контейнеров, запущенных на вашем кластере, можно эффективно распоряжаться имеющимися на нодах ресурсами. Задание Pod’у небольшого запроса памяти даёт хорошие шансы для него быть запланированным. Ограничение памяти, превышающее величину запроса памяти, позволяет достичь 2 вещей:
Pod может иметь всплески активности, в течение которых ему может потребоваться дополнительная память.
Величина памяти, доступная Pod’у при повышении активности, ограничена некоторой разумной величиной.
Очистка
Удалим пространство имён. Эта операция удалит все Pod’ы, созданные в рамках данного упражнения:
Что дальше
Для разработчиков приложений
Для администраторов кластера
На этой странице показывается, как настроить запрос CPU и лимит CPU для контейнера. Контейнер не сможет использовать больше ресурсов CPU, чем для него ограничено. Если в системе есть свободное время CPU, контейнеру гарантируется выдача запрошенных им ресурсов CPU.
Подготовка к работе
Вам нужен Kubernetes кластер и инструмент командной строки kubectl должен быть настроен на связь с вашим кластером. Если у вас ещё нет кластера, вы можете создать, его используя Minikube, или вы можете использовать одну из песочниц Kubernetes:
На кластере должен быть хотя бы 1 доступный для работы CPU, чтобы запускать учебные примеры.
Для некоторых шагов с этой страницы понадобится запущенный сервер метрик на вашем кластере. Если сервер метрик уже запущен, следующие шаги можно пропустить.
Если вы используете Minikube, выполните следующую команду, чтобы запустить сервер метрик:
Проверим, работает ли сервер метрик (или другой провайдер API ресурсов метрик, metrics.k8s.io ), выполните команду:
Создание пространства имён
Создадим Namespace, чтобы создаваемые в этом упражнении ресурсы были изолированы от остального кластера.
Установка запроса CPU и лимита CPU
В этом упражнении мы создадим Pod, имеющий один контейнер. Зададим для контейнера запрос в 0.5 CPU и лимит в 1 CPU. Конфигурационный файл для такого Pod’а:
Удостоверимся, что Pod запущен:
Посмотрим детальную информацию о Pod’е:
В выводе видно, что Pod имеет один контейнер с запросом в 500 милли-CPU и с ограничением в 1 CPU.
В этом варианте вывода Pod’ом использовано 974 милли-CPU, что лишь чуть меньше заданного в конфигурации Pod’a ограничения в 1 CPU.
Единицы измерения CPU
Ресурсы CPU измеряются в CPU единицах. Один CPU, в Kubernetes, соответствует:
Дробные значения возможны. Контейнер, запрашивающий 0.5 CPU, получит вполовину меньше ресурсов, чем контейнер, запрашивающий 1 CPU. Можно использовать окончание m для обозначения милли. Например, 100m CPU, 100 milliCPU и 0.1 CPU обозначают одно и то же. Точность выше 1m не поддерживается.
CPU всегда запрашивается в абсолютных величинах, не в относительных; 0.1 будет одинаковой частью от CPU для одноядерного, двухъядерного или 48-ядерного процессора.
Запрос ресурсов CPU больше доступного на ноде
Планирование Pod’а основано на запросах. Pod попадает в расписание запуска на ноде лишь в случае достаточного количества доступных ресурсов CPU на ноде, чтобы удовлетворить запрос CPU Pod’а.
В этом упражнении мы создадим Pod с запросом CPU, превышающим мощности любой ноды в вашем кластере. Ниже представлен конфигурационный файл для Pod’а с одним контейнером. Контейнер запрашивает 100 CPU, что почти наверняка превышет имеющиеся мощности любой ноды в кластере.
Проверим статус Pod’а:
Вывод показывает Pending статус у Pod’а. То есть Pod не запланирован к запуску ни на одной ноде и будет оставаться в статусе Pending постоянно:
Посмотрим подробную информацию о Pod’е, включающую в себя события:
В выводе отражено, что контейнер не может быть запланирован из-за нехватки ресурсов CPU на нодах:
Если ограничения на CPU не заданы
Если ограничения на использование контейнером CPU не установлены, возможны следующие варианты:
У контейнера отсутствует верхняя граница количества CPU доступных ему ресурсов. В таком случае он может занять все ресурсы CPU, доступные на ноде, на которой он запущен.
Контейнер запущен в пространстве имён, в котором задана стандартная величина ограничения ресурсов CPU. Тогда контейнеру автоматически присваивается это ограничение. Администраторы кластера могут использовать LimitRange, чтобы задать стандартную величину ограничения ресурсов CPU.
Мотивация для использования запросов и лимитов CPU
Вы можете распоряжаться ресурсами CPU на нодах вашего кластера эффективнее, если для запущенных контейнеров установлены запросы и ограничения на использование ресурсов CPU. Задание небольшого запроса CPU даёт Pod’у хорошие шансы быть запланированным. Установка лимита на ресурсы CPU, большего, чем запрос, позволяет достичь 2 вещей:
Очистка
Удалим созданное для этого упражнения пространство имён:
Что дальше
Для разработчиков приложений
Для администраторов кластера
На этой странице рассказывается, как настроить liveness, readiness и startup пробы для контейнеров.
Kubelet использует liveness пробу для проверки, когда перезапустить контейнер. Например, liveness проба должна поймать блокировку, когда приложение запущено, но не может ничего сделать. В этом случае перезапуск приложения может помочь сделать приложение более доступным, несмотря на баги.
Kubelet использует readiness пробы, чтобы узнать, готов ли контейнер принимать траффик. Pod считается готовым, когда все его контейнеры готовы.
Kubelet использует startup пробы, чтобы понять, когда приложение в контейнере было запущено. Если проба настроена, он блокирует liveness и readiness проверки, до того как проба становится успешной, и проверяет, что эта проба не мешает запуску приложения. Это может быть использовано для проверки работоспособности медленно стартующих контейнеров, чтобы избежать убийства kubelet’ом прежде, чем они будут запущены.
Подготовка к работе
Вам нужен Kubernetes кластер и инструмент командной строки kubectl должен быть настроен на связь с вашим кластером. Если у вас ещё нет кластера, вы можете создать, его используя Minikube, или вы можете использовать одну из песочниц Kubernetes:
Определение liveness команды
Многие приложения, работающие в течение длительного времени, ломаются и могут быть восстановлены только перезапуском. Kubernetes предоставляет liveness пробы, чтобы обнаруживать и исправлять такие ситуации.
Когда контейнер запускается, он исполняет команду
В течение 30 секунд посмотрим события Pod:
Вывод команды показывает, что ещё ни одна liveness проба не завалена:
После 35 секунд посмотрим события Pod снова:
Внизу вывода появились сообщения, показывающие, что liveness проба завалена и containers был убит и пересоздан.
Подождите ещё 30 секунд и убедитесь, что контейнер был перезапущен:
Вывод команды показывает, что RESTARTS увеличено на 1:
Определение liveness HTTP запроса
В конфигурационном файле вы можете видеть Pod с одним контейнером. Поле periodSeconds определяет, что kubelet должен производить liveness пробы каждые 3 секунды. Поле initialDelaySeconds сообщает kubelet’у, что он должен ждать 3 секунды перед проведением первой пробы. Для проведения пробы kubelet отправляет запрос HTTP GET на сервер, который запущен в контейнере и слушает порт 8080. Если обработчик пути /healthz на сервере возвращает код успеха, kubelet рассматривает контейнер как живой и здоровый. Если обработчик возвращает код ошибки, kubelet убивает и перезапускает контейнер.
Любой код, больший или равный 200 и меньший 400, означает успех. Любой другой код интерпретируется как ошибка.
Вы можете посмотреть исходные коды сервера в server.go.
В течение первых 10 секунд жизни контейнера обработчик /healthz возвращает статус 200. После обработчик возвращает статус 500.
Kubelet начинает выполнять health checks через 3 секунды после старта контейнера. Итак, первая пара проверок будет успешна. Но после 10 секунд health checks будут завалены и kubelet убьёт и перезапустит контейнер.
Чтобы попробовать HTTP liveness проверку, создайте Pod:
Через 10 секунд посмотрите события Pod, чтобы проверить, что liveness probes завалилась и container перезапустился:
В релизах до v1.13 (включая v1.13), если переменная окружения http_proxy (или HTTP_PROXY ) определена на node, где запущен Pod, HTTP liveness проба использует этот прокси. В версиях после v1.13, определение локальной HTTP прокси в переменной окружения не влияет на HTTP liveness пробу.
Определение TCP liveness пробы
Третий тип liveness проб использует TCP сокет. С этой конфигурацией kubelet будет пытаться открыть сокет к вашему контейнеру на определённый порт. Если он сможет установить соединение, контейнер будет считаться здоровым, если нет, будет считаться заваленным.
В дополнение к readiness пробе, конфигурация включает liveness пробу. Kubelet запустит первую liveness пробу через 15 секунд после старта контейнера. Аналогично readiness пробе, он будет пытаться соединиться с контейнером goproxy на порт 8080. Если liveness проба завалится, контейнер будет перезапущен.
Для испытаний TCP liveness проверки, создадим Pod:
Через 15 секунд посмотрим события Pod’а для проверки liveness пробы:
Использование именованных портов
Вы можете использовать именованный порт ContainerPort для HTTP или TCP liveness проверок:
Защита медленно запускающихся контейнеров со startup пробами
Иногда приходится иметь дело со старыми приложениями, которым может требоваться дополнительное время для запуска на их первую инициализацию. В таких случаях бывает сложно настроить параметры liveness пробы без ущерба для скорости реакции на deadlock’и, для выявления которых как раз и нужна liveness проба. Хитрость заключается в том, чтобы настроить startup пробу с такой же командой, что и HTTP или TCP проверка, но failureThreshold * periodSeconds должно быть достаточным, чтобы покрыть наихудшее время старта.
Итак, предыдущий пример будет выглядеть так:
Благодаря startup пробе, приложению дано максимум 5 минут (30 * 10 = 300 сек.) для завершения его старта. Как только startup проба успешна 1 раз, liveness проба начинает контролировать дедлоки контейнеров. Если startup probe так и не заканчивается успехом, контейнер будет убит через 300 секунд и подвергнется restartPolicy pod’а.
Определение readiness проб
Иногда приложения временно не могут обслужить траффик. Например, приложение может требовать загрузки огромных данных или конфигурационных файлов во время старта, или зависит от внешних сервисов после старта. В таких случаях вы не хотите убивать приложение, но и отправлять ему клиентские запросы тоже не хотите. Kubernetes предоставляет readiness пробы для определения и нивелирования таких ситуаций. Pod с контейнерами сообщает, что они не готовы принимать траффик через Kubernetes Services.
Конфигурация HTTP и TCP readiness проб также идентичны liveness пробам.
Readiness и liveness пробы могут быть использованы одновременно на одном контейнере. Использование обеих проб может обеспечить отсутствие траффика в контейнер, пока он не готов для этого, и контейнер будет перезапущен, если сломается.
Конфигурация проб
Probes имеют несколько полей, которые вы можете использовать для более точного контроля поведения liveness и readiness проверок:
HTTP пробы имеют дополнительные поля, которые могут быть установлены для httpGet :
Что дальше
Вы также можете прочитать API references для:
