Kubernetes(K8s)笔记Day08 :DaemonSet 控制器 ,系统自动污点与 DaemonSet 特殊容忍度, Pod 优先级(QoS Class)

📅 2026/8/8 9:23:33
Kubernetes(K8s)笔记Day08 :DaemonSet 控制器 ,系统自动污点与 DaemonSet 特殊容忍度, Pod 优先级(QoS Class)
一、DaemonSet 控制器概念、原理解读1.1 什么是 DaemonSetDaemonSet 是 Kubernetes 中的一个工作负载控制器用于确保集群中的每个节点上都运行一个指定的 Pod 副本。核心行为节点加入当新节点加入集群时DaemonSet 会自动在新节点上创建 Pod节点删除当节点被删除时对应的 Pod 会被回收节点移除当节点被从集群中移除时其上的 DaemonSet Pod 也会被清理1.2 工作原理DaemonSet 控制器通过以下机制实现其功能监听 API Server实时获取当前集群的节点列表对比状态将当前节点列表与已创建的 Pod 进行对比自动调度发现某个节点上没有对应的 Pod 时通过调度器或直接指定节点创建 Pod关键特性每个节点有且只有一个该 DaemonSet 管理的 Pod默认行为Pod 的名称由 DaemonSet 自动生成格式为daemonset-name-随机后缀当节点标签变化导致不再匹配 selector 时Pod 会被自动删除1.3 应用场景节点守护类每个节点都需要运行的组件类别典型组件日志收集Fluentd、Filebeat、Logstash监控代理Prometheus Node Exporter、Datadog Agent、Zabbix Agent网络插件Calico、Flannel、Cilium 的 Agent 组件存储插件CSIContainer Storage Interface节点驱动安全扫描Falco、Sysdig、Aqua Agent系统服务类组件说明kube-proxy每个节点都需要运行实现 Service 的网络代理Calico网络插件提供跨节点 Pod 通信能力节点网络配置如 Macvlan、Multus 等 CNI 插件为什么 DaemonSet 适合这些场景日志收集需要在每个节点上采集所有容器的日志监控代理需要采集每个节点的系统指标网络插件需要在每个节点上配置网络规则和路由存储驱动需要在每个节点上挂载存储卷二、DaemonSet 使用案例2.1 每个节点上部署日志采集Fluentd完整 YAML 示例[roothd1 ~]# cat daemonset.yamlapiVersion:apps/v1kind:DaemonSetmetadata:name:fluentd-elasticsearchnamespace:kube-system# 部署在 kube-system 命名空间与系统组件统一管理labels:k8s-app:fluentd-loggingspec:selector:matchLabels:name:fluentd-elasticsearchtemplate:#pod模板metadata:labels:# Pod 标签必须被 selector 匹配name:fluentd-elasticsearchspec:tolerations:-key:node-role.kubernetes.io/control-plane# 针对 master/control-plane 节点的污点effect:NoSchedule# 允许 Pod 调度到有该污点的节点上containers:-name:fluentd-elasticsearchimage:docker.io/library/fluentd:v2.5.1imagePullPolicy:IfNotPresentresources:#容器的资源限制limits:memory:200Mirequests:cpu:100mmemory:200MivolumeMounts:#挂载点-name:varlog# 引用下方 volumes 中定义的卷mountPath:/var/log# 挂载到容器内的 /var/log 目录terminationGracePeriodSeconds:30#优雅终止时间volumes:#存储卷定义-name:varlog# 卷名称被 volumeMounts 引用hostPath:path:/var/log# 宿主机上的 /var/log 目录该目录下包含了所有容器和系统组件的日志文件YAML 完整字段解析字段说明kind: DaemonSet资源类型表示为 DaemonSet 控制器namespace: kube-system通常部署在系统命名空间与系统组件统一管理selector.matchLabels标签选择器用于匹配 DaemonSet 管理的 PodtemplatePod 模板定义要部署的 Pod 规格tolerations容忍度配置允许调度到控制平面节点master 节点resources资源限制保证日志采集不占用过多资源volumeMounts挂载宿主机的/var/log目录到容器中采集容器日志hostPath使用宿主机路径挂载直接读取节点上的日志文件# # DaemonSet在每个节点上部署 Fluentd 日志采集器# apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd-elasticsearch# DaemonSet 名称namespace: kube-system# 部署在 kube-system 命名空间与系统组件统一管理labels: k8s-app: fluentd-logging# 便于通过标签筛选该 DaemonSetspec:# ---------- 标签选择器 ----------selector: matchLabels: name: fluentd-elasticsearch#必须与 template.metadata.labels 保持一致# 否则 Kubernetes 拒绝创建# ---------- Pod 模板 ----------template: metadata: labels: name: fluentd-elasticsearch# Pod 标签必须被 selector 匹配spec:# ---------- 容忍度允许调度到 master 节点 ----------tolerations: - key: node-role.kubernetes.io/control-plane# 针对 master/control-plane 节点的污点effect: NoSchedule# 允许 Pod 调度到有该污点的节点上# 让日志采集器也能采集 master 节点的日志# ---------- 容器定义 ----------containers: - name: fluentd-elasticsearch image: docker.io/library/fluentd:v2.5.1 imagePullPolicy: IfNotPresent# 镜像拉取策略本地存在则不拉取# ---------- 资源限制 ----------resources: limits: memory: 200Mi# 最大可用内存 200Mi防止日志采集占用过多资源requests: cpu: 100m# 保证至少 0.1 核 CPUmemory: 200Mi# 保证至少 200Mi 内存# ---------- 挂载点 ----------volumeMounts: - name: varlog# 引用下方 volumes 中定义的卷mountPath: /var/log# 挂载到容器内的 /var/log 目录# 这样 Fluentd 就能读取宿主机上所有容器的日志文件# ---------- 优雅终止时间 ----------terminationGracePeriodSeconds:30# Pod 收到 SIGTERM 信号后最多等待 30 秒# 让 Fluentd 有机会将缓冲区中的日志发送完毕再退出# ---------- 存储卷定义 ----------volumes: - name: varlog# 卷名称被 volumeMounts 引用hostPath:# hostPath 类型挂载宿主机的目录path: /var/log# 宿主机上的 /var/log 目录# 该目录下包含了所有容器和系统组件的日志文件部署与验证[roothd1 ~]# kubectl apply -f daemonset.yamldaemonset.apps/fluentd-elasticsearch created# 查看 DaemonSet 状态需要指定命名空间[roothd1 ~]# kubectl get ds -n kube-systemNAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE fluentd-elasticsearch33333none23m# 查看 Pod 在各节点的分布情况[roothd1 ~]# kubectl get pods -n kube-system -o wide | grep fluentdfluentd-elasticsearch-d22wn1/1 Running022m10.244.59.173 hd2 fluentd-elasticsearch-pmqzx1/1 Running022m10.244.169.95 hd3 fluentd-elasticsearch-tm8rz1/1 Running022m10.244.66.67 hd1验证要点每个节点上正好运行一个 Fluentd Pod数量和节点数一致。2.2 DaemonSet 滚动更新DaemonSet 支持两种更新策略策略说明适用场景RollingUpdate默认各个节点逐步替换 Pod先删旧 Pod再建新 Pod可配置maxUnavailable控制同时不可用的 Pod 数量例如 10% 或 1 个生产环境需要平滑升级OnDelete只有当用户手动删除旧的 Pod 时才会创建新版本的 Pod需要精细控制更新节奏的场景查看更新策略定义[roothd1 ~]# kubectl explain ds.spec.updateStrategyFIELDS: rollingUpdateObjecttypestring# 查看 rollingUpdate 支持的参数[roothd1 ~]# kubectl explain ds.spec.updateStrategy.rollingUpdateFIELDS: maxUnavailablestring# 可以指定为数字或百分比更新策略的工作机制由于 DaemonSet 保证每个节点最多运行一个 Pod因此滚动更新时采用“先删后建”的策略先删除旧 Pod等待旧 Pod 完全终止再创建新 Pod这与 Deployment 的滚动更新先建新 Pod再删旧 Pod不同因为节点资源限制不允许两个 Pod 同时存在。三、系统自动污点与 DaemonSet 特殊容忍度Tolerations3.1 什么是污点和容忍度概念说明污点Taint标记在节点上的属性用于排斥Pod 调度到该节点容忍度Toleration标记在 Pod 上的属性允许 Pod 被调度到具有特定污点的节点上关系节点有污点Pod 有容忍度才能调度上去。容忍度是 Pod 对节点污点的“免疫”声明。3.2 节点自动污点系统污点Kubernetes 集群会在节点出现特定问题时由节点控制器Node Controller或kubelet自动为其添加污点用于标记节点状态从而触发 Pod 的驱逐或阻止新 Pod 调度。这是一种保障集群整体稳定性的自愈机制。常见的系统自动污点污点名Taint触发条件Node Condition效果Effect主要触发组件node.kubernetes.io/not-ready节点未就绪ReadyFalseNoExecute节点控制器node.kubernetes.io/unreachable节点无法访问ReadyUnknownNoExecute节点控制器node.kubernetes.io/memory-pressure节点内存有压力NoSchedulekubeletnode.kubernetes.io/disk-pressure节点磁盘有压力NoSchedulekubeletnode.kubernetes.io/pid-pressure节点PID有压力NoSchedulekubeletnode.kubernetes.io/network-unavailable节点网络不可用NoSchedulekubelet / 云厂商控制器node.kubernetes.io/unschedulable节点被标记不可调度kubectl cordonNoSchedulekubectl / 控制器node.kubernetes.io/out-of-disk节点磁盘空间已满NoSchedulekubeletnode.cloudprovider.kubernetes.io/uninitialized节点刚启动未完成初始化NoSchedulekubelet外部云环境3.3 污点效果Effect说明效果说明NoSchedule阻止新的 Pod 调度到该节点但不影响已在运行的 PodNoExecute不仅阻止新 Pod 调度还会驱逐节点上已运行且没有对应容忍度的 PodPreferNoSchedule软性限制尽量避免调度到该节点但无法避免时也会调度3.4 普通 Pod 的默认容忍度Kubernetes 会为每个 Pod自动添加对以下污点的容忍度默认 300 秒污点容忍时间node.kubernetes.io/not-ready300 秒node.kubernetes.io/unreachable300 秒设计目的当节点出现短暂网络问题5 分钟内恢复时上面的 Pod 不会被立即驱逐避免了因网络抖动而引发的大规模 Pod 重调度。生效逻辑节点在 300 秒内恢复 → Pod 继续运行无感知节点超过 300 秒未恢复 → Pod 被驱逐调度到其他健康节点3.5 DaemonSet Pod 的特殊容忍度DaemonSet 管理的 Pod 天生对这些节点问题污点具有无限无穷大的容忍时间因此节点失联时DaemonSet Pod 不会被驱逐目的确保节点出现故障时日志收集、监控、网络代理等系统级组件依然能够工作例如即使节点处于NotReady状态Fluentd 依然能收集已有的日志并尝试发送关键区别普通 Deployment Pod节点失联 300 秒后被驱逐DaemonSet Pod节点失联后无限等待不驱逐四、Pod 优先级QoS Class4.1 什么是 QoSQuality of ServiceQoSQuality of Service服务质量是 Kubernetes 对 Pod 资源请求requests和限制limits的分类机制用于在资源压力较大时决定 Pod 的驱逐优先级哪些 Pod 优先被杀死以释放资源。4.2 QoS 等级对比QoS 等级不是一个你可以手动设置的字段而是由 Kubernetes 根据 Pod 里的resources.requests和resources.limits字段自动计算出来的标签等级QoS保证程度驱逐优先级高压力下典型使用场景判定标准Pod 内所有容器需满足Guaranteed保证最高保证资源完全隔离性能最稳定最低最后被驱逐核心关键业务数据库、支付、订单服务等所有容器同时满足1. 都设置了requests和limits2. 所有requests和limits的值都相等3.requests值必须大于 0Burstable可突发部分保证保证requests额外资源尽力而为中等在 BestEffort 之后被驱逐常规在线业务大部分微服务能容忍小幅资源竞争1. 不满足 Guaranteed 的条件2.至少一个容器设置了requests或limitsBestEffort尽力而为无任何保证资源紧缺时最脆弱最高最先被驱逐低优先级批处理任务测试环境、数据处理、离线分析等Pod 内所有容器均未设置requests和limits4.3 QoS 判定规则关键原则最严格容器决定 Pod 等级一个 Pod 包含多个容器时取最严格的等级作为整个 Pod 的 QoS 等级如果有一个容器是BestEffort整个 Pod 就是BestEffort如果有容器是Guaranteed也有容器是Burstable整个 Pod 就是Burstable资源单位说明m毫核千分之一核心例如200m 0.2 个 CPU 核心MiMebibyte二进制写法兆比字节例如200Mi 200 × 1024 × 1024 字节4.4 QoS 示例Guaranteed Pod[roothd1 ~]# cat pod-guaranteed.yamlapiVersion:v1kind:Podmetadata:name:my-guaranteedlabels:app:mynginxspec:containers:-name:mycontainersimage:docker.io/library/nginx:latestimagePullPolicy:IfNotPresentresources:#资源限制字段limits:cpu:200mmemory:200Mirequests:cpu:200m# 与 limits.cpu 相等memory:200Mi# 与 limits.memory 相等判定requestslimits且均大于 0 →Guaranteed(保证)#应用[roothd1 ~]# kubectl apply -f my-guaranteed.yamlpod/my-guaranteede created# 查看 Pod 的 QoS 等级[roothd1 ~]# kubectl describe pod my-guaranteed | grep -i QosQoS Class: GuaranteedBurstable Pod[roothd1 ~]# cat pod-burstable.yamlapiVersion:v1kind:Podmetadata:name:my-burstablelabels:app:mynginxspec:containers:-name:mycontainersimage:docker.io/library/nginx:latestimagePullPolicy:IfNotPresentresources:limits:cpu:300mmemory:300Mirequests:cpu:200m# 与 limits.cpu 不相等memory:200Mi# 与 limits.memory 不相等判定不满足 Guaranteed 条件且有 requests 设置 →Burstable可突发#应用[roothd1 ~]# kubectl apply -f pod-burstable.yamlpod/my-burstable created# 查看 Pod 的 QoS 等级[roothd1 ~]# kubectl describe pod my-burstable | grep -i QosQoS Class: BurstableBestEffort Pod[roothd1 ~]# cat pod-besteffort.yamlapiVersion:v1kind:Podmetadata:name:my-besteffortlabels:app:mynginxspec:containers:-name:mycontainersimage:docker.io/library/nginx:latestimagePullPolicy:IfNotPresent# 没有 resources 设置判定所有容器均未设置requests和limits→BestEffort#应用[roothd1 ~]# kubectl apply -f pod-besteffort.yamlpod/my-besteffort created# 查看 Pod 的 QoS 等级[roothd1 ~]# kubectl describe pod my-besteffort | grep -i QosQoS Class: BestEffort4.5 驱逐顺序总结由低到高资源压力增大时驱逐顺序 Last Evicted ←───────────────────────────→ First Evicted ↑ ↑ Guaranteed BestEffort (最稳定) (最脆弱)驱逐优先级QoS 等级说明最低最后被驱逐Guaranteed核心业务必须保障中等Burstable常规业务适当保障最高最先被驱逐BestEffort非核心任务随时可牺牲五、核心知识点速查DaemonSet 核心要点知识点说明定义确保每个节点运行一个 Pod 副本自动调度新节点加入 → 自动创建 Pod节点删除 → 自动回收 Pod应用场景日志收集Fluentd、监控代理Node Exporter、网络插件Calico、存储驱动CSI更新策略RollingUpdate默认逐步替换和OnDelete手动触发节点故障容忍DaemonSet Pod 对节点问题污点具有无限容忍不会被驱逐污点与容忍度要点知识点说明污点节点排斥 Pod 的机制容忍度Pod 允许调度到有污点节点的机制系统自动污点节点出现NotReady、MemoryPressure等问题时自动添加普通 Pod 默认容忍not-ready和unreachable容忍 300 秒DaemonSet Pod 容忍无限容忍节点故障时不驱逐QoS 要点知识点说明Guaranteedrequestslimits最高保障最后被驱逐Burstablerequestslimits或只设其一中等保障BestEffort不设requests和limits最低保障最先被驱逐驱逐顺序BestEffort → Burstable → Guaranteed判定原则最严格的容器决定整个 Pod 的 QoS 等级