K8S实战(九)| 控制器 DaemonSet - 将守护进程容器化

前言

Deployment 管理的 Pod 容许在一个节点上运行多个副本。html

当须要在节点上运行收集日志或者执行监控任务的容器时,显然不适合启动多个 Pod 副本。node

这种场景下,咱们能够启用 DaemonSet 控制器来管理 Pod。linux

更新历史

Daemon Pod 的特色

  1. Pod 运行在集群中的所有或者部分节点上
  2. 每一个节点上只能有一个这样的 Pod
  3. 当集群中加入了新节点,Pod 会自动在新节点上建立
  4. 当节点被从集群中移除后,节点上 Pod 会自动被回收掉

Daemon Pod 适用的场景

  1. 网络插件的 Agent
  2. 存储插件的 Agent
  3. 监控任务的 Agent
  4. 收集日志的 Agent

DaemonSet

建立一个 DSdocker

cat daemonset.yamlapi

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      tolerations:
      # this toleration is to have the daemonset runnable on master nodes
      # remove it if your masters can't run pods
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers
# kubectl apply -f daemonset.yaml
daemonset.apps/fluentd-elasticsearch created

查看微信

[root@master01 ~]# kubectl get ds --namespace kube-system
NAME                    DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR                 AGE
fluentd-elasticsearch   6         6         6       6            6           <none>                        11m

目前集群中有 3 个 master,3 个 worker,一共 6 个节点,能够看到 6 个节点上都运行了该 node网络

工做流程

DaemonSet Controller,从 Etcd 里获取全部的 Node 列表,而后遍历全部的 Node。app

而后检查当前这个 Node 上是否是有一个携带了 name=fluentd-elasticsearch 标签的 Pod 在运行。elasticsearch

而检查的结果,大概有这么三种状况:ui

  1. Node 上没有这种 Pod,那么就意味着要在这个 Node 上建立这个 Pod;
  2. Node 上有这种 Pod,可是数量大于 1,那就说明要把多余的 Pod 从这个 Node 上删除掉;
  3. 只有一个这种 Pod,说明这个节点是正常的。

重要参数

spec.affinity.nodeAffinity

经过命令

# kubectl edit pod fluentd-elasticsearch-22g5r --namespace=kube-system

能够看到 DaemonSet 自动给 Pod 增长了参数

spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchFields:
          - key: metadata.name
            operator: In
            values:
            - master03

限制了该 Pod 只能运行在 master03 这个 Node 上

tolerations

一样经过上面的命令,能够看到有参数

tolerations:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
  - effect: NoSchedule
    key: node.kubernetes.io/disk-pressure

意味着能够容忍全部标记有以下“污点”的 Node,能够在这些 Node 上运行
master/not-ready/unreachable/disk-pressure

正常状况下,若是 Node 上被标记了这些“污点”,Pod 被禁止调度到这样的 Node 上运行

但 DaemonSet 给 Pod 加上了 tolerations,使 Pod 能够忽略这些污点,从而成功将 Pod 调度到“污点”节点上

若是节点有故障致使 Pod 启动失败,DaemonSet 会一直尝试,直到 Pod 成功启动

仅在部分节点运行 Pod

能够在 YAML 中手工指定 .spec.template.spec.affinity,这样 Pod 会运行在指定的 Node 上

nodeAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
    nodeSelectorTerms:
    - matchFields:
      - key: metadata.name
        operator: In
        values:
        - target-host-name

若是没有指定该参数,那么 Pod 会运行在全部 Node 上

DaemonSet 优势

咱们也能够本身写一个守护进程来执行相似的工做,使用 DaemonSet Pod 有哪些优势呢。

  1. DaemonSet Pod 自带自身监控功能,省去了咱们本身再写一个针对守护进程的监控程序的工做
  2. DaemonSet Pod 无论运行什么任务,都是统一的语言和管理方式
  3. DaemonSet Pod 自带了资源限制功能,避免了守护进程长时间运行占用过多资源对宿主机形成影响

结束语

DaemonSet 倾向于精确控制 Pod 运行在哪些机器上,确保这些机器上都有这个 Pod 在运行。

而 Deployment 更适合于管理离用户更近的无状态类 Pod,好比 Web 服务。

它们的共同点是,都不但愿本身管理的 Pod 终止,Pod 出现问题后能够自愈。

联系我

微信公众号:zuolinux_com

微信扫码关注