第十六章 kubernetes 部署守护进程


一、DaemonSet概述

官方文档:https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/

DaemonSet确保在所有(或部分)Node节点上运行Pod的副本。随着新的Node被添加到群集中的同时,会将Pod添加到新Node中。随着节点从群集中删除,垃圾收集器也将会删除这些Pod。DaemonSet的一些典型场景和用法:

集群存储:在每个Node节点上,运行集群存储守护程序,例如glusterd,ceph。
日志收集:在每个Node节点上,运行日志收集守护程序,例如fluentd或logstash。
节点监控:在每个Node节点上,运行节点监控守护程序,例如Prometheus Node Exporter,collectd,Dynatrace OneAgent,Datadog agent,New Relic agent,Ganglia gmond或者Instana agent。

二、创建DaemonSet应用

#1.在每个node节点安装数据采集工具,编写yaml文件
[root@kubernetes-master-001 ~]# vi tst.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: ds-test
  labels:
    app: filebeat
spec:
  # 标签选择器
  selector:
    matchLabels:
      app: filebeat
  # 标签类型
  template:
    metadata:
      labels:
        app: filebeat
    spec:
      # 配置容器
      containers:
      - name: logs
        image: nginx
        ports:
        - containerPort: 80
        # 挂载目录
        volumeMounts:
        - name: varlog
          mountPath: /tmp/log
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
#2.必填字段
与Kubernetes中其它的对象一样,DaemonSet必须包含*apiVersion,kind和metadata字段。同时,DaemonSet还需要spec字段部分的内容。

#3.Pod模板
.spec.template是.spec的必填字段。.spec.template用来定义Pod模板。DaemonSet中的Pod模板必须设置RestartPolicy 等于Always,未指定的默认值即为Always。

#4.Pod选择器
通过.spec.selector字段定义Pod选择器。从Kubernetes 1.8开始,必须指定一个与.spec.template标签相匹配选择器。一旦创建了DaemonSet,就不能对.spec.selector进行修改,改变Pod选择器可能会导致Pod成为孤儿。

.spec.selector是一个由两个字段组成的对象:

- matchLabels– 与ReplicationControlle*的.spec.selector字段同样的工作机制。
- matchExpressions – 允许通过指定键,值列表以及与键和值相关的运算符来构建更复杂的选择器。

如果同时指定了两者时,结果取两者的和。如果指定了.spec.selector,则必须匹配.spec.template.metadata.labels,如果不匹配将会被API拒绝。

#5.仅在某些节点上运行Pod
如果指定了.spec.template.spec.nodeSelector,则DaemonSet控制器将在与该节点选择器匹配的Node节点上部署Pod 。同样,如果指定了.spec.template.spec.affinity,则DaemonSet控制器将在与该节点关联相匹配的Node节点上创建Pod 。如果您未指定上述两个字段,则DaemonSet控制器将会在所有的Node节点上创建Pod。

三、部署DaemonSet应用

#1.部署DaemonSet应用
[root@kubernetes-master-001 ~]# kubectl apply -f tst.yaml 
daemonset.apps/ds-test created

#2.查看DaemonSet应用
[root@kubernetes-master-001 ~]# kubectl get  pods
NAME                   READY   STATUS    RESTARTS   AGE
ds-test-7krrv          1/1     Running   0          59s
ds-test-jnxzm          1/1     Running   0          59s
web-5bb6fd4c98-54ll2   1/1     Running   0          2d
web-5bb6fd4c98-585rn   1/1     Running   0          2d

四、进入DaemonSet查看

[root@kubernetes-master-001 ~]# kubectl  exec -it ds-test-7krrv bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@ds-test-7krrv:/# ls /tmp/log/
anaconda	   containers	       maillog		  secure-20211108	vmware-network.5.log	vmware-vmtoolsd-root.log
audit		   cron		       maillog-20211108   spooler		vmware-network.6.log	wtmp
boot.log	   cron-20211108       messages		  spooler-20211108	vmware-network.7.log	yum.log
boot.log-20200806  dmesg	       messages-20211108  tallylog		vmware-network.8.log	yum.log-20211108
boot.log-20200810  dmesg.old	       ntpstats		  tuned			vmware-network.9.log
boot.log-20211108  firewalld	       pods		  vmware-network.1.log	vmware-network.log
boot.log-20211109  grubby	       rhsm		  vmware-network.2.log	vmware-vgauthsvc.log.0
btmp		   grubby_prune_debug  sa		  vmware-network.3.log	vmware-vmsvc-root.log
btmp-20211108	   lastlog	       secure		  vmware-network.4.log	vmware-vmsvc.log
root@ds-test-7krrv:/#

五、调度Daemon Pods

1.由DaemonSet控制器调度(自1.12版本起,默认禁用)

通常,由Kubernetes调度器选择Pod所运行的机器。但是,由DaemonSet控制器创建的Pod,在创建是就已经为Pod 选择了机器(在创建Pod时指定.spec.nodeName,因此调度器会忽略它)。因此:

- DaemonSet控制器将不会考虑unschedulable的Node节点。
- 即使尚未启动调度器,DaemonSet控制器也可以生成Pod,这可以帮助集群引导程序。

2.由默认调度器调度(自1.12版本起,默认启用)

特性状态: Kubernetes v1.13 beta

DaemonSet确保所有符合条件的节点都运行Pod的副本。通常,由Kubernetes调度器选择Pod所运行的Node节点。但是,DaemonSet Pods是由DaemonSet控制器所创建和调度的。这就产生了以下的问题:

- 不一致的Pod行为:正常的Pod,在创建是处于Pending状态;但DaemonSet Pod在创建时,并不是处于Pending 状态。这使用户感到困惑。
- Pod抢占由默认调度器处理。启用抢占后,DaemonSet控制器将在不考虑Pod优先级和抢占的情况下制定调度决策。

ScheduleDaemonSetPods允许使用默认调度器而不是DaemonSet控制器来调度DaemonSet,方法是将NodeAffinity术语添加到DaemonSet Pods,而不是使用.spec.nodeName术语。默认调度器将Pod绑定到目标主机。如果DaemonSet pod的节点关联已存在,则替换它。DaemonSet控制器仅在创建或修改DaemonSet Pods时执行这些操作,并且不对DaemonSet的spec.template进行任何更改。
nodeAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
    nodeSelectorTerms:
    - matchFields:
      - key: metadata.name
        operator: In
        values:
        - target-host-name
        
此外,node.kubernetes.io/unschedulable:NoSchedule容忍会自动添加到DaemonSet Pods。在调度DaemonSet Pod时,默认调度器会忽略unschedulable的Node节点。

3.污点和容忍

根据相关特性,DaemonSet Pods会自动添加以下的容忍度。
容忍建 影响 版本 描述
node.kubernetes.io/not-ready NOEXECUTE 1.13+ 当存在诸如网络分区之类的节点问题时,不会驱逐DaemonSet pod。
node.kubernetes.io/unreachable NOEXECUTE 1.13+ 当存在诸如网络分区之类的节点问题时,不会驱逐DaemonSet pod。
node.kubernetes.io/disk-pressure NoSchedule 1.8+
node.kubernetes.io/memory-pressure NoSchedule 1.8+
node.kubernetes.io/unschedulable NoSchedule 1.12+ DaemonSet pods可以通过默认调度程序容忍不可调度的属性。
node.kubernetes.io/network-unavailable NoSchedule 1.12+ 使用主机网络的DaemonSet pod可以通过默认调度程序容忍网络不可用的属性。

六、与Daemon Pods进行通信

下面是与DaemonSet中Pod进行通信的一些可能模式:

- 推送:DaemonSet中的Pod配置为将更新发送给另一个服务,例如统计数据库。他们没有客户。
- NodeIP和已知端口:DaemonSet中的Pod可以使用hostPort,以便可以通过Node节点IP访问Pod。客户端以某种方式知道节点IP列表,并按知道端口。
- DNS:使用相同的Pod选择器创建无头服务(headless service),然后使用该endpoints资源发现DaemonSets 或从DNS检索多个记录。
- 服务:使用相同的Pod选择器创建服务,并使用该服务在随机Node节点上访问守护程序。(无法到达特定节点。)

七、更新DaemonSet

如果更改了Node节点标签,DaemonSet会立即将Pod添加到新匹配的Node节点,并从不匹配的Node节点中删除Pod。可以修改DaemonSet创建的Pod。但是,不允许更新Pod所有字段。此外,DaemonSet控制器将在下次创建节点(即使具有相同名称)时使用原始模板。可以删除DaemonSet,如果通过kubectl指定了–cascade=false,则Pod会保留在Node节点上。可以使用不同的模板创建新的DaemonSet,具有不同模板的新DaemonSet将所有现有Pod识别为具有匹配标签。尽管Pod模板不匹配,它也不会修改或删除它们,需要通过删除Pod或删除节点来强制创建新的Pod。

相关