Прим. перев.: Эта статья продолжает цикл материалов от технического писателя из 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 определяется представлением запроса на запуск (execute) одного или более контейнеров на одном узле, и эти контейнеры разделяют доступ к таким ресурсам, как тома хранилища и сетевой стек.
Однако в обиходе термин «pod» может употребляться и в смысле этого запроса, и в смысле совокупности контейнеров, которые запускаются в ответ на запрос. Поэтому в публикации мы будем использовать слово «pod», когда говорим о запросе, а для второго случая — употреблять выражение «набор контейнеров».
Pod'ы считаются базовыми строительными блоками Kubernetes, потому что все рабочие нагрузки в Kubernetes — например, Deployments, ReplicaSets и Jobs — могут быть выражены в виде pod'ов.
Pod — это один и единственный объект в Kubernetes, который приводит к запуску контейнеров. Нет pod'а — нет контейнера!

Схема 1. Deployment, ReplicaSet, pod и контейнеры

Схема 2. Pod'ы, планировщик (Scheduler) и Kubelet
На этой иллюстрации выделены соответствующие объекты и компоненты. Pod'ы представлены как Kubernetes Pod Objects, а работой с ними занимаются:

Схема 3. Объекты Kubernetes
На этой иллюстрации показаны объекты Kubernetes, ответственные за работу с pod'ом:
Pod Object задаёт набор контейнеров, которые будут запущены, и желаемую политику перезапуска (restart policy) в случае падения контейнера, а также отслеживает состояние запуска.
Binding Object привязывает Pod Object к Node Object, т.е. назначает pod на узел для последующего запуска.
Node Object представляет узел в кластере Kubernetes.

Схема 4. Обработка pod'а
Когда pod создан пользователем или контроллером вроде ReplicaSet Controller или Job Controller, Kubernetes обрабатывает pod в два этапа:

Схема 5. Управляющий цикл планировщика Kubernetes
Задача планировщика (Scheduler) в Kubernetes — запланировать pod, то есть назначить ему подходящий узел в кластере Kubernetes для последующего запуска.

Связывание объекта pod'а с объектом узла
Pod назначается узлу (или связывается с ним) тогда и только тогда, когда есть объект связывания (binding), у которого:
(Любители приключений могут посмотреть на GitHub gist от Kelsey Hightower под названием «Creating and Scheduling a Pod Manually» — пошаговое руководство по созданию объекта связывания вручную.)

Схема 6. Управляющий цикл Kubelet
Задача Kubelet — запустить pod, что по сути означает запуск набора контейнеров pod'а. Запуск pod'а Kubelet'ом происходит в две фазы: инициализацию и основную стадию.
Как правило, набор контейнеров на фазе инициализации осуществляет подготовительные работы, такие как подготовку необходимой структуры директорий и файлов. А набор контейнеров на основной фазе выполняет уже «самые главные» задачи.
В обиходе же, хотя это и не совсем корректно, термин «pod» зачастую подразумевает набор контейнеров на основной фазе или же ещё более узкое значение «самого главного» контейнера основной фазы.

Схема 7.1. Запуск pod'а, фаза инициализации (init) и основная фаза (main)
Во время инициализации Kubelet последовательно запускает контейнеры в соответствии со спецификациями pod'а
Во время основной фазы Kubelet одновременно запускает контейнеры в соответствии со спецификациями pod'а

Схема 7.2. Запуск pod'а, подробности этого процесса
В случае сбоя у контейнера, когда контейнер прекращает работу с отличным от нуля (0) кодом возврата (exit code), Kubelet может перезапустить контейнер в соответствии с политикой рестарта pod'а. Эта политика имеет одно из следующих значений:
У политики рестарта pod'а различная семантика для init-контейнеров и основных контейнеров: если запуск init-контейнеров обязан привести к завершению, то основные контейнеры могут и не завершаться.

Политика рестарта для init-контейнера
Init-контейнер будет перезапущен (т.е. повлечёт за собой запуск нового контейнера с такой же спецификацией) при завершении своей работы только при выполнении следующих условий:

Политика рестарта для основного (main) контейнера
Основной контейнер будет перезапущен (т.е. повлечёт за собой запуск нового контейнера с такой же спецификацией) при завершении своей работы только при выполнении следующих условий:

Схема 8. Пример временной шкалы с красной точкой, символизирующей сбой у контейнера
На иллюстрации показана возможная временная шкала запуска pod'а с двумя спецификациями init-контейнеров и двумя спецификациями основных контейнеров. Также она показывает создание (в соответствии с политикой рестарта) нового контейнера Main Container 1.2 после проблемы с запуском Main Container 1.1.

Схема 9. Взаимодействие Kubelet с объектом pod'а и исполняемой средой контейнера (container runtime)
Kubelet получает спецификации pod'а
Kubelet сворачивает
Фаза pod'а — это проекция состояния контейнеров из набора контейнеров, она зависит от:

Схема 10. Фазы pod'а

Фаза Pending
Pod находится в фазе ожидания тогда и только тогда, когда:

Фаза Running
Pod находится в фазе работы тогда и только тогда, когда:

Фаза Success
Pod находится в фазе успеха тогда и только тогда, когда:

Фаза Failure
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 проходит через разные фазы, сообщая о состоянии — или, точнее говоря, о состоянии своего набора контейнеров — пользователю и системе.
Читайте также в нашем блоге:

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, а работой с ними занимаются:
- планировщик (Scheduler),
- Kubelet.
Объекты Kubernetes

Схема 3. Объекты Kubernetes
На этой иллюстрации показаны объекты Kubernetes, ответственные за работу с pod'ом:
- собственно объект pod'а (Pod Object);
- объект связывания (Binding Object);
- объект узла (Node Object).
Pod Object задаёт набор контейнеров, которые будут запущены, и желаемую политику перезапуска (restart policy) в случае падения контейнера, а также отслеживает состояние запуска.
Binding Object привязывает Pod Object к Node Object, т.е. назначает pod на узел для последующего запуска.
Node Object представляет узел в кластере Kubernetes.
Обработка pod'а

Схема 4. Обработка pod'а
Когда pod создан пользователем или контроллером вроде ReplicaSet Controller или Job Controller, Kubernetes обрабатывает pod в два этапа:
- Scheduler планирует pod,
- Kubelet запускает pod.
Планирование pod'а

Схема 5. Управляющий цикл планировщика Kubernetes
Задача планировщика (Scheduler) в Kubernetes — запланировать pod, то есть назначить ему подходящий узел в кластере Kubernetes для последующего запуска.

Связывание объекта pod'а с объектом узла
Pod назначается узлу (или связывается с ним) тогда и только тогда, когда есть объект связывания (binding), у которого:
- пространство имён равняется пространству имён pod'а,
- название равняется названию pod'а,
- тип цели равняется
Node, - название цели равняется названию узла.
(Любители приключений могут посмотреть на GitHub gist от Kelsey Hightower под названием «Creating and Scheduling a Pod Manually» — пошаговое руководство по созданию объекта связывания вручную.)
Запуск pod'а

Схема 6. Управляющий цикл Kubelet
Задача Kubelet — запустить pod, что по сути означает запуск набора контейнеров pod'а. Запуск pod'а Kubelet'ом происходит в две фазы: инициализацию и основную стадию.
Как правило, набор контейнеров на фазе инициализации осуществляет подготовительные работы, такие как подготовку необходимой структуры директорий и файлов. А набор контейнеров на основной фазе выполняет уже «самые главные» задачи.
В обиходе же, хотя это и не совсем корректно, термин «pod» зачастую подразумевает набор контейнеров на основной фазе или же ещё более узкое значение «самого главного» контейнера основной фазы.

Схема 7.1. Запуск pod'а, фаза инициализации (init) и основная фаза (main)
Во время инициализации Kubelet последовательно запускает контейнеры в соответствии со спецификациями pod'а
.Spec.InitContainers и в заданном в списке порядке. Для успешного запуска pod'а и с учётом политики рестарта, его init-контейнеры должны запуститься и успешно завершиться.Во время основной фазы Kubelet одновременно запускает контейнеры в соответствии со спецификациями pod'а
.Spec.Containers. Здесь уже для успешного запуска pod'а и с учётом политики рестарта, его основные (main) контейнеры должны быть запущены и либо успешно завершиться, либо работать неограниченное время.
Схема 7.2. Запуск pod'а, подробности этого процесса
В случае сбоя у контейнера, когда контейнер прекращает работу с отличным от нуля (0) кодом возврата (exit code), Kubelet может перезапустить контейнер в соответствии с политикой рестарта pod'а. Эта политика имеет одно из следующих значений:
Always, OnFailure, Never.У политики рестарта pod'а различная семантика для init-контейнеров и основных контейнеров: если запуск init-контейнеров обязан привести к завершению, то основные контейнеры могут и не завершаться.

Политика рестарта для init-контейнера
Init-контейнер будет перезапущен (т.е. повлечёт за собой запуск нового контейнера с такой же спецификацией) при завершении своей работы только при выполнении следующих условий:
- exit-код контейнера сообщает об ошибке и
- политика рестарта pod'а имеет значение
AlwaysилиOnFailure.

Политика рестарта для основного (main) контейнера
Основной контейнер будет перезапущен (т.е. повлечёт за собой запуск нового контейнера с такой же спецификацией) при завершении своей работы только при выполнении следующих условий:
- политика рестарта определена как
Alwaysили - политика рестарта определена как
OnFailureи exit-код контейнера сообщает об ошибке.

Схема 8. Пример временной шкалы с красной точкой, символизирующей сбой у контейнера
На иллюстрации показана возможная временная шкала запуска pod'а с двумя спецификациями init-контейнеров и двумя спецификациями основных контейнеров. Также она показывает создание (в соответствии с политикой рестарта) нового контейнера Main Container 1.2 после проблемы с запуском Main Container 1.1.
Фазы pod'а

Схема 9. Взаимодействие Kubelet с объектом pod'а и исполняемой средой контейнера (container runtime)
Kubelet получает спецификации pod'а
.Spec.InitContainers и .Spec.Containers, запускает указанный набор контейнеров и соответствующим образом обновляет значения pod'а .Status.InitContainerStatuses и .Status.ContainerStatuses.Kubelet сворачивает
.Status.InitContainerStatuses и .Status.ContainerStatuses pod'а в одно значение — .Status.Phase.Фаза pod'а — это проекция состояния контейнеров из набора контейнеров, она зависит от:
- состояний и exit-кодов init-контейнеров,
- состояний и exit-кодов основных контейнеров.

Схема 10. Фазы pod'а
Ожидание (Pending)

Фаза Pending
Pod находится в фазе ожидания тогда и только тогда, когда:
- ни один из init-контейнеров pod'а не находится в состоянии
Terminatedс ошибкой (Failure); - все основные контейнеры pod'а находятся в состоянии
Waiting.
Работает (Running)

Фаза Running
Pod находится в фазе работы тогда и только тогда, когда:
- все init-контейнеры pod'а находятся в состоянии
Terminatedс успехом (Success); - хотя бы один основной контейнер pod'а находится в состоянии
Running; - ни один из основных контейнеров pod'а не находится в состоянии
Terminatedс ошибкой (Failure).
Успех (Success)

Фаза Success
Pod находится в фазе успеха тогда и только тогда, когда:
- все init-контейнеры pod'а находятся в состоянии
Terminatedс успехом (Success); - все основные контейнеры pod'а находятся в состоянии
Terminatedс успехом (Success).
Отказ (Failure)

Фаза Failure
Pod находится в фазе отказа тогда и только тогда, когда:
- все контейнеры pod'а находятся в состоянии
Terminated; - хотя бы один из контейнеров pod'а находятся в состоянии
Terminatedс ошибкой (Failure).
Неизвестно (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 проходит через разные фазы, сообщая о состоянии — или, точнее говоря, о состоянии своего набора контейнеров — пользователю и системе.
P.S. от переводчика
Читайте также в нашем блоге:
- «Kubernetes: жизнь пода»;
- «Как обеспечивается высокая доступность в Kubernetes»;
- «Как на самом деле работает планировщик Kubernetes?»;
- «Что происходит в Kubernetes при запуске kubectl run?» Часть 1 и часть 2;
- «Наш опыт с Kubernetes в небольших проектах» (видео доклада, включающего в себя знакомство с техническим устройством Kubernetes).
