DaemonSet
工作负载,确保了全部(某一些)节点运行一个 Pod
副本
如果有节点加入集群,自动为该节点新增一个 Pod
如果有节点从集群中移除,该节点上的 Pod
就会被回收
删除工作负载 DaemonSet
就会删除它创建的所有节点的 Pod
还是老规矩:kubectl explain ds
apiVersion >
kind >
metadata
kubectl explain ds.spec
必须字段
apiVersion
、kind
和 metadata
.spec
.spec.template
.spec.selector
特定节点运行
如果指定了 .spec.template.spec.nodeSelector
,DaemonSet 控制器将在能够与 Node 选择算符匹配的节点上创建 Pod。 类似这种情况,可以指定 .spec.template.spec.affinity
,之后 DaemonSet 控制器 将在能够与节点亲和性 匹配的节点上创建 Pod。 如果根本就没有指定,则 DaemonSet Controller 将在所有节点上创建 Pod
###ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
运行查看一下结果
DS
资源会在每一个节点只运行一个,控制节点除外,好像要特殊设置才行,遇到了我再看看spec.affinity.nodeAffinity
字段以匹配目标主机:kubectl get ds fluentd-elasticsearch
.spec.nodeName
字段来接管 Pod 并将 Pod 绑定到目标主机,如果新的 Pod 无法放在节点上,默认的调度程序可能会根据新 Pod 的优先级抢占某些现存的 Pod用户通过设置 DaemonSet 的
.spec.template.spec.schedulerName
字段,可以为 DamonSet 的 Pod 指定不同的调度程序。不设置就是default-scheduler
关于亲和性、污点、容忍度后续进行一个补充
如果节点的标签被修改,DaemonSet 将立刻向新匹配上的节点添加 Pod, 同时删除不匹配的节点上的 Pod
你可以修改 DaemonSet 创建的 Pod。不过并非 Pod 的所有字段都可更新。 下次当某节点(即使具有相同的名称)被创建时,DaemonSet 控制器还会使用最初的模板
你可以删除一个 DaemonSet。如果使用 kubectl
并指定 --cascade=orphan
选项, 则 Pod 将被保留在节点上。接下来如果创建使用相同选择算符的新 DaemonSet, 新的 DaemonSet 会收养已有的 Pod。 如果有 Pod 需要被替换,DaemonSet 会根据其 updateStrategy
来替换
可以对 DaemonSet 执行滚动更新操作
参考官网地址:
https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/daemonset/#required-fields
参考官网地址:
https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/workload-resources/daemon-set-v1/
apiVersion: apps/v1
kind: DaemonSet
metadata
标准的对象元数据
spec
此守护进程集的预期行为
selector 必需
对由守护进程集管理的 Pod 的标签查询。Pod 必须匹配此查询才能被此 DaemonSet 控制。 查询条件必须与 Pod 模板的标签匹配
template 必需
描述将要创建的 Pod 的对象。DaemonSet 将在与模板的节点选择器匹配的每个节点上 (如果未指定节点选择器,则在每个节点上)准确创建此 Pod 的副本
minReadySeconds (int32)
新建的 DaemonSet Pod 应该在没有任何容器崩溃的情况下处于就绪状态的最小秒数,这样它才会被认为是可用的。 默认为 0(Pod 准备就绪后将被视为可用)
updateStrategy (DaemonSetUpdateStrategy)
用新 Pod 替换现有 DaemonSet Pod 的更新策略
revisionHistoryLimit (int32)
用来允许回滚而保留的旧历史记录的数量。此字段是个指针,用来区分明确的零值和未指定的指针。默认值是 10
我打算每个节点都运行一个基于 nginx 的 Pod
示例文件
###ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ds-demo
labels:
k8s-app: nginx
spec:
selector:
matchLabels:
name: app
template:
metadata:
labels:
name: app
spec:
tolerations:
#这些容忍度设置是为了让该守护进程集在控制平面节点上运行
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
containers:
- name: nginx
image: nginx:1.23
imagePullPolicy: Never ##这个镜像拉取我是真的难受 直接弄本地来吧
运行查看一下
尝试删除一个 Pod
##尝试删除一下 k8s-02上面的pod,跟着一下状态
kubectl delete pod ds-demo-dlzh4
DaemonSet 有两种更新策略:
OnDelete
: 使用 OnDelete
更新策略时,在更新 DaemonSet 模板后,只有当你手动删除老的 DaemonSet pods 之后,新的 DaemonSet Pod 才会被自动创建。跟 Kubernetes 1.6 以前的版本类似。RollingUpdate
: 这是默认的更新策略。使用 RollingUpdate
更新策略时,在更新 DaemonSet 模板后, 老的 DaemonSet Pod 将被终止,并且将以受控方式自动创建新的 DaemonSet Pod。 更新期间,最多只能有 DaemonSet 的一个 Pod 运行于每个节点上kubectl explain ds.spec.updateStrategy
我要对上面的资源更新一个镜像,修改一下 yaml 文件
###ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ds-demo
labels:
k8s-app: nginx
spec:
selector:
matchLabels:
name: app
updateStrategy: ## 更新
type: RollingUpdate ## 更新策略
rollingUpdate: ##更新参数,仅在 type 值为 "RollingUpdate" 时出现
maxUnavailable: 1 ##更新期间不可用的 DaemonSet Pod 的最大数量
template:
metadata:
labels:
name: app
spec:
tolerations:
#这些容忍度设置是为了让该守护进程集在控制平面节点上运行
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
containers:
- name: nginx
image: nginx:1.23.3
imagePullPolicy: Never ##这个镜像拉取我是真的难受 直接弄本地来吧
更新一下,并跟踪状态
查看更新状态
[root@k8s-01 k8s-yaml]# kubectl rollout status ds ds-demo
daemon set "ds-demo" successfully rolled out
[root@k8s-01 k8s-yaml]#
我们再更新一次,换一种方式
###ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ds-demo
labels:
k8s-app: nginx
spec:
selector:
matchLabels:
name: app
updateStrategy: ## 更新
type: OnDelete ## 更新策略
template:
metadata:
labels:
name: app
spec:
tolerations:
#这些容忍度设置是为了让该守护进程集在控制平面节点上运行
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
containers:
- name: nginx
image: nginx:1.23
imagePullPolicy: Never ##这个镜像拉取我是真的难受 直接弄本地来吧
更新运行看状态:kubectl apply -f ds.yaml
杀死一个 Pod 试试
[root@k8s-01 k8s-yaml]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ds-demo-6fxtx 1/1 Running 0 6m44s 192.168.0.135 k8s-02 <none> <none>
ds-demo-8zlpb 1/1 Running 0 6m29s 192.168.0.74 k8s-01 <none> <none>
ds-demo-9r7hv 1/1 Running 0 6m18s 192.168.0.7 k8s-03 <none> <none>
[root@k8s-01 k8s-yaml]# kubectl delete pod ds-demo-8zlpb
pod "ds-demo-8zlpb" deleted
[root@k8s-01 k8s-yaml]#
看一下是否更新完成:镜像是否改变 kubectl describe pod ds-demo-qgd49
DS 修订版本
kubectl explain ds.spec
中的 [revisionHistoryLimit] 确认了版本保留的数量,默认就是10
查看 DS 的所有版本
kubectl rollout history ds ds-demo
查看指定版本的详细信息
kubectl rollout history ds ds-demo --revision=2
回滚到指定版本
kubectl rollout undo ds ds-demo --to-revision=2
查看更新结果
因为我之前改过更新策略,我必须杀死 Pod 后,才能回退成功
查看回滚进度
kubectl rollout status ds ds-demo
[root@k8s-01 k8s-yaml]# kubectl rollout status ds ds-demo
error: rollout status is only available for RollingUpdate strategy type
[root@k8s-01 k8s-yaml]#
如果 DS 更新卡住的话,可能有以下一些原因:
.spec.minReadySeconds
,主控节点和工作节点之间的时钟偏差会使 DaemonSet 无法检测到正确的滚动更新进度