一、DaemonSet概述
官方文档: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文件
test.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应用
kubectl apply -f test.yaml
daemonset.apps/ds-test created
#2.查看DaemonSet应用
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查看
> 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
由 DaemonSet 控制器调度(自1.12版本起,默认禁用)
通常,由Kubernetes调度器选择Pod所运行的机器。但是,由DaemonSet控制器创建的Pod,在创建是就已经为Pod 选择了机器(在创建Pod时指定.spec.nodeName,因此调度器会忽略它)。因此:
- DaemonSet 控制器将不会考虑 unschedulable的Node 节点。
- 即使尚未启动调度器,DaemonSet 控制器也可以生成 Pod,这可以帮助集群引导程序。
由默认调度器调度(自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节点。
污点和容忍
根据相关特性,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。
评论