О Pods
Pods — это наименьшая единица API в Kubernetes. Если говорить более технически, Pods — это атомарная единица планирования в Kubernetes. Но зачем нам нужны Pods? Чтобы ответить на этот вопрос, нужно сначала понять суть контейнера: контейнер — это, по сути, процесс. Именно так. Контейнеры — это процессы в облачной вычислительной системе, а образы контейнеров — это, по сути, установочные пакеты “.exe” для этой системы. Kubernetes, в этой аналогии, выступает в роли операционной системы.
Процессы и группы процессов
Давайте войдём на Linux-машину и выполним следующую команду:
$ pstree -g
Эта команда отображает древовидную структуру запущенных в данный момент процессов в системе. Вывод может выглядеть примерно так:
systemd(1)-+-accounts-daemon(1984)-+-{gdbus}(1984)
| `-{gmain}(1984)
|-acpid(2044)
...
|-lxcfs(1936)-+-{lxcfs}(1936)
| `-{lxcfs}(1936)
|-mdadm(2135)
|-ntpd(2358)
|-polkitd(2128)-+-{gdbus}(2128)
| `-{gmain}(2128)
|-rsyslogd(1632)-+-{in:imklog}(1632)
| |-{in:imuxsock) S 1(1632)
| `-{rs:main Q:Reg}(1632)
|-snapd(1942)-+-{snapd}(1942)
| |-{snapd}(1942)
| |-{snapd}(1942)
| |-{snapd}(1942)
| |-{snapd}(1942)
Как видите, в реальной операционной системе процессы не работают изолированно. Вместо этого они объединены в группы процессов. Например, программа rsyslogd отвечает за обработку журналов в Linux. Главная программа rsyslogd — main — и используемый ею модуль ядра imklog принадлежат к группе процессов 1632. Эти процессы взаимодействуют, чтобы выполнять задачи программы rsyslogd. Kubernetes, по сути, переносит эту концепцию «групп процессов» в технологию контейнеров и делает её «полноправным гражданином» в этой облачной «операционной системе». Kubernetes выбрал такой подход, потому что инженеры Google поняли, что развёртываемые ими приложения часто демонстрировали отношения, подобные «процессам и группам процессов». В частности, эти приложения требовали тесного взаимодействия, что обуславливало необходимость их развёртывания на одной машине. Управлять такими операционными отношениями без концепции «групп» было бы невероятно сложно. Возьмём, к примеру, rsyslogd. Он состоит из трёх процессов: модуля imklog, модуля imuxsock и главной функции самого rsyslogd. Эти три процесса должны работать на одной машине; иначе их обмен данными через сокеты и файлы столкнётся с проблемами.
Взаимодействие между контейнерами

Как показано на диаграмме выше, этот Pod содержит два пользовательских контейнера — A и B — и Infra-контейнер. В Kubernetes Infra-контейнер спроектирован так, чтобы потреблять минимум ресурсов, и использует специальный образ с именем k8s.gcr.io/pause. Этот образ представляет собой контейнер, написанный на ассемблере, который постоянно находится в «приостановленном» состоянии, а его несжатый размер составляет всего 100–200 КБ. Как только Infra-контейнер «захватывает» пространство имён Network Namespace, пользовательские контейнеры могут присоединиться к этому пространству имён. Поэтому если вы посмотрите на файлы пространств имён этих контейнеров на хост-машине (путь к этому файлу упоминался ранее), они будут указывать на одно и то же значение. Это означает, что для контейнеров A и B внутри Pod они могут общаться напрямую, используя localhost. Они видят те же сетевые устройства, что и Infra-контейнер. Pod имеет только один IP-адрес, который является IP-адресом, связанным с сетевым пространством имён Pod. Естественно, все остальные сетевые ресурсы выделяются на уровне Pod и совместно используются всеми контейнерами внутри этого Pod. Жизненный цикл Pod привязан исключительно к Infra-контейнеру и не зависит от контейнеров A и B. Более того, для всех пользовательских контейнеров в одном Pod входящий и исходящий трафик можно считать проходящим через Infra-контейнер. Этот аспект очень важен, потому что если в будущем вы захотите разработать сетевой плагин для Kubernetes, ваше основное внимание должно быть направлено на настройку Network Namespace Pod, а не на то, как каждый пользовательский контейнер использует вашу сетевую конфигурацию. Последнее не имеет значения. Это означает, что если ваш сетевой плагин полагается на установку пакетов или конфигураций внутри контейнера, это нежизнеспособное решение. Корневая файловая система образа Infra-контейнера практически пуста, не оставляя вам возможностей для настройки. С другой стороны, это также означает, что вашему сетевому плагину не нужно беспокоиться о статусе запуска пользовательских контейнеров, а нужно только сосредоточиться на настройке Pod, то есть Network Namespace Infra-контейнера. Благодаря такой конструкции совместное использование томов становится намного проще. Kubernetes может определять все конфигурации томов на уровне Pod. В результате каталог на хосте, соответствующий тому, уникален для Pod, и любой контейнер внутри Pod может просто объявить о монтировании этого каталога. Такой подход к проектированию Pod, способствующий «сверхтесным отношениям» между контейнерами, призван побудить пользователей задуматься: возможно, приложения, состоящие из нескольких функционально не связанных компонентов, работающих в одном контейнере, лучше представить в виде нескольких контейнеров внутри Pod. Чтобы уловить эту идею, попробуйте применить её к сценариям, которые трудно решить с помощью одного контейнера. Например, представьте приложение, которое постоянно записывает файлы журналов в каталог /var/log внутри контейнера. В этом случае вы можете смонтировать том внутри Pod в каталог /var/log контейнера приложения. Затем, в том же Pod, запустите sidecar-контейнер, который также объявляет о монтировании того же тома в свой каталог /var/log. После этого единственной задачей sidecar-контейнера будет непрерывное чтение файлов журналов из своего каталога /var/log и их пересылка в такие хранилища, как MongoDB или Elasticsearch. Такая настройка создаёт базовый механизм сбора журналов. Как и в первом примере, основная функция sidecar в этом сценарии также связана с использованием общего тома для файловых операций. Однако не стоит забывать и о другой важной характеристике Pod: все контейнеры внутри Pod используют одно и то же сетевое пространство имён (Network Namespace). Это позволяет делегировать многие задачи по настройке и управлению сетью Pod sidecar-контейнеру, полностью обходя необходимость вмешиваться в работу пользовательских контейнеров. Ярким примером этого является проект сервисной сетки Istio.
Резюме
В этом обсуждении мы углубились в причины, по которым нужны Pods. По сути, Pod — это фундаментальная единица в кластере Kubernetes, которая инкапсулирует один или несколько контейнеров (обычно Docker-контейнеров). Эти контейнеры совместно используют сетевые и дисковые ресурсы. С точки зрения процессов и групп процессов, Pod можно рассматривать как облегчённую группу процессов. Он позволяет развёртывать, масштабировать и управлять несколькими тесно взаимодействующими процессами (контейнерами) как единым целым, упрощая развёртывание и эксплуатацию сложных приложений. В следующей статье мы предоставим более глубокое объяснение Pod.
Novita AI — это универсальная облачная платформа, которая расширяет ваши AI-амбиции. Благодаря бесшовно интегрированным API, бессерверным вычислениям и ускорению GPU, мы предоставляем экономически эффективные инструменты, необходимые для быстрого создания и масштабирования вашего AI-бизнеса. Устраните проблемы с инфраструктурой и начните бесплатно — Novita AI воплощает ваши AI-мечты в реальность.
Рекомендуемое чтение:
