1. 程式人生 > 實用技巧 >容器化守護程序:demonSet

容器化守護程序:demonSet

一、 需求:k8s叢集中有這樣一類需求

1、各種網路外掛的 Agent 元件,都必須執行在每一個節點上,用來處理這個節點上的容器網路;

2、各種儲存外掛的 Agent 元件,也必須執行在每一個節點上,用來在這個節點上掛載遠端儲存目錄,操作容器的 Volume 目錄;

3、各種監控元件和日誌元件,也必須執行在每一個節點上,負責這個節點上的監控資訊和日誌蒐集。

解決:就是k8s中的daemonSet,我們定義的各種controller,需要每個node上有且僅有一個pod執行,用此來完成。

二、舉例

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:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      containers:
      - name: fluentd-elasticsearch
        image: k8s.gcr.io/fluentd-elasticsearch:1.20
        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

它的作用:通過 fluentd 將 Docker 容器裡的日誌轉發到 ElasticSearch 中

需要注意的是:Docker 容器裡應用的日誌,預設會儲存在宿主機的 /var/lib/docker/containers/{{. 容器 ID}}/{{. 容器 ID}}-json.log 檔案裡,所以這個目錄正是 fluentd 的蒐集目標

1、問題:DaemonSet 又是如何保證每個 Node 上有且只有一個被管理的 Pod 呢?

答案:DaemonSet Controller,首先從 Etcd 裡獲取所有的 Node 列表,然後遍歷所有的 Node。這時,它就可以很容易地去檢查,當前這個 Node 上是不是有一個攜帶了 name=fluentd-elasticsearch 標籤的 Pod 在執行。
num >1, 刪除至1
num == 1,不變
num == 0,通過 nodeAffinity 來建立至1

2、nodeAffinity是什麼?舉例

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: metadata.name
            operator: In
            values:
            - node-geektime

這裡的nodeAffinity 的含義是:

1) requiredDuringSchedulingIgnoredDuringExecution:它的意思是說,這個 nodeAffinity 必須在每次排程的時候予以考慮。同時,這也意味著你可以設定在某些情況下不考慮這個 nodeAffinity;

2) 這個 Pod,將來只允許執行在“metadata.name”是“node-geektime”的節點上。

nodeAffinity能夠支援更加豐富的用法,因此代替了nodeSelector

3、問題: master節點上有汙點,預設pod部署不上去

解決:通過tolerations來解決

...
template:
    metadata:
      labels:
        name: network-plugin-agent
    spec:
      tolerations:
      - key: node.kubernetes.io/network-unavailable
        operator: Exists
        effect: NoSchedule

4、如何進行版本控制?

通過ControllerRevision 的k8s資源物件來控制。通過kubectl rollout undo 來完成