Паттерн Daemon Service (Фоновая служба) позволяет размещать и запускать приоритетные инфраструктурные поды на целевых узлах. Он используется главным образом администраторами для запуска подов, привязанных к конкретным узлам, в целях расширения возможностей платформы Kubernetes.
Понятие демона (фонового процесса) в программных системах существует на многих уровнях. На уровне операционной системы демон — это долго выполняющаяся, самовосстанавливающаяся компьютерная программа, которая запускается как фоновый процесс. В Unix имена демонов обычно заканчиваются на «d», например httpd, named и sshd. В других операционных системах используются альтернативные термины, такие как служебные задачи и фантомные задания.
Независимо от названия, эти программы объединяет то, что они выполняются как процессы, обычно не взаимодействуют с монитором, клавиатурой и мышью и запускаются во время загрузки системы. Аналогичное понятие существует и на уровне приложений. Например, в JVM потоки-демоны работают в фоновом режиме и предоставляют вспомогательные услуги пользовательским потокам выполнения. Эти потоки-демоны имеют низкий приоритет, работают в фоновом режиме, не влияют на жизненный цикл приложения и выполняют такие задачи, как сборка мусора или финализация.
В Kubernetes тоже есть похожее понятие — набор демонов DaemonSet. Как мы знаем, Kubernetes является распределенной платформой, разбросанной по нескольким узлам, основная задача которой — управление подами приложений, поэтому DaemonSet представлен подами, выполняющимися в фоновом режиме на узлах кластера и предоставляющими некоторые услуги остальной части кластера.
Набор реплик ReplicaSet и его предшественник ReplicationController — это управляющие структуры, отвечающие за выполнение определенного количества подов. Эти контроллеры постоянно проверяют список запущенных подов и следят за тем, чтобы фактическое количество выполняющихся подов всегда соответствовало желаемому. В этом смысле набор демонов DaemonSet действует аналогично и следит, чтобы всегда выполнялось определенное количество подов. Разница лишь в том, что первые два, ReplicaSet и ReplicationController, поддерживают выполнение определенного количества подов, руководствуясь обычными требованиями к высокой доступности и уровню нагрузки для приложений, независимо от количества узлов.
DaemonSet, напротив, решая, сколько экземпляров подов запустить, не учитывает уровень нагрузки. Его главная задача — поддерживать выполнение одного пода на каждом узле или на определенных узлах. Давайте посмотрим, как определяется DaemonSet (листинг 9.1).
Листинг 9.1. Ресурс DaemonSet
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: random-refresher
spec:
selector:
matchLabels:
app: random-refresher
template:
metadata:
labels:
app: random-refresher
spec:
nodeSelector:
feature: hw-rng
containers:
- image: k8spatterns/random-generator:1.0
name: random-generator
command:
- sh
- -c
- >-
"while true; do
java -cp / RandomRunner /host_dev/random 100000;
sleep 30; done"
volumeMounts:
- mountPath: /host_dev
name: devices
volumes:
- name: devices
hostPath:
path: /dev
Использовать только узлы с меткой feature и значением hw-rng.
Наборы демонов DaemonSet часто монтируют разделы файловой системы узла для решения задач обслуживания.
hostPath для прямого доступа к каталогам узла.
При таком поведении основными кандидатами для включения в набор демонов DaemonSet обычно являются процессы, связанные с поддержкой инфраструктуры, такие как сборщики журналов, экспортеры метрик и даже маршрутизаторы kube-proxy, которые выполняют операции на уровне кластера. Существует много различий в том, как DaemonSet и ReplicaSet управляют подами, но основные из них следующие:
• По умолчанию DaemonSet размещает на каждом узле по одному экземпляру пода. Это поведение можно изменить, определив ограниченное подмножество узлов в параметре nodeSelector.
• DaemonSet создает под с требуемым значением в параметре nodeName. Поэтому DaemonSet не требует наличия планировщика Kubernetes для запуска контейнеров. Эта особенность позволяет использовать DaemonSet для запуска компонентов Kubernetes и управления ими.
• Поды, созданные контроллером DaemonSet, могут запускаться до запуска планировщика, что позволяет запускать их на узлах раньше любых других подов.
• Так как планировщик не используется, контроллер DaemonSet не принимает во внимание параметр unschedulable узла.
• Поды, управляемые контроллером DaemonSet, как предполагается, должны выполняться только на целевых узлах. По этой причине многие контроллеры обрабатывают их иначе и с более высоким приоритетом. Например, перепланировщик будет избегать вытеснения таких модулей, механизм автоматического масштабирования кластера будет управлять ими отдельно и т.д.
Обычно DaemonSet создает один экземпляр пода на каждом узле или подмножестве узлов. Учитывая это, есть несколько способов достичь подов, управляемых контроллером DaemonSet:
Создать службу Service с тем же селектором пода, как в DaemonSet, и использовать службу для достижения фонового пода на случайном узле, выбранном балансировщиком нагрузки.
Создать автономную (headless) службу Service с тем же селектором пода, как в DaemonSet, и использовать ее для извлечения нескольких записей A из DNS, содержащих IP-адреса и порты всех подов.
Поды в DaemonSet могут определять параметр hostPort и становиться доступными через IP-адреса узлов и указанный номер порта. Поскольку комбинация hostIP, hostPort и protocol должна быть уникальной, количество мест, где под может быть запланирован, ограниченно.
Приложение в поде из DaemonSet может записывать данные в хорошо известное место или передавать внешней для него службе. В таком случае потребителям не нужно напрямую обращаться к подам в DaemonSet.
статические поды
Другой способ запуска контейнеров подобно тому, как это делает DaemonSet, — использовать статические поды. Kubelet, помимо взаимодействия с Kubernetes API Server и получения определений подов, может также получать объявления ресурсов из локального каталога. Подами, которые определены таким способом, управляет только Kubelet, и они выполняются только на одном узле. Программный интерфейс служб не наблюдает за этими подами, они не управляются никакими контроллерами и их работоспособность не проверяется. За такими подами наблюдает только клиент Kubelet, который перезапускает их, когда они завершаются. Аналогично, Kubelet периодически сканирует указанный в настройках каталог, обнаруживает изменения в определениях подов и добавляет или удаляет поды при необходимости.
Статические поды можно использовать для запуска контейнерных версий системных процессов Kubernetes или других контейнеров. Но контроллеры DaemonSet лучше интегрированы с остальной частью платформы и выглядят предпочтительнее статических подов.
В этой книге мы описываем особенности и паттерны Kubernetes, которые используются в основном разработчиками, а не администраторами. DaemonSet находится где-то посередине, больше тяготея к набору инструментов администратора, но мы включили его в обсуждение, потому что он также часто используется разработчиками приложений. Контроллеры DaemonSet и CronJob также являются прекрасными примерами, как Kubernetes превращает понятия, характерные для одного узла, такие как Crontab и демоны, в кластерные примитивы для управления распределенными системами. Все это новые распределенные понятия, которые разработчики тоже должны знать.
• Пример фоновой службы (http://bit.ly/2TMX3rc).
• Описание контроллера DaemonSet (http://bit.ly/2r07CWx).
• Выполнение непрерывного обновления в DaemonSet (http://bit.ly/2CAZ13F).
• Наборы демонов DaemonSet и задания Job (http://bit.ly/2HLeHof).
• Статические поды (https://kubernetes.io/docs/tasks/administer-cluster/static-pod/).