DaemonSet简介
DaemonSet:服务守护进程,它的主要作用是在k8s集群所有的节点中运行我们部署的守护进程,相当于在集群节点上分别部署pod副本,如果有新的节点加入集群,DaemonSet会自动在该节点上运行我们需要的部署的pod副本,相反,如果有节点退出户集群,DaemonSet也会移除部署在旧节点的pod副本。
1,DaemonSet的主要特征:
- 这个pod运行在k8s集群中每一个节点上(node)
- 每一个节点上只会运行一个这样的pod实例
- 如果新的节点加入k8s集群后,该pod会自动的在新节点上被创建出来
- 当旧节点被删除后,它上面的pod也相应的会被回收掉
2,DaemonSet常用场景:
- 网路组件的agent组件,如(Flannel,Calico)需要运行在每一个节点上,用来处理这个节点上的容器网路
- 存储插件的agent组件,如(Ceph),需要运行在每一个节点上,用来在这个节点上挂载远程存储目录
- 监控系统的数据收集组件,如(prometheus node exporter Cadvisor)需要运行在每一个节点上,负责在每一个节点上,负责这个节点上的监控信息收集
- 日志系统的数据收集组件,如(Fluent,Logstash)需要运行在每一个节点上,复制这个节点上的日志收集
DaemonSet的实现原理
DaemonSet开始运行的时机,很多时候比整个k8s集群出现的时机都要早,比如再创建k8s集群后,node的节点上由于没有可用的容器网路,集群节点状态会是Notready,普通的pod将无法运行,这就需要通过DaemonSet部署一个网路插件ahent组件。
1,DamonSet是如何确保每一个节点只运行一个pod?
- DaemonSet的控制器模型DaemonSet Controller先从Etcd里获取所有node列表
- 然后遍历所有的node检查,当前这个node节点上是不是只有一个携带了我们定义的标签的pod在运行
- 如果没有定义的pod,那么意味着要在这个node上创建这样的一个pod
- 如果有定义的pod,但是数量大于1,那么那么就说明要调用k8s api把多余的pod从这个node上删除掉掉
- 如果正好只有一个定义的pod,那说明这个节点是正常的
2,如果只在定义的节点上运行pod?
首先我们会想到使用nodeSelector字段来指定node的名字,但是在k8s项目里,nodeSelector起始已经将要废弃的字段了,因为,现在有一个新功能更完善的字段可以代替它,即:nodeAffinity。
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: metadata.name
operator: In
values:
- node-geektime
上面文件定义了spec.affinity字段,它是pod里面和调度相关的一个字段,然后又定义了一个nodeAffinity(节点关系),这里它的定义含义是:
- requiredDuringSchedulingIgnoredDuringExecution:它的意思是说,这个 nodeAffinity 必须在每次调度的时候予以考虑。同时,这也意味着你可以设置在某些情况下不考虑这个nodeAffinity
- 这个 Pod,将来只允许运行在“metadata.name”是“node-geektime”的节点上;
- 这个 Pod,将来只允许运行在“metadata.name”是“node-geektime”的节点上;
后面会有专门的随笔介绍node,pod的亲和性
DaemonSet Controller 会在创建 Pod 的时候,自动在这个 Pod 的 API 对象资源里,加上这样一个 nodeAffinity 定义。其中,需要绑定的节点名字,正是当前正在遍历的这个 Node。当然,DaemonSet 并不需要修改用户提交的 YAML 文件里的 Pod 模板,而是在向 Kubernetes 发起请求之前,直接修改根据模板生成的 Pod 对象。3,DaemonSet的污点和容忍(后面会有随笔详细介绍)
DaemonSet会有在这个pod自动加上另外的一个与调度相关的字段,叫做tolerations(容忍),这个字段意味着这个pod会容忍(Toleration)某些node的污点(taint),可以在有污点的节点上调度运行,从而保证每一个节点上都会被调度一个pod
DaemonSet字段添加的tolerations字段:
apiVersion: v1
kind: Pod
metadata:
name: with-toleration
spec:
tolerations:
- key: node.kubernetes.io/unschedulable
operator: Exists
effect: NoSchedule
在k8s集群中,当一个节点的网路插件尚未安装时,这个节点就会被自动加上名为:node.kubernetes.io/network-unavailable的污点,通过这样的英特tolerations,调度器在调度这个pod时候,就会忽略当前节点上的污点,从而成功的将网路组件的Agent调度到这个机器上来启动
...
template:
metadata:
labels:
name: network-plugin-agent
spec:
tolerations:
- key: node.kubernetes.io/network-unavailable
operator: Exists
effect: NoSchedule
尽管DaemonSet pod遵守污点(taint)和容忍(tolerations),但是一下的容忍会根据相关特性字段添加到DaemonSet管理的pod中
Toleration Key | 影响 | 版本 | 描述 |
---|---|---|---|
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+ | 当存在节点问题(如网络分区)时,DaemonSet pod不会被驱逐。 |
node.kubernetes.io/memory-pressure | NoSchedule | 1.8+ | 当存在节点问题(如网络分区)时,DaemonSet pod不会被驱逐。 |
node.kubernetes.io/unschedulable | NoSchedule | 1.12+ | 在默认的调度程序中,DaemonSet pod允许不可调度的属性。 |
node.kubernetes.io/network-unavailable | NoSchedule | 1.12+ | 使用主机网络的DaemonSet pod,默认调度器允许网络不可用属性。 |
DaemonSet的使用方法
定义一个DaemonSet
创建一个DaemonSet和Deployment相似,比如创建一个nginx的DaemonSet:
[root@k8s-master01 ns-slx-study]# cat DaemonSet.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
app: nginx-ds
name: nginx01-ds
spec:
selector:
matchLabels:
app1: nginx-mb-ds
template:
metadata:
labels:
app1: nginx-mb-ds
spec:
nodeSelector: #选择指定的node上的标签,是pod级别的
disktype: ssd
containers:
- name: nginx123
image: nginx:1.15.12
imagePullPolicy: IfNotPresent
1,必须字段
和其他所有 Kubernetes 配置一样,DaemonSet 需要 apiVersion、kind 和 metadata 字段,同时也需要一个.spec 配置段
2,pod模板
.spec 唯一需要的字段是.spec.template。.spec.template 是一个 Pod 模板,它与 Pod 具有相同的配置方式,但它不具有 apiVersion 和 kind 字段。除了 Pod 必需的字段外,在 DaemonSet 中的 Pod 模板必须指定合理的标签。
3,pod Selector
.spec.selector 字段表示 Pod Selector,它与其他资源的.spec.selector 的作用相同。
4,指定节点部署
nodeSelector 字段,必须在node上大对应的label
#创建命令
kubectl create -f DaemonSet.yaml
# 使用-o wide 可以查看 Pod 所在的节点时
kubectl get po -o wide
DaemonSet更新和回滚
如果添加了新节点或修改了节点标签(Label),DaemonSet 将立刻向新匹配上的节点添加Pod,同时删除不能匹配的节点上的 Pod。
在k8s1.16以后的版本中,可以在DaemonSet 上执行滚动更新,未来的 Kubernetes 版本将支持节点的可控更新
DaemonSet 更新策略和 StatefulSet 类似,也有 OnDelete 和 RollingUpdate 两种方式。
updateStrategy:
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
type: RollingUpdate
方式:edit 和yaml ,更建议使用edit的方式
命令行方式(不建议)
#更新
kubectl edit ds/<daemonset-name>
kubectl patch ds/<daemonset-name> -p=<strategic-merge-patch>
#更新镜像
kubectl set image ds/<daemonset-name><container-name>= <container-newimage> --record=true
#查看更新状态
kubectl rollout status ds/<daemonset-name>
#列出所有修订版本
kubectl rollout history daemonset <daemonset-name>
#回滚到指定revision
kubectl rollout undo daemonset <daemonset-name> --to-revision=<revision>
DaemonSet 的更新和回滚与 Deployment 类似
标签:node,spec,DaemonSet,节点,Pod,pod
From: https://www.cnblogs.com/slx-yyds/p/17153657.html