kubernetes控制器之DaemonSet
什麼是 DaemonSet?
DaemonSet 確保全部(或者一些)Node 上執行一個 Pod 的副本。當有 Node 加入叢集時,也會為他們新增一個 Pod 。當有 Node 從叢集移除時,這些 Pod 也會被回收。刪除 DaemonSet 將會刪除它建立的所有 Pod。
使用 DaemonSet 的一些典型用法:
- 執行叢集儲存 daemon,例如在每個 Node 上執行
glusterd
、ceph
。 - 日誌收集,比如fluentd,logstash等
- 系統監控,比如Prometheus Node Exporter,collectd,New Relic agent,Ganglia gmond等
- 系統程式,比如kube-proxy, kube-dns, glusterd, ceph等
一個簡單的用法是,在所有的 Node 上都存在一個 DaemonSet,將被作為每種型別的 daemon 使用。 一個稍微複雜的用法可能是,對單獨的每種型別的 daemon 使用多個 DaemonSet,但具有不同的標誌,和/或對不同硬體型別具有不同的記憶體、CPU要求。
例子
使用Fluentd收集日誌的例子:
apiVersion: extensions/v1beta1 kind: DaemonSet metadata: name: fluentd spec: template: metadata: labels: app: logging id: fluentd name: fluentd spec: containers: - name: fluentd-es image: gcr.io/google_containers/fluentd-elasticsearch:1.3 env: - name: FLUENTD_ARGS value: -qq volumeMounts: - name: containers mountPath: /var/lib/docker/containers - name: varlog mountPath: /varlog volumes: - hostPath: path: /var/lib/docker/containers name: containers - hostPath: path: /var/log name: varlog
選擇執行節點:當指定.spec.template.spec.nodeSelector,DaemonSet將會在匹配的節點上建立pod。如果都沒有指定,DaemonSet在所有node節點上建立pod.
指定Node節點
DaemonSet會忽略Node的unschedulable狀態,有兩種方式來指定Pod只執行在指定的Node節點上:
- nodeSelector:只調度到匹配指定label的Node上
- nodeAffinity:功能更豐富的Node選擇器,比如支援集合操作
- podAffinity:排程到滿足條件的Pod所在的Node上
nodeSelector示例
首先給Node打上標籤
kubectl label nodes node-01 disktype=ssd
然後在daemonset中指定nodeSelector為disktype=ssd:
spec: nodeSelector: disktype: ssd
nodeAffinity示例
nodeAffinity目前支援兩種:requiredDuringSchedulingIgnoredDuringExecution和preferredDuringSchedulingIgnoredDuringExecution,分別代表必須滿足條件和優選條件。比如下面的例子代表排程到包含標籤kubernetes.io/e2e-az-name並且值為e2e-az1或e2e-az2的Node上,並且優選還帶有標籤another-node-label-key=another-node-label-value的Node。
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/e2e-az-name
operator: In
values:
- e2e-az1
- e2e-az2
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: another-node-label-key
operator: In
values:
- another-node-label-value
containers:
- name: with-node-affinity
image: gcr.io/google_containers/pause:2.0
podAffinity示例
podAffinity基於Pod的標籤來選擇Node,僅排程到滿足條件Pod所在的Node上,支援podAffinity和podAntiAffinity。這個功能比較繞,以下面的例子為例:
- 如果一個“Node所在Zone中包含至少一個帶有security=S1標籤且執行中的Pod”,那麼可以排程到該Node
- 不排程到“包含至少一個帶有security=S2標籤且執行中Pod”的Node上
apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S1
topologyKey: failure-domain.beta.kubernetes.io/zone
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S2
topologyKey: kubernetes.io/hostname
containers:
- name: with-pod-affinity
image: gcr.io/google_containers/pause:2.0
靜態Pod
除了DaemonSet,還可以使用靜態Pod來在每臺機器上執行指定的Pod,這需要kubelet在啟動的時候指定manifest目錄:
kubelet --pod-manifest-path=/etc/kubernetes/manifests
然後將所需要的Pod定義檔案放到指定的manifest目錄中。
注意:靜態Pod不能通過API Server來刪除,但可以通過刪除manifest檔案來自動刪除對應的Pod。