Ответ
Для этого используется контроллер DaemonSet. Его основная задача — поддерживать запущенную копию pod на всех (или выбранных) узлах кластера. Я применяю DaemonSet для системных сервисов.
Базовый пример DaemonSet для агента мониторинга:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
namespace: monitoring
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
# Селектор узлов: запускать только на worker-нодах
nodeSelector:
node-role.kubernetes.io/worker: ""
# Толерантности: разрешить запуск на нодах с taint
tolerations:
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
containers:
- name: node-exporter
image: prom/node-exporter:latest
ports:
- containerPort: 9100
hostPort: 9100 # Проброс порта на хост
securityContext:
privileged: true # Для доступа к системным метрикам
Ключевые аспекты и примеры использования:
- Системный мониторинг: Node Exporter, Datadog agent, Fluentd для сбора логов.
- Сетевые плагины: Calico, Cilium (их компоненты часто работают как DaemonSet).
- Хранилище: GlusterFS, Ceph (демоны для управления хранилищем на каждой ноде).
Управление размещением:
nodeSelector: Запуск только на нодах с определенными лейблами.tolerations: Позволяет pod быть запланированным на ноды с taint (например, на master-ноды).affinity/anti-affinity: Более сложные правила размещения относительно других pod.
Отличие от Deployment: Deployment управляет количеством pod-реплик, которые могут быть размещены на любых нодах. DaemonSet же гарантирует ровно один pod на ноду (соответствующую селекторам). При добавлении новой ноды в кластер DaemonSet автоматически создаст на ней pod.
Ответ 18+ 🔞
Вот, смотри, как это работает на самом деле. Есть такая штука — DaemonSet. Его задача проще пареной репы, но дохуя важная: он следит, чтобы на каждой твоей ноде в кластере (ну или на тех, которые ты выбрал) крутилась одна копия пода. Я его обычно для всякого системного говна юзаю, которое должно быть везде, как назойливая муха.
Вот тебе простейший пример DaemonSet для какого-нибудь агента сбора метрик:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
namespace: monitoring
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
# Селектор узлов: запускать только на worker-нодах
nodeSelector:
node-role.kubernetes.io/worker: ""
# Толерантности: разрешить запуск на нодах с taint
tolerations:
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
containers:
- name: node-exporter
image: prom/node-exporter:latest
ports:
- containerPort: 9100
hostPort: 9100 # Проброс порта на хост
securityContext:
privileged: true # Для доступа к системным метрикам
А теперь, ёпта, где эта хрень реально нужна:
- Следить за всем подряд: Node Exporter, Datadog, Fluentd для логов — классика жанра. Без этого ты слепой, как крот.
- Сеть: Разные Calico да Cilium — они свои костыли тоже через DaemonSet раскидывают, чтобы на каждой ноде свой сетевой гоблин сидел.
- Хранилища: GlusterFS, Ceph — опять же, им свой демон на каждой машине нужен, чтобы дисками рулить.
Как им, блядь, управлять, чтобы он не лез, куда не надо:
nodeSelector: Скажешь ему — «валяй только на нодах с таким-то лейблом». И он послушно поползёт только туда.tolerations: Это чтобы он мог залезть на «грязные» ноды, которые отталкивают обычные поды. Например, на мастер-ноды, которые обычно для системных подачков.affinity/anti-affinity: Это уже для параноиков, которые хотят контролировать, чтобы поды друг от друга подальше сидели или, наоборот, поближе.
И главное, не путай с Deployment, а то сам от себя охуеешь. Deployment — это как начальник, который говорит: «Мне нужно 10 одинаковых работяг, посадите их где угодно». А DaemonSet — это суровый надзиратель, который орёт: «На КАЖДОЙ табуретке должен сидеть по одному моему челу!». Добавил новую ноду в кластер — этот надзиратель тут же нового работягу на неё посадит, без всяких разговоров.