一、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。
评论