в kubernetes

Знакомство с Kubernetes. Часть 3: Поды (Pods)


В данной статье цикла о знакомстве с оркестратором Kubernetes детальнее разберемся с подами (Pods) — наименьшей функциональной единицей для развертывания в объектной модели Kubernetes.

Pod (переводится с английского как стручок) состоит обычно из одного или нескольких контейнеров, хранилища (storage), отдельного IP-адреса и опций, которые определяют, как именно контейнер(ы) должны запускаться. Также Pod представляет собой некий запущенный процесс в кластере Kubernetes.

Чаще всего в Pod'ах используются docker-контейнеры (что и не удивительно), но можно использовать и другие контейнеры (например, rkt от CoreOS).

Важно Kubernetes управляет Pod'ами, а не контейнерами напрямую.

В кластере Kubernetes Pod'ы используются двумя способами:

  • Pod из одного контейнера — наиболее распространенный случай использования. В этом варианте Pod можно представить как обертку вокруг одного контейнера;
  • Pod из нескольких контейнеров, работающих сообща — контейнеры в данном случае образуют отдельную единицу (сервис) и используют общие ресурсы — например, файлы из одного хранилища (storage). При этом, отдельный контейнер Pod'а может обновлять эти файлы.

Каждый Pod предназначен для запуска одного экземпляра конкретного приложения. Если есть необходимость горизонтального масштабирования, то можно запустить несколько экземпляров Pod'а — в терминологии Kubernetes это называется репликацией. Реплицированные Pod'ы создаются и управляются как единая группа абстракцией, которая называется контроллер (Controller). Подробнее контроллеры рассматриваются в отдельной статье.

Pod'ы спроектированы для поддержки множества взаимодействующих процессов (например, контейнеров), которые образуют отдельный сервис (единицу обслуживания). Контейнеры внутри Pod'а автоматически размещаются и управляются на одной и той же физической (или виртуальной) ноде кластера. Контейнеры в Pod'е могут совместно использовать ресурсы и зависимости, взаимодействовать друг с другом и определять, когда и как они будут завершаться.

К слову, группировка и запуск нескольких контейнеров в Pod'е считается «продвинутым» вариантом использования, и применять этот шаблон нужно только при реальной необходимости. Например, у вас может быть контейнер с web-сервером, использующий файлы из общего (относительно Pod'а) хранилища, и отдельный контейнер, который обновляет эти файлы из удаленного источника. Визуально это может выглядеть так:

Pod'ы предоставляют запущенным внутри контейнерам два типа общих ресурсов: сеть и хранилище.

Сеть

Каждому Pod'у присваивается уникальный IP-адрес. Внутри Pod'а каждый контейнер использует общее пространство имен (namespace) сети, включая IP-адрес и сетевые порты. Между собой внутри Pod'а контейнеры взаимодействуют через localhost. При взаимодействии с объектами, находящимися за пределами Pod'а, контейнеры «договариваются» между собой и координируют использование общих сетевых ресурсов (таких как порты).

Хранилище

Pod может определить набор общих томов (volumes) для хранения данных. Контейнеры внутри Pod'а могут работать с этими томами и, таким образом, обмениваться данными между собой. Благодаря использованию томов, можно сохранить данные, если один из контейнеров Pod'а (которому нужны эти данные для корректной работы) должен быть перезапущен. Время жизни томов совпадает с временем жизни самого Pod'а.

Что касается работы в кластере Kubernetes, то редко когда приходится создавать и запускать отдельные Pod'ы вручную (варианты запуска при ознакомлении с Kubernetes мы в расчет не берем). Связано это с тем, что Pod'ы изначально проектировались как эфемерные объекты, минимальные единицы, «строительные блоки» для сущностей более высокого уровня (например, контроллеров). Когда Pod создается (не важно, вручную вами или контроллером), он по плану (за это отвечает scheduler) запускается на одной из нод кластера Kubernetes. На этой ноде Pod остается до тех пор, пока:

  • не завершится процесс внутри Pod'а (например, если это одноразовая задача);
  • Pod не будет удален вручную;
  • Pod не будет «выселен» с ноды из-за нехватки ресурсов;
  • нода не выйдет из строя.

Примечание Перезапуск контейнера внутри Pod'а не следует путать с перезапуском самого Pod'а.

Сами по себе Pod'ы не являются «самолечащимися» (self-healing) объектами. Если запуск Pod'а запланирован на ноде, которая вышла из строя, или сама операция запуска потерпела крах, то Pod удаляется. Точно также, при нехватке ресурсов на ноде (когда Pod'ы «выселяются») или при переводе ноды в режим обслуживания, Pod'ы не будут запущены на других узлах и удалятся. Для обеспечения запуска на других нодах (и управления Pod'ами в целом) в Kubernetes используются абстракции более высокого уровня, называемые контроллерами — в основном именно с ними и приходится иметь дело.

Контроллер может управлять несколькими экземплярами Pod'ов — в том числе обеспечивать репликацию и самовосстановление в пределах кластера (при выходе из строя ноды, идентичный экземпляр Pod'а будет запущен на другой ноде). Примером контроллера, который содержит в себе один или несколько экземпляров Pod'а могут быть:

  • Deployment
  • StatefulSet
  • DaemonSet

Для обеспечения такого функционала контроллеры используют шаблоны Pod'ов (Pod Templates). Шаблон Pod'а — спецификация, которая используется контроллерами и другими объектами (например, заданиями — Jobs/CronJob) для запуска настоящего, реального Pod'а. Ниже приведен пример простой спецификации (ее еще иногда называют манифестом), описывающей контейнер, который напечатает сообщение при запуске и «уснет» на час:

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']

Предложенный манифест (спецификацию) можно сохранить в файле single-example-pod.yml и запустить Pod с помощью утилиты командной строки kubectl:

kubectl create -f single-example-pod.yml

Больше информации о Pod'ах можно найти в официальной документации по Kubernetes.

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