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

微信掃碼關注

相關文章
相關標籤/搜索