DaemonSet是Pod控制器的又一种实现,用于在集群中的全部节点上同时运行一份指定的Pod资源副本,后续新加入的集群工作节点也会自动创建一个相关的Pod对象,当从集群移除节点时,此类Pod对象也将被自动回收而无须重建。管理员也可以使用节点选择器及标签指定仅在部分具有特定特征的节点上运行指定的Pod对象。
DaemonSe的应用场景:
- 运行集群存储的守护进程,如在各个节点上运行 glusterd 或 ceph。
- 在各个节点上运行日志收集守护进程,如 fluentd 和 logstash。
- 在各个节点上运行监控系统的代理守护进程,如 Prometheus Node Exporter、collectd、Datadog agent、New Relic agent或Ganglia Gmond等。
创建DaemonSet资源对象
DaemonSet控制器的spec字段中嵌套使用的字段同样主要包括了前面讲到的Pod控制器资源支持的 selector、template、和minReadySeconds,并且功能和用法基本相同,但它不支持使用replicas,毕竟DaemonSet并不是基于期望的副本数来控制Pod资源数量,而是基于节点数量,但template是必选字段。
下面的资源配置清单logstash-ds.yaml
示例中定义来一个名logstash-ds的DaemonSet控制器。
1.创建DaemonSet控制器配置清单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
cat logstash-ds.yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: logstash-ds labels: app: agent-ds spec: selector: matchLabels: app: logstash template: metadata: labels: app: logstash spec: containers: - name: logstash-agent image: logstash:7.6.0 |
2.创建DaemonSet控制器
kubectl apply -f logstash-ds.yaml
3.查看控制器及Pod状态
1 2 3 4 5 6 7 8 9 10 11 |
#查看DaemonSet控制器状态,如下三个Pod还未就绪 kubectl get DaemonSet -o wide NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR logstash-ds 3 3 0 3 0 <none> 2m19s logstash-agent logstash:7.6.0 app=logstash #目前集群中共三个Node,如下每个Node上被运行了一个DaemonSet控制器中定义的Pod模版定义的Pod对象 kubectl get pods -o wide -l app=logstash NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES logstash-ds-6txcm 1/1 Running 0 5m50s 10.244.2.89 k8s-node02 <none> <none> logstash-ds-w6qtt 1/1 Running 0 5m50s 10.244.5.118 k8s-node03 <none> <none> logstash-ds-wff7n 1/1 Running 0 5m50s 10.244.3.147 k8s-node01 <none> <none> |
4.查看DaemonSet控制器的详细信息
如下:Node-Selector字段的值为空,表示它需要运行在集群中的每个节点之上(后续如果有新Node加入,那么DaemonSet控制器将自动在该Node上运行自身控制器中定义的Pod模版中的Pod对象),如果指定了Node-Selector那么,DaemonSet将只运行在所指定的Node上,下面Event事件中,显示创建三个Pod的过程。
5.指定Node运行DaemonSet控制器所定义的Pod对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
cat logstash-ds.yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: logstash-ds labels: app: agent-ds spec: selector: matchLabels: app: logstash template: metadata: labels: app: logstash spec: nodeName: k8s-node02 #指定节点hostname,与下面nodeSelector指定其一即可 nodeSelector: kubernetes.io/hostname: k8s-node02 #节点选择器,指定Node上的标签 containers: - name: logstash-agent image: logstash:7.6.0 |
更新控制器配置清单
kubectl apply -f logstash-ds.yaml
查看调度结果,如下只运行在了node02节点上
更新DaemonSet对象
DaemonSet从kubernetes1.6版本开始支持更新机制,更新配置定义在spec.updateStrategy
嵌套字段中。
DaemonSet目前支持RollingUpdate
(滚动更新)和OnDelete
(删除时更新)两种策略。
- RollingUpdate:滚动更新,默认为滚动更新策略,工作逻辑类似Deployment控制器,不过DaemonSet的滚动更新只支持
maxUnavailable
属性来定义最大不可用Pod资源副本数量(默认为1)。 - OnDelete:删除时更新的方法则是在删除相应节点的Pod对象后重新创建新版本并更新为新版本。
1.更新控制器配置清单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
cat logstash-ds.yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: logstash-ds labels: app: agent-ds spec: minReadySeconds: 10 #添加每个Pod升级后等待时间 revisionHistoryLimit: 6 #历史存储版本记录次数 updateStrategy: type: RollingUpdate #更新模式,滚动更新 rollingUpdate: maxUnavailable: 0 #更新时不可用的Pod服务为0个 selector: matchLabels: app: logstash template: metadata: labels: app: logstash spec: containers: - name: logstash-agent image: logstash:7.7.0 #将容器镜像升级为logstash:7.7.0 |
2.更新控制器
我下面使用kubectl apply
,当然你也可以使用kubectl set image
来替换镜像
kubectl apply -f logstash-ds.yaml
3.查看更新过程
如下,原本是一个logstatsh,然后DaemonSet控制器创建了两个新版本的Pod,随后删除了原来旧版本的Pod,又启动了一个新版本的Pod代替原老版本的Pod。
4.查看升级后的镜像
1 2 3 4 5 6 |
kubectl get pods -l app=logstash -o custom-columns=Name:metadata.name,Image:spec.containers[0].image Name Image logstash-ds-8ps8n logstash:7.7.0 logstash-ds-dbhx7 logstash:7.7.0 logstash-ds-pg8dz logstash:7.7.0 |
DaemonSet金丝雀发布
DaemonSet控制器在发布的时候也可以采用金丝雀发布风格,在特定Pod升级后,暂停升级,将流量导入升级后的Pod进行测试,测试无误后恢复所有Pod升级,DaemonSet金丝雀升级方法与Deployment金丝雀升级方法一致,这里不再演示。
DaemonSet回滚
DaemonSet回滚操作与Deployment也是同样操作,这里简单演示以下。
1.查看历史版本信息
1 2 3 4 5 6 7 |
kubectl rollout history ds logstash-ds daemonset.apps/logstash-ds REVISION CHANGE-CAUSE 1 <none> 2 <none> 3 <none> |
2.查看指定版本详细信息
1 2 3 4 5 6 7 8 9 10 11 12 13 |
kubectl rollout history ds logstash-ds --revision=1 daemonset.apps/logstash-ds with revision #1 Pod Template: Labels: app=logstash Containers: logstash-agent: Image: logstash:7.6.0 Port: <none> Host Port: <none> Environment: <none> Mounts: <none> Volumes: <none> |
3.回退到上次版本
kubectl rollout undo ds logstash-ds
4.回退到指定版本
kubectl rollout undo ds logstash-ds --to-revision=1