Как обеспечить запуск pod на каждой ноде Kubernetes?

Ответ

Для этого используется контроллер 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 (демоны для управления хранилищем на каждой ноде).

Управление размещением:

  1. nodeSelector: Запуск только на нодах с определенными лейблами.
  2. tolerations: Позволяет pod быть запланированным на ноды с taint (например, на master-ноды).
  3. 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 — опять же, им свой демон на каждой машине нужен, чтобы дисками рулить.

Как им, блядь, управлять, чтобы он не лез, куда не надо:

  1. nodeSelector: Скажешь ему — «валяй только на нодах с таким-то лейблом». И он послушно поползёт только туда.
  2. tolerations: Это чтобы он мог залезть на «грязные» ноды, которые отталкивают обычные поды. Например, на мастер-ноды, которые обычно для системных подачков.
  3. affinity/anti-affinity: Это уже для параноиков, которые хотят контролировать, чтобы поды друг от друга подальше сидели или, наоборот, поближе.

И главное, не путай с Deployment, а то сам от себя охуеешь. Deployment — это как начальник, который говорит: «Мне нужно 10 одинаковых работяг, посадите их где угодно». А DaemonSet — это суровый надзиратель, который орёт: «На КАЖДОЙ табуретке должен сидеть по одному моему челу!». Добавил новую ноду в кластер — этот надзиратель тут же нового работягу на неё посадит, без всяких разговоров.