K8S 之 DaemonSet
摘要
-
本文介绍 K8S 的 DaemonSet ,本文以 CentOS 8 为例。
DaemonSet 介绍
-
DaemonSet 定义了提供节点本地设施的 Pod。这些设施可能对于集群的运行至关重要,例如网络辅助工具,或者作为 add-on 的一部分。
-
DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。 当有节点加入集群时, 也会为他们新增一个 Pod 。 当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
-
DaemonSet 的一些典型用法:
- 在每个节点上运行集群守护进程
- 在每个节点上运行日志收集守护进程
- 在每个节点上运行监控守护进程
-
DaemonSet 与 Deployment 的主要区别是:
- 无法自定义副本数量
- 每个node上都会运行且只允许运行一个 Pod
- 当有新Node加入集群时,会自动在其上部署并运行Pod副本,当Node从集群移除时,这些Pod也会被回收
DaemonSet 管理
DaemonSet 创建
-
DaemonSet 只能 通过
yaml
创建,不支持create
创建
1 | # 通过 yaml 文件创建 |
-
一个简单的
daemonset.yaml
文件说明
1 | apiVersion: apps/v1 # 指定使用的 API 版本,这里是 apps/v1,适用于 DaemonSet 资源 |
查看 DaemonSet
1 | # 查看 DaemonSet ,默认显示 default 命名空间下的 DaemonSet |
允许 master 节点运行 pod
-
上面看到pod只在worker1和worker2上运行,而没有在master节点上运行
-
默认情况下,Kubernetes 不允许在 master 节点上运行 Pod,这是因为master节点有污点
1 | $ kubectl describe node k8s-master | grep Taints |
-
为了能让pod运行在具有污点的节点上,我们需要为pod指定容忍度(tolerations),实际上 DaemonSet 控制器会自动将一组容忍度添加到 DaemonSet Pod
容忍度键名 | 效果 | 操作 | 描述 |
---|---|---|---|
node.kubernetes.io/not-ready |
NoExecute |
Exists | DaemonSet Pod 可以被调度到不健康或未就绪的节点上,且不会被驱逐。 |
node.kubernetes.io/unreachable |
NoExecute |
Exists | DaemonSet Pod 可以被调度到不可达的节点上,且不会被驱逐。 |
node.kubernetes.io/disk-pressure |
NoSchedule |
Exists | DaemonSet Pod 可以被调度到存在磁盘压力的节点上。 |
node.kubernetes.io/memory-pressure |
NoSchedule |
Exists | DaemonSet Pod 可以被调度到存在内存压力的节点上。 |
node.kubernetes.io/pid-pressure |
NoSchedule |
Exists | DaemonSet Pod 可以被调度到存在进程数压力的节点上。 |
node.kubernetes.io/unschedulable |
NoSchedule |
Exists | DaemonSet Pod 可以被调度到标记为不可调度的节点上。 |
node.kubernetes.io/network-unavailable |
NoSchedule |
Exists | 针对 spec.hostNetwork: true 的 Pod,可以被调度到网络不可用的节点上。 |
-
增加可以运行在 master 节点的容忍度
1 | apiVersion: apps/v1 |
-
增加容忍度后重新运行
1 | kubectl apply -f daemonset.yaml |
访问pod中的nginx服务
-
此时我们还没有创建
Service
(后面章节会介绍),所以只能通过 Pod 的 IP 访问
1 | # 任意pod的IP,端口80 |
查看 DaemonSet 详情
-
当 DaemonSet 运行错误时,可以通过该命令查看 DaemonSet 的详情,找到错误原因
1 | kubectl describe ds <ds-name> |
删除 DaemonSet
1 | kubectl delete ds <ds-name> |
查看 DaemonSet 日志
1 | kubectl logs ds/<ds-name> |
滚动升级与回滚 DaemonSet
-
对
RollingUpdate
类型的DaemonSet
的.spec.template
的任何更新都将触发滚动更新。 -
我们修改过
DaemonSet
的.spec.template
,并保存后,重新运行kubectl apply -f <yaml-file>
即可触发滚动升级。 -
如果只是更新容器的镜像,也可以通过如下命令触发滚动升级
1 | # kubectl set image ds/<ds-name> <container-name>=<image>:<tag> --record=true |
-
查看滚动升级状态
1 | # kubectl rollout status ds/<ds-name> |
-
查看历史版本
1 | # 前面的序号表示版本号 |
-
回滚
1 | # 回退到前一个版本 |
Deployment 和 DaemonSet 的对比总结
特性 | Deployment | DaemonSet |
---|---|---|
用途 | 管理一组可水平扩展的 Pod,按需副本数运行 | 在每个(或特定)节点上运行 一个副本 的 Pod |
常见场景 | 无状态服务、Web 服务、API、后端服务 | 日志采集(如 fluentd)、监控(如 node-exporter)、系统守护进程 |
副本控制 | 可通过 spec.replicas 灵活控制副本数 |
每个匹配的节点自动运行一个 Pod,无需设置 replicas |
节点分布 | Pod 分布随机,调度器选择可用节点 | Pod 分布固定,每个匹配节点必跑一个 Pod |
更新策略 | RollingUpdate (默认)、Recreate ,支持回滚 |
RollingUpdate (默认从 Kubernetes 1.6 起支持) |
伸缩方式 | kubectl scale deployment 可以水平扩缩容 |
不支持手动伸缩,跟随节点变化自动伸缩 |
Pod 更新行为 | 按策略滚动更新全部副本 | 每个节点上的 Pod 逐个滚动更新 |
调度策略 | 通过调度器分配节点,可搭配 affinity 使用 |
默认调度所有节点,可用 nodeSelector 、affinity 、taints 控制 |