k8s工作負載控制器--DaemonSet

misakivv發表於2024-08-05

目錄
  • 一、概述
  • 二、適用場景
  • 三、基本操作
    • 1、官網的DaemonSet資源清單
    • 2、欄位解釋
    • 3、編寫DaemonSet資源清單
    • 4、基於yaml建立DaemonSet
    • 5、注意點
      • 5.1、必須欄位
      • 5.2、DaemonSet 物件的名稱
      • 5.3、.spec.selector 與 .spec.template.metadata.labels之間的關係
    • 6、檢視DaemonSet
      • 6.1、檢視DaemonSet列表
      • 6.2、檢視 DaemonSet 控制器所建立的 Pod 副本資訊
    • 7、滾動更新
      • 7.1、檢視DaemonSet詳情
      • 7.2、更新nginx映象版本
      • 7.3、檢視滾動更新狀態
      • 7.4、檢視DS滾動更新過程
      • 7.5、檢視DS滾動更新版本
    • 8、版本回退
      • 8.1、回滾
      • 8.2、檢視版本回退情況
    • 9、刪除DaemonSet
      • 9.1、直接刪除DS
      • 9.2、基於建立的資源清單刪除DS
  • 四、DaemonSet排程
    • 1、排程方式
    • 2、指定nodeName節點執行
      • 2.1、原理機制
      • 2.2、示例
        • 2.2.1、建立一個DaemonSet資源清單,指定nodeName
        • 2.2.2、應用 DaemonSet
        • 2.2.3、檢視 DaemonSet Pod 的狀態
    • 3、透過標籤執行 (nodeSelector)
      • 3.1、原理機制
      • 3.2、示例
        • 3.2.1、給 k8s-node1 新增標籤
        • 3.2.2、建立DaemonSet 資源清單,使用nodeSelector
        • 3.2.3、應用 DaemonSet
        • 3.2.4、檢視 DaemonSet Pod 的狀態
        • 3.2.5、刪除k8s-node1上的標籤
    • 4、透過親和力排程 (node Affinity 和 node Anti-affinity)
      • 4.1、Node Affinity (節點親和性)
        • 4.1.1、原理
        • 4.1.2、給node-k8s2新增標籤
        • 4.1.3、建立 DaemonSet 資源清單,使用 nodeAffinity
        • 4.1.4、應用DaemonSet
        • 4.1.5、檢視 DaemonSet Pod 的狀態
      • 4.2、Node Anti-affinity (節點反親和性)
        • 4.2.1、原理
        • 4.2.2、給node-k8s2新增標籤
        • 4.2.3、建立 DaemonSet 資源清單,使用 node Anti-affinity
        • 4.2.4、應用DaemonSet
        • 4.2.5、檢視 DaemonSet Pod 的狀態
    • 5、汙點與容忍度(TolerationsTaints
      • 5.1、原理
      • 5.2、示例
        • 5.2.1、給 k8s-node1 新增 taint
        • 5.2.2、建立 DaemonSet 資源清單
        • 5.2.3、應用Daemonset
        • 5.2.4、 檢視 DaemonSet Pod 的狀態
  • 五、如何與 DaemonSet 中的 Pod 進行通訊
    • 1、 推送(Push)
      • 1.1、實現
      • 1.2、示例
    • 2、 NodeIP 和已知埠
      • 2.1、實現
      • 2.2、示例
    • 3、DNS
      • 3.1、實現
      • 3.2、示例
    • 4、Service
      • 4.1、實現
      • 4.2、示例

一、概述

DaemonSet 確保全部(或者某些)節點上執行一個 Pod 的副本。 當有節點加入叢集時, 也會為他們新增一個 Pod 。 當有節點從叢集移除時,這些 Pod 也會被回收。刪除 DaemonSet 將會刪除它建立的所有 Pod。

DaemonSet 的主要作用,是在 Kubernetes 叢集裡,執行一個 Daemon Pod。 DaemonSet 只管理 Pod 物件,然後透過 nodeAffinity 和 Toleration 這兩個排程器引數的功能,保證了每個節點上有且只有一個 Pod

img

二、適用場景

DaemonSet適用於每個node節點均需要部署一個守護程序的場景

  • 日誌採集agent,如fluentd或logstash
  • 監控採集agent,如Prometheus Node Exporter,Sysdig Agent,Ganglia gmond
  • 分散式叢集元件,如Ceph MON,Ceph OSD,glusterd,Hadoop Yarn NodeManager等
  • k8s必要執行元件,如網路flannel,weave,calico,kube-proxy等

三、基本操作

1、官網的DaemonSet資源清單

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:
      # 這些容忍度設定是為了讓該守護程序集在控制平面節點上執行
      # 如果你不希望自己的控制平面節點執行 Pod,可以刪除它們
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      - key: node-role.kubernetes.io/master
        operator: Exists
        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
      # 可能需要設定較高的優先順序類以確保 DaemonSet Pod 可以搶佔正在執行的 Pod
      # priorityClassName: important
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log

2、欄位解釋

apiVersion: apps/v1    #指定YAML檔案的API版本,這裡是apps/v1
kind: DaemonSet    #定義資源型別,這裡是DaemonSet
metadata:    #包含DaemonSet的後設資料
  name: fluentd-elasticsearch     #此DaemonSet的名稱
  namespace: kube-system    #定義DaemonSet所屬的名稱空間
  labels:    #定義標籤
    k8s-app: fluentd-logging    #此標籤表示該DaemonSet與日誌處理有關
spec:    #DaemonSet的規約,包含了DaemonSet的規格和行為的詳細配置
  selector:    #定義了DaemonSet所管理的Pods的標籤選擇器,即哪些Pods應該被這個DaemonSet管理。這裡matchLabels必須與template.metadata.labels相匹配。
    matchLabels:
      name: fluentd-elasticsearch
  template:    #Pod的模板,用於建立和管理DaemonSet下的Pods
    metadata:    #Pod的後設資料,這裡包含了與spec.selector.matchLabels相匹配的標籤。
      labels:
        name: fluentd-elasticsearch
    spec:    #Pod的規約
      tolerations:     #定義了Pod可以容忍的節點汙點,允許Pod在帶有特定汙點的節點上執行。這裡配置了兩個容忍度,分別針對控制平面節點和標記為master的節點,確保日誌採集容器可以在這些特殊節點上執行。
      # 這些容忍度設定是為了讓該守護程序集在控制平面節點上執行
      # 如果你不希望自己的控制平面節點執行 Pod,可以刪除它們
      - key: node-role.kubernetes.io/control-plane    #汙點的鍵,通常表示控制平面節點的標籤。
        operator: Exists    #Exists,表示只要節點上有與key匹配的汙點,無論其值是什麼,都將被視為匹配
        effect: NoSchedule    #NoSchedule,表示如果節點上存在與key匹配的汙點,則預設情況下不允許Pod被排程到該節點。但是,由於這個Pod宣告瞭對該汙點的容忍度,所以Pod可以被排程到帶有node-role.kubernetes.io/control-plane汙點的節點上。
      - key: node-role.kubernetes.io/master    #指向標記為master的節點的汙點鍵。
        operator: Exists    #只要節點上有與key匹配的汙點,無論其值是什麼,都將被視為匹配。
        effect: NoSchedule    #表明預設情況下,沒有相應容忍度的Pod將不能被排程到帶有node-role.kubernetes.io/master汙點的節點上。但是,由於這個Pod宣告瞭對該汙點的容忍度,所以Pod可以被排程到帶有node-role.kubernetes.io/master汙點的節點上。
      containers:    #Pod的容器配置
      - 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    #定義了容器內部掛載卷的路徑
      # 可能需要設定較高的優先順序類以確保 DaemonSet Pod 可以搶佔正在執行的 Pod
      # priorityClassName: important
      terminationGracePeriodSeconds: 30    #定義了當Pod被刪除時,Kubernetes等待的秒數,以允許容器優雅地關閉。
      volumes:    #定義Pod可以使用的卷
      - name: varlog    #定義了一個卷的名稱
        hostPath:    #指定了這個卷的主機路徑
          path: /var/log

3、編寫DaemonSet資源清單

daemonset.yaml

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: simple-daemonset
  namespace: default
spec:
  selector:
    matchLabels:
      app: simple-daemonset-app
  template:
    metadata:
      labels:
        app: simple-daemonset-app
    spec:
      containers:
      - name: nginx-container
        image: nginx:latest
        ports:
        - containerPort: 80

4、基於yaml建立DaemonSet

kubectl apply -f daemonset.yaml 

image-20240804115806378

5、注意點

5.1、必須欄位

DaemonSet需要apiVersion、kind 、metadata 和spec欄位

以下是DaemonSetYAML定義中最基本的必需欄位:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: <daemonset-name>
  namespace: <namespace>
spec:
  selector:
    matchLabels:
      <label-key>: <label-value>
  template:
    metadata:
      labels:
        <label-key>: <label-value>
    spec:
      containers:
      - name: <container-name>
        image: <image-name>
  • apiVersion:指定YAML檔案使用的Kubernetes API版本。對於DaemonSet,通常使用apps/v1。

  • kind:指定資源型別,這裡應為DaemonSet。

  • metadata

    • name:DaemonSet的名稱,必須是唯一的。
    • namespace:DaemonSet所在的名稱空間,預設為default,但強烈建議明確指定。
  • spec:DaemonSet的規格,定義了它的行為和管理的Pod的模板。

    • selector:選擇器,用於標識DaemonSet管理的Pods。

      • matchLabels:一個鍵值對的對映,用於匹配DaemonSet管理的Pods的標籤。這是必須的,用於確保DaemonSet管理的Pods與之關聯。
    • template:Pod的模板,定義了DaemonSet建立的Pods的結構。

      • metadata:Pod的後設資料,其中必須包含與spec.selector.matchLabels相匹配的labels欄位。
      • spec:Pod的規格,定義了容器、卷、網路設定等。
        • containers:一個或多個容器的列表,每個容器都需要定義name和image。

5.2、DaemonSet 物件的名稱

DaemonSet 物件的名稱必須是一個合法的 DNS 子域名

  • 不能超過 253 個字元
  • 只能包含小寫字母、數字,以及 '-' 和 '.'
  • 必須以字母數字開頭
  • 必須以字母數字結尾

5.3、.spec.selector 與 .spec.template.metadata.labels之間的關係

img

.spec.selector 必須與 .spec.template.metadata.labels 匹配。這意味著 matchLabels 中定義的每個鍵值對都必須存在於 .spec.template.metadata.labels 中,以確保DaemonSet能夠正確地選擇它所建立的Pods。如果 .spec.selector 中的標籤是 .spec.template.metadata.labels 的子集,則這種匹配是有效的。但如果 .spec.template.metadata.labels 中缺少 .spec.selector 中的任何一個標籤,或者標籤值不同,那麼配置將被視為無效,Kubernetes API將拒絕這個配置。

6、檢視DaemonSet

6.1、檢視DaemonSet列表

kubectl get ds -n default -o wide

image-20240804153945583

NAME:DaemonSet的名稱。在這個例子中,DaemonSet的名稱是simple-daemonset。

DESIRED:這是DaemonSet期望在叢集中執行的Pod數量。對於DaemonSet而言,這通常是叢集中節點的數量,因為DaemonSet的目標是在每個節點上執行至少一個Pod的例項。在這個例子中,DESIRED的值是2,是因為叢集有兩個節點。

CURRENT:這是DaemonSet當前管理的Pod數量。理想情況下,CURRENT的值應該等於DESIRED的值,這意味著DaemonSet已經達到了其目標狀態。在這個例子中,CURRENT的值也是2,與DESIRED相匹配。

READY:這是DaemonSet管理的Pod中處於就緒狀態的數量。就緒狀態(Ready)意味著Pod中的所有容器都已經啟動並且健康檢查(如果有的話)已透過。在這個例子中,READY的值是2,表明Pod已經準備好並正在執行。

UP-TO-DATE:這是當前正在執行的Pod中與DaemonSet最新模板匹配的數量。當DaemonSet更新其Pod模板時,這個數字可以幫助你跟蹤更新進度。在這個例子中,UP-TO-DATE的值是2,意味著所有執行的Pod都使用了最新的模板。

AVAILABLE:這是DaemonSet管理的Pod中可以服務流量的數量。這個數字通常與READY相同,除非某些Pod由於某種原因被標記為不可用。在這個例子中,AVAILABLE的值是2,與READY一致。

NODE SELECTOR:這是DaemonSet使用的節點選擇器,它定義了哪些節點可以執行DaemonSet的Pod。表示DaemonSet沒有使用節點選擇器,它的Pod可以在任何節點上執行。如果NODE SELECTOR包含特定的鍵值對,那麼DaemonSet的Pod將僅在具有相應標籤的節點上執行。

AGE:這是DaemonSet的建立時間,以持續時間的形式給出。在這個例子中,DaemonSet的AGE是65s,意味著它在65秒前建立。

6.2、檢視 DaemonSet 控制器所建立的 Pod 副本資訊

kubectl get pods -n default -o wide

image-20240804171611968

7、滾動更新

7.1、檢視DaemonSet詳情

kubectl get ds -n default
 
kubectl get daemonset simple-daemonset -n default -o json | jq '.spec.updateStrategy'

image-20240804151217017

可以看到DaemonSet支援RollingUpdate滾動更新策略

image-20240804151622106

  • RollingUpdate:這是預設的更新策略。使用 RollingUpdate 更新策略時,在更新 DaemonSet 模板後, 老的 DaemonSet Pod 將被終止,並且將以受控方式自動建立新的 DaemonSet Pod。 更新期間,最多隻能有 DaemonSet 的一個 Pod 執行於每個節點上。
  • maxSurge:定義了在更新過程中可以超出desiredNumberScheduled(期望的Pod數量)的額外Pod數量。在這個例子中,maxSurge設定為0,意味著在更新過程中不會建立超過當前期望數量的額外Pod。換句話說,DaemonSet在終止一箇舊的Pod之前不會建立一個新的Pod。
  • maxUnavailable:定義了在更新過程中可以有多少Pod不可用。maxUnavailable設定為1,意味著在更新過程中,可以有最多1個Pod不可用。這通常發生在舊的Pod被終止,而新的Pod尚未完全啟動並變得可用時。
  • type :為 RollingUpdate 是要啟用 DaemonSet 的滾動更新功能必須設定的

7.2、更新nginx映象版本

kubectl set image daemonsets simple-daemonset nginx-container=nginx:1.14.0 -n default

image-20240804161126418

7.3、檢視滾動更新狀態

kubectl rollout status ds simple-daemonset -n default

image-20240804171921680

7.4、檢視DS滾動更新過程

kubectl describe ds simple-daemonset -n default

image-20240804172331396

7.5、檢視DS滾動更新版本

kubectl rollout history ds simple-daemonset -n default

image-20240804172448761

REVERSION1就是初始版本

8、版本回退

8.1、回滾

kubectl rollout undo daemonset -n default simple-daemonset --to-revision=1

image-20240804174613001

8.2、檢視版本回退情況

kubectl describe ds simple-daemonset -n default

image-20240804174834329

9、刪除DaemonSet

9.1、直接刪除DS

kubectl delete ds simple-daemonset -n default

image-20240804175713055

9.2、基於建立的資源清單刪除DS

kubectl delete -f daemonset.yaml

image-20240804175505739

四、DaemonSet排程

1、排程方式

DaemonSet透過kubernetes預設的排程器scheduler會在所有的node節點上執行一個Pod副本,可以透過如下三種方式將Pod執行在部分節點上

  • 指定 nodeName 節點執行
  • 透過標籤執行 nodeSelector
  • 透過親和力排程 node Affinitynode Anti-affinity
  • 汙點與容忍度(TolerationsTaints
  • PriorityPreemption (優先順序和搶佔)

2、指定nodeName節點執行

這種方式通常不用於 DaemonSet,因為 DaemonSet 的目標是在儘可能多的節點上執行 Pod 副本。但是可以透過 .spec.nodeName 來指定特定節點執行 Pod。

2.1、原理機制

  • 當為 Pod 指定了具體的 nodeName 後,Kubernetes 排程器將跳過排程過程,直接將 Pod 分配給指定的節點。
  • 這種方式通常用於測試目的或者在特殊場景下使用,例如當您需要確保某個 Pod 在特定節點上執行時。

2.2、示例

2.2.1、建立一個DaemonSet資源清單,指定nodeName

cat <<EOF > daemonset-nodename.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-nodename
spec:
  selector:
    matchLabels:
      way: nodename
  template:
    metadata:
      labels:
        way: nodename
    spec:
      nodeName: k8s-node1  # 指定 nodeName
      containers:
      - name: daemon-nodename-container
        image: nginx:latest
EOF

2.2.2、應用 DaemonSet

kubectl apply -f daemonset-nodename.yaml

2.2.3、檢視 DaemonSet Pod 的狀態

kubectl get pods -l way=nodename -o wide

image-20240804192315570

3、透過標籤執行 (nodeSelector)

  • nodeSelector 是一種簡單的方式,用於指定 Pod 應該執行在具有特定標籤的節點上。
  • 當在 Pod 模板中定義了 nodeSelector,Kubernetes 排程器會將 Pod 分配到具有相應標籤的節點上。

3.1、原理機制

  • 需要在節點上設定特定的標籤。
  • 在 DaemonSet 的 Pod 模板中定義 nodeSelector,指定節點標籤。
  • Kubernetes 排程器會根據 nodeSelector 將 Pod 分配到符合條件的節點上。

3.2、示例

3.2.1、給 k8s-node1 新增標籤

kubectl label nodes k8s-node1 role=worker

image-20240804192958533

3.2.2、建立DaemonSet 資源清單,使用nodeSelector

cat <<EOF > daemonset-nodeselector.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-nodeselector
spec:
  selector:
    matchLabels:
      way: nodeSelector
  template:
    metadata:
      labels:
        way: nodeSelector
    spec:
      nodeSelector:  # 使用 nodeSelector
        role: worker
      containers:
      - name: daemonset-nodeselector-container
        image: nginx:latest
EOF

3.2.3、應用 DaemonSet

kubectl apply -f daemonset-nodeselector.yaml

3.2.4、檢視 DaemonSet Pod 的狀態

kubectl get pods -l way=nodeSelector -o wide

image-20240804194013592

3.2.5、刪除k8s-node1上的標籤

測試完及時刪除標籤

kubectl label nodes k8s-node1 role-

image-20240804194225056

4、透過親和力排程 (node Affinity 和 node Anti-affinity)

4.1、Node Affinity (節點親和性)

4.1.1、原理

  • Node Affinity 是一種排程策略,允許定義的 Pod 必須或應該排程到哪些節點上。
  • 這種策略分為兩類:requiredDuringSchedulingIgnoredDuringExecutionpreferredDuringSchedulingIgnoredDuringExecution
  • requiredDuringSchedulingIgnoredDuringExecution 表示必須滿足的硬性要求。
  • preferredDuringSchedulingIgnoredDuringExecution 表示可選的偏好。

4.1.2、給node-k8s2新增標籤

按照節點親和性原理,pod最終會被排程到k8s-node2這個節點上

kubectl label nodes k8s-node2 role=worker

image-20240804200337059

4.1.3、建立 DaemonSet 資源清單,使用 nodeAffinity

cat <<EOF> daemonset-affinity.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-affinity
spec:
  selector:
    matchLabels:
      way: nodeAffinity
  template:
    metadata:
      labels:
        way: nodeAffinity
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: role
                operator: In
                values:
                - worker
      containers:
      - name: daemon-affinity-container
        image: nginx:latest
EOF

4.1.4、應用DaemonSet

kubectl apply -f daemonset-affinity.yaml

4.1.5、檢視 DaemonSet Pod 的狀態

kubectl get pods -l way=nodeAffinity -o wide

image-20240804201440131

4.2、Node Anti-affinity (節點反親和性)

4.2.1、原理

  • Node Anti-affinity 是一種排程策略,允許您定義 Pod 不應該排程到哪些節點上。
  • 這種策略也是分為兩類:requiredDuringSchedulingIgnoredDuringExecutionpreferredDuringSchedulingIgnoredDuringExecution
  • requiredDuringSchedulingIgnoredDuringExecution 表示必須滿足的硬性要求。
  • preferredDuringSchedulingIgnoredDuringExecution 表示可選的偏好。

4.2.2、給node-k8s2新增標籤

按照節點反親和性原理,節點不會被排程到k8s-node2上

kubectl label node k8s-node2 ROLE=worker2

image-20240804215430150

4.2.3、建立 DaemonSet 資源清單,使用 node Anti-affinity

cat <<EOF > daemonset-Anti-affinity.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-anti-affinity
spec:
  selector:
    matchLabels:
      way: Anti-affinity
  template:
    metadata:
      labels:
        way: Anti-affinity
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: ROLE
                operator: DoesNotExist
              - key: ROLE
                operator: NotIn
                values:
                - worker2
      containers:
      - name: daemonset-anti-affinity-container
        image: nginx:latest
EOF

4.2.4、應用DaemonSet

kubectl apply -f daemonset-Anti-affinity.yaml

4.2.5、檢視 DaemonSet Pod 的狀態

kubectl get pods -l way=Anti-affinity -o wide

image-20240804220142509

5、汙點與容忍度(TolerationsTaints

  • Taints(汙點) 是節點上的標記,用於排斥 Pod。
  • Tolerations(容忍度) 則是 Pod 上的配置,用於容忍節點上的 taints。

5.1、原理

  • 節點可以設定 taints 來排斥 Pod。
  • Pod 可以設定 tolerations 來容忍這些 taints。
  • Kubernetes 排程器會根據 tolerations 和 taints 的匹配情況來決定 Pod 是否可以被排程到節點上。

5.2、示例

5.2.1、給 k8s-node1 新增 taint

  • k8s-node1: 有汙點 example.com/taint-key=taint-value:NoSchedule
  • k8s-node2: 沒有汙點
kubectl taint nodes k8s-node1 example.com/taint-key=taint-value:NoExecute

5.2.2、建立 DaemonSet 資源清單

省略了 tolerations 部分。這意味著 DaemonSet 的 Pod 不會容忍任何汙點,因此它將不會被排程到帶有 example.com/taint-key=taint-value:NoExecute 汙點的節點上。

cat <<EOF > daemonset-no-tolerations.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-no-tolerations
spec:
  selector:
    matchLabels:
      way: no-tolerations
  template:
    metadata:
      labels:
        way: no-tolerations
    spec:
      containers:
      - name: daemonset-no-tolerations-container
        image: nginx:latest
EOF

5.2.3、應用Daemonset

kubectl apply -f daemonset-no-tolerations.yaml

5.2.4、 檢視 DaemonSet Pod 的狀態

kubectl get pods -l way=no-tolerations -o wide

image-20240804224413108

五、如何與 DaemonSet 中的 Pod 進行通訊

1、 推送(Push)

  • 推送模式是指 DaemonSet 中的 Pod 主動將資料傳送到其他服務或系統中,如統計資料庫或其他後端服務。
  • 這種模式不需要外部客戶端主動連線到 DaemonSet 中的 Pod。

1.1、實現

  • 配置 DaemonSet:
    • 需要在 DaemonSet 中的 Pod 規格中配置相應的邏輯,使其能夠主動傳送資料。
    • 通常,這涉及到使用像 HTTP 請求、訊息佇列或其他通訊協議來傳送資料。

1.2、示例

日誌聚合:

  • 可以使用像 Fluentd 或 Logstash 這樣的工具,配置它們將日誌資料推送到像 Elasticsearch 或 Splunk 這樣的後端。
  • daemonset-tolerations.yaml 檔案中,您需要配置容器以傳送日誌資料:
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-tolerations
spec:
  selector:
    matchLabels:
      way: tolerations
  template:
    metadata:
      labels:
        way: tolerations
    spec:
      containers:
      - name: daemonset-tolerations-container
        image: nginx:latest
        command: ["sh", "-c", "while true; do echo 'Log message'; sleep 10; done | fluentd -t -l /dev/stdin"]
        volumeMounts:
        - mountPath: /var/log/nginx
          name: log-volume
      volumes:
      - name: log-volume
        hostPath:
          path: /var/log/nginx

這裡我們假設 Fluentd 服務已經配置好,並且 Pod 將日誌資料推送給 Fluentd。

2、 NodeIP 和已知埠

  • NodeIP 和已知埠是指 DaemonSet 中的 Pod 使用 hostPort,這意味著它們監聽在節點的主機埠上。
  • 外部客戶端可以透過節點的 IP 地址和預先定義的埠來連線到這些 Pod。

2.1、實現

  • 配置 DaemonSet:
    • 在 DaemonSet 中的 Pod 規格中暴露 hostPort
    • 客戶端可以透過查詢節點列表或透過其他方式獲得節點 IP 地址,並使用預先定義的埠進行連線。

2.2、示例

監控系統:

  • 假設有一個監控系統,需要從每個節點收集指標。
  • 可以配置 DaemonSet 中的每個 Pod 監聽在節點的一個特定埠上,比如 9100。
  • daemonset-tolerations.yaml 檔案中,配置容器以暴露埠:
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-tolerations
spec:
  selector:
    matchLabels:
      way: tolerations
  template:
    metadata:
      labels:
        way: tolerations
    spec:
      containers:
      - name: daemonset-tolerations-container
        image: nginx:latest
        ports:
        - containerPort: 80
          hostPort: 9100
  • 獲取節點ip
kubectl get nodes -o jsonpath='{range .items[*]}{.status.addresses[?(@.type=="ExternalIP")].address}{"\n"}{end}'

3、DNS

  • DNS 模式是指建立一個無頭服務(Headless Service),它使用與 DaemonSet 中的 Pod 相同的選擇器。
  • 無頭服務會建立一個 DNS 記錄,該記錄解析為 DaemonSet 中所有 Pod 的 IP 地址。

3.1、實現

  • 建立無頭服務:
    • 建立一個無頭服務,其選擇器與 DaemonSet 的選擇器相同。
    • 無頭服務將自動建立一個 DNS 記錄,該記錄指向所有匹配的 Pod 的 IP 地址。
    • 客戶端可以透過查詢 DNS 記錄來獲取所有 Pod 的 IP 地址列表,並進行通訊。

3.2、示例

建立一個無頭服務 my-daemonset-service,其選擇器與 DaemonSet 相同。

apiVersion: v1
kind: Service
metadata:
  name: my-daemonset-service
spec:
  clusterIP: None
  selector:
    way: tolerations
  ports:
  - name: http
    port: 80
    targetPort: 80
  • 客戶端查詢 DNS:
    • 客戶端可以透過查詢 DNS 記錄 my-daemonset-service.default.svc.cluster.local 來獲取所有 Pod 的 IP 地址。
    • 可以透過 nslookupdig 命令來查詢 DNS 記錄:
nslookup my-daemonset-service.default.svc.cluster.local

4、Service

  • Service 模式是指建立一個服務,其選擇器與 DaemonSet 中的 Pod 相同。
  • 客戶端可以透過服務名稱來訪問 DaemonSet 中的任意 Pod。

4.1、實現

  • 建立服務:
    • 建立一個服務,其選擇器與 DaemonSet 的選擇器相同。
    • 服務將自動建立一個 DNS 記錄,該記錄解析為當前活動的 Pod 的 IP 地址。
    • 客戶端可以透過服務名稱來訪問 Pod。

4.2、示例

  • 建立一個服務 my-daemonset-service,其選擇器與 DaemonSet 相同。
apiVersion: v1
kind: Service
metadata:
  name: my-daemonset-service
spec:
  selector:
    way: tolerations
  ports:
  - name: http
    port: 80
    targetPort: 80
  • 客戶端訪問服務:
    • 客戶端可以透過服務名稱 my-daemonset-service.default.svc.cluster.local 來訪問 DaemonSet 中的任意 Pod。
    • 由於服務是負載均衡的,客戶端可能會隨機連線到不同的 Pod。

相關文章