DaemonSet

DaemonSet 會確保每一個 Pod 的副本會在每一個 Node 上執行(如果沒有特別設定的話)。

與 ReplicaSet 不同的是,DaemonSet 比較像是一些管理功能的佈署,譬如資源監控器、一些管理的 Agent。

而 ReplicaSet 是確保副本的數量,並且會分散在每個 Node 上。

當應用程式的單一副本必須在叢集中的所有或部份 Node 上執行時,就應該使用 DaemonSet。

DaemonSet 調度器

預設情況下,除非你額外設定 Node 選擇器(–selector),否則 DaemonSet 會在每個 Node 上建立 Pod 的副本,
透過 nodeName 欄位來限制要在哪些 Node 上執行。

DaemonSet 跟 ReplicaSet 一樣,會週期性的查看 Pod 的狀況,並且比較預期/實際的 Pod 數量來做調整。

如果有新的 Node 加入到叢集中,當 DaemonSet 發現這個新的 Node,就會自動將 Pod 放到 Node 上。

建立 DaemonSet

使用 kubectl 來建立一個 DaemonSet,以下是一個簡易的範例檔,稍作修改就可以使用。

範例檔:

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: abc-daemonset
  labels:
    app: abc-DaemonSet
spec:
  minReadySeconds: 10
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: abc
    spec:
      containers:
        - name: abc
          image: abc123.com/example-pod:v1.1.1  

或是你可以使用 fluented 的範例檔,會在每個 Node 上,建立一個 fluented 的日誌 agent。

K8S 建置與執行的範例檔

建立 DaemonSet

kubectl apply -f fluentd.yaml
daemonset "fluentd" created

查詢 DaemonSet

kubectl describe daemonset fluentd

查看 Pod 在那一個 Node 上面:

kubectl get pods -o wide

限制 DaemonSet 在某些 Node 上

要確保每一個 Node 都有一個副本,要使用 DaemonSet,若要讓副本只存在某些 Node,也是用 DaemonSet。
例如我們要讓某些 Pod 跑在有 SSD 的 Node 上,或是將 Pod 放在某些只有 GPU 的機器。

增加 Node 的 Label

要限制 DaemonSet 的第一步,就是將 Node 打上標籤,可以利用 kubectl lable 指令來完成。

kubectl label nodes (node-name) ssd=true

查看 Node 的 Label,或是使用 -o wide 並不會顯示 Lable,需要用 Json 的輸出格式來找 items.metadata.label

kubectl get nodes --show-lable

kubectl get nodes -o json

使用 --selector 來直接篩選節點

kubectl get nodes --selector ssd=true

建立 DaemonSet

kubectl create -f daemonset-nginx.yaml

查看 DaemonSet

kubectl get daemonset
kubectl descirbe daemonset (name)

設定 nodeSelect

在設定玩 Node 的標籤之後,就可以修改 manifest 的 spec.template.spec.nodeSelector 來設定只跑在哪些 Node 上。

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: abc-daemonset
  labels:
    app: abc-DaemonSet
spec:
  minReadySeconds: 10
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: abc
    spec:
      nodeSelector:
        ssd: "true"
      containers:
        - name: abc
          image: abc123.com/example-pod:v1.1.1    

更新 DaemonSet 內的 Pod

新版的 K8S (1.6 之後) 已經支援 DaemonSet 的滾動更新,你可以先檢查一下你的 K8S 是否高於 1.6

kubectl --version

再來需要設定 spec.updateStrategy.type 的值來制定更新策略,設定為 RollingUpdate 即可。

控制滾動更新 (RollingUpdate) 有兩個參數可以設定:

  • spec.minreadyseconds:前一個 Pod 更新後,在 Ready 的狀態下要多久後再進行下一個 Pod 更新。
  • spec.updatesStrategy.reolingUpdate.maxUnavailable:可以同時滾動更新的 Pod 數量

您可以設定 spec.minReadySeconds 為 30 ~ 60 秒已確保 Pod 在更新後是正常的狀況後再執行下一個更新。

設定 spec.updatesStrategy.reolingUpdate.maxUnavailable 為 1 是比較安全的設定,但是更新的時間就會比較久。增加此值可以讓更新的速度變快,但若是更新時失敗,也會增加死掉的 Pod 數量。

如果你的 K8S 沒有高於 1.6,你可以在修改 manifest 檔後用 kubectl apply -f (manifest.yaml) 套用,然後手動把每一個 Pod 殺掉,就會重新啟動。

查看 Rollout 的狀況

使用 kubectl rollout 指令來看更新的狀況

kubectl rollout status daemonSets my-daemon-set

刪除 DaemonSet

刪除 DaemonSet 的指令,kubectl delete,或是利用 manifest 檔刪除

kubectl delete -f xxxx.yaml

刪除 DaemonSet 之後,所有被管理的 Pod 都會刪除,如果你不想刪除 Pod,可以用 –cascade 參數,則 DaemonSet 會刪除,Pod 會保留下來。

文章資訊
slug:k8s-daemonset
title:DaemonSet 簡介與使用
tags:k8s,Kubernetes,daemonset
categories:k8s
thumbnail:DaemonSet.jpg
最後修改日期: 2019-08-27

作者