Kubernetes Node 节点完全指南:管理、状态、污点调度与优雅关闭机制
云原生教程【免费下载链接】kubernetes-handbookKubernetes Handbook Kubernetes指南 https://kubernetes.feisky.xyz项目地址https://gitcode.com/gh_mirrors/kub/kubernetes-handbook点击查看免费下载Node 是 Kubernetes 集群中真正承载工作负载的主机物理机或虚拟机也是 Pod 调度的基本单元。本文以 Kubernetes Handbook 仓库中的 Node 章节 为主体系统讲解 Node 的组件构成、节点管理机制、状态字段、Taints/Tolerations 调度约束以及优雅关闭、非优雅关闭和 v1.33 动态节点资源分配等关键运维能力并结合仓库源码与配置佐证帮助读者从原理到实操完整掌握 Node 节点的管理。Node 在 Kubernetes 中的定位在 Kubernetes 集群中Node 是 Pod 真正运行的主机可以是物理机也可以是虚拟机。为了管理 Pod每个 Node 节点上至少要运行三类服务container runtime如docker、containerd或rkt真正负责镜像与容器的生命周期管理kubelet接收并执行 Master 发来的指令管理 Pod 及 Pod 中的容器kube-proxy监听 API Server 中 Service 和 Endpoint 的变化为 Service 提供集群内部的负载均衡。仓库 核心组件章节 给出了完整的端口对照Node 节点上常见端口包括10248kubelet healthz、10249kube-proxy metrics、10250kubelet API、10255只读 kubelet API、10256kube-proxy healthz、4194kubelet cAdvisor以及 30000-32767NodePort Service 范围。下图展示了 Node 节点内部的组件构成与 Pod 承载关系图片来自仓库 architecture/images/node.pngNode 上关键组件的启动配置从仓库的 systemd 单元文件可以看到 kubelet 的常规启动方式。manifests/systemd/kubelet.service 中 kubelet 通过环境变量文件-/etc/kubernetes/config与-/etc/kubernetes/kubelet注入参数关键变量包括KUBELET_ADDRESSkubelet 监听地址如--address172.20.0.113KUBELET_HOSTNAME节点主机名覆盖如--hostname-override172.20.0.113KUBELET_API_SERVERAPI Server 地址KUBELET_POD_INFRA_CONTAINERPod 基础设施容器pause镜像KUBELET_ARGS其余参数如--cgroup-driversystemd --cluster-dns10.254.0.2 --cluster-domaincluster.local.等。完整示例参见 etc/kubernetes/kubelet。kubelet 的详细工作原理syncLoop、PLEG、CRI 接口、Pod 启动流程等可参考 kubelet 章节。Node 管理Node 不是 Kubernetes 创建的与 Pod、Namespace 等资源不同Node 本质上不是由 Kubernetes 创建的Kubernetes 只是管理 Node 上的资源。虽然可以通过 Manifest 创建一个 Node 对象如下 YAML 所示但 Kubernetes 也只会去检查是否真的有这么一个 Node如果检查失败也不会向该 Node 调度 Podkind: Node apiVersion: v1 metadata: name: 10-240-79-157 labels: name: my-first-k8s-node这个检查由Node Controller完成。Node Controller 是 kube-controller-manager 中的核心控制器完整控制器清单见 controller-manager 章节负责维护 Node 状态与 Cloud Provider 同步 Node给 Node 分配容器 CIDR删除带有NoExecutetaint 的 Node 上的 Pods。默认情况下kubelet 在启动时会向 master 注册自己并创建 Node 资源。kubelet 通过--register-node参数决定是否自注册若 kubelet 选择自注册模式启动时通过 API Server 注册节点信息并定时向 API Server 发送节点新消息API Server 将信息写入 etcd若未选择自注册则需要用户自行配置 Node 资源信息同时告知 kubelet API Server 的位置。在启用 Cloud Provider 的集群中kubelet 还会自动给 Node 添加node.cloudprovider.kubernetes.io/uninitializedNoScheduletaint由 cloud-controller-manager 在初始化完成后移除相关时序问题的解决方案见 cloud-provider 章节。Node 的状态信息每个 Node 都包含以下五类状态信息地址Addresses包括 hostname、外网 IP 和内网 IP条件Conditions包括OutOfDisk、Ready、MemoryPressure和DiskPressure容量CapacityNode 上的可用资源包括 CPU、内存和 Pod 总数可分配AllocatableNode 上可分配给 Pod 的资源量包括 CSI 卷附件限制等动态资源基本信息Info包括内核版本、容器引擎版本、OS 类型等。Node 条件直接影响调度决策调度器章节 总结了两个关键规则如果 Node Condition 处于MemoryPressure则所有 BestEffort 的新 Pod未指定 resources limits 和 requests不会调度到该 Node 上如果 Node Condition 处于DiskPressure则所有新 Pod 都不会调度到该 Node 上。Node 状态异常时的驱逐由 Node Controller 执行kubelet 默认每 10s 更新 Node 状态--node-status-update-frequency10skube-controller-manager 每 5s 检查一次--node-monitor-period5sNode 超过 40s 未更新状态--node-monitor-grace-period40s会被标记为NotReady超过 5 分钟未更新则驱逐该 Node 上的所有 Pod默认驱逐速率--node-eviction-rate0.1即每 10 秒一个节点。Taints 和 Tolerations控制 Pod 调度到合适的 NodeTaints 和 Tolerations 用于保证 Pod 不被调度到不合适的 Node 上。其中Taint 应用于 Node 上而Toleration 应用于 Pod 上Toleration 是可选的。比如可以使用 taint 命令给 node1 添加 taintskubectl taint nodes node1 key1value1:NoSchedule kubectl taint nodes node1 key1value2:NoExecute调度器章节 详细介绍了目前支持的三种 taint 类型NoSchedule新的 Pod 不调度到该 Node 上不影响正在运行的 PodPreferNoSchedulesoft 版的 NoSchedule尽量不调度到该 Node 上NoExecute新的 Pod 不调度到该 Node 上并且删除evict已在运行的 Pod。Pod 可以增加一个时间tolerationSeconds来推迟被删除的时间。当 Pod 的 Tolerations 匹配 Node 的所有 Taints 时Pod 可以调度到该 Node 上已运行的 Pod 也不会被删除。对于NoExecute如果 Pod 增加了tolerationSeconds则会在该时间之后才删除 Pod。例如假设 node1 上应用了以下 taintkubectl taint nodes node1 key1value1:NoSchedule kubectl taint nodes node1 key1value1:NoExecute kubectl taint nodes node1 key2value2:NoSchedule下面的 Pod 由于没有 toleratekey2value2:NoSchedule无法调度到 node1 上tolerations: - key: key1 operator: Equal value: value1 effect: NoSchedule - key: key1 operator: Equal value: value1 effect: NoExecute而正在运行且带有tolerationSeconds的 Pod 则会在 600s 之后被删除tolerations: - key: key1 operator: Equal value: value1 effect: NoSchedule - key: key1 operator: Equal value: value1 effect: NoExecute tolerationSeconds: 600 - key: key2 operator: Equal value: value2 effect: NoSchedule几个重要的默认行为DaemonSet 创建的 Pod 会自动加上对node.alpha.kubernetes.io/unreachable和node.alpha.kubernetes.io/notReady的 NoExecute Toleration避免它们因此被删除Kubernetes 会自动给 Pod 添加针对node.kubernetes.io/not-ready和node.kubernetes.io/unreachable的容忍度且默认配置tolerationSeconds300可通过自定义 tolerations 覆盖例如tolerations: - key: node.kubernetes.io/unreachable operator: Exists effect: NoExecute tolerationSeconds: 10 - key: node.kubernetes.io/not-ready operator: Exists effect: NoExecute tolerationSeconds: 10此外调度器还存在专门针对 Taint/Toleration 的过滤与评分策略predicate 阶段的PodToleratesNodeTaints检查 Pod 是否容忍 Node Taintspriority 阶段的TaintTolerationPriority优先调度到匹配 TaintToleration 的节点上详见 调度器策略清单。Node 维护模式cordon 与 drain标志 Node 不可调度但不影响其上正在运行的 Pod这在维护 Node 时非常有用kubectl cordon $NODENAME与kubectl drain相比cordon只标记 Node 不可调度SchedulingDisabled不会驱逐已运行的 Pod恢复时使用kubectl uncordon $NODENAME而 kubectl drain 的语义更强删除该 Node 上由 ReplicationController、ReplicaSet、DaemonSet、StatefulSet 或 Job 创建的 Pod不删除 mirror pods因为不可通过 API 删除如果还有其它类型的 Pod比如不通过 RC 而直接通过kubectl create创建的 Pod且没有--force选项命令会直接失败增加--force选项则会强制删除这些非控制器管理的 Pod。典型的维护流程是kubectl drain驱逐并排空→ 维护硬件/系统 →kubectl uncordon恢复调度。仓库 nginx-ha 示例 也演示了结合 PDBPodDisruptionBudget使用 drain 的完整流程。Node 优雅关闭Graceful Shutdown当配置ShutdownGracePeriod和ShutdownGracePeriodCriticalPods后Kubelet 会根据 systemd 事件检测 Node 的关闭状态并自动终止其上运行的 Pod。注意ShutdownGracePeriodCriticalPods必须小于ShutdownGracePeriod这两个参数默认配置为 0即优雅关闭特性默认是未开启的。比如如果ShutdownGracePeriod设置为 30s而ShutdownGracePeriodCriticalPods设置为 10s那么 Kubelet 将使节点关闭延迟 30 秒。在关闭期间将保留前 2030-10秒用于终止普通 Pod而保留最后 10 秒用于终止关键 Pod。Node 非优雅关闭Non-Graceful Shutdown在 Node 发生异常如断电、宕机的情况下Kubelet 可能没有机会检测并执行优雅关闭。此时会引发两个典型问题StatefulSet 无法创建同名的新 Pod如果 Pod 使用了卷VolumeAttachments 不会从原来的已关闭节点上删除导致这些 Pod 所使用的卷无法挂接到新的运行节点上。Node 非优雅关闭机制正是为了解决这些问题。操作方式为手动将具有NoExecute或NoSchedule效果的node.kubernetes.io/out-of-service污点添加到节点上标记其无法提供服务。如果满足以下两个条件在 kube-controller-manager 上启用了NodeOutOfServiceVolumeDetach特性Pod 上没有设置对应的容忍度那么这些 Pod 将被强制删除并且在该节点上被终止的 Pod 将立即进行卷卸载操作。这样就允许那些在无法提供服务节点上的 Pod 能在其他节点上快速恢复。动态节点资源分配v1.33 Alpha从 Kubernetes 1.33 开始通过MutableCSINodeAllocatableCount特性AlphaCSI 驱动程序能够动态更新节点的可分配资源信息特别是卷附件的数量限制。这提高了调度器对节点真实容量的感知能力避免将 Pod 调度到资源不足的节点上。该特性主要影响节点可分配资源的实时更新CSI 驱动程序可以根据实际存储后端的状态动态调整节点的卷附件限制更准确的调度决策调度器基于最新的节点可分配信息进行 Pod 调度减少调度失败存储资源优化提高存储资源的利用效率避免静态配置的局限性。仓库 CSI 章节 给出了详细的配置方法需要在 API Server 和 Kubelet 上同时开启特性门控# API Server --feature-gatesMutableCSINodeAllocatableCounttrue # Kubelet --feature-gatesMutableCSINodeAllocatableCounttrue并在 CSIDriver 对象中设置节点分配计数的更新周期apiVersion: storage.k8s.io/v1 kind: CSIDriver metadata: name: example.csi.k8s.io spec: # 设置节点分配计数更新周期秒 nodeAllocatableUpdatePeriodSeconds: 60该特性支持两种更新机制周期性更新CSI 驱动程序设置间隔时间刷新节点附件容量和反应式更新卷附件失败时触发立即更新。特性状态表见 特性开关章节MutableCSINodeAllocatableCount默认falseAlpha自 1.33 起。需要强调的是该特性当前处于 Alpha 阶段生产环境使用前建议充分测试。参考文档Node 概念文档调度器章节Taints 和 Tolerations、调度策略kubelet 章节节点自注册、Pod 管理、驱逐kube-controller-manager 章节Node Controller、Node 驱逐kube-proxy 章节节点上的负载均衡组件CSI 章节v1.33 动态 CSI 节点分配计数Cloud Provider 章节Node 初始化 taintkubectl drain 用法kubelet systemd 单元文件赞分享云原生教程【免费下载链接】kubernetes-handbookKubernetes Handbook Kubernetes指南 https://kubernetes.feisky.xyz项目地址https://gitcode.com/gh_mirrors/kub/kubernetes-handbook点击查看免费下载相关推荐Kubernetes节点关闭机制深度解析Kubernetes节点关闭机制深度解析 概述 在Kubernetes集群中节点可能会因为计划内维护或意外故障如断电等而关闭。节点关闭可能导致运行在上面的文档教程云原生Bootstrap MaxLength完全指南从基础安装到高级配置Bootstrap MaxLength完全指南从基础安装到高级配置 想要为你的Bootstrap表单添加智能字符计数功能吗Bootstrap MaxLeng前端UI库/组件Kubernetes Python客户端污点与容忍节点调度限制的完整指南Kubernetes Python客户端污点与容忍节点调度限制的完整指南 Kubernetes Python客户端是官方提供的Python库用于与Kuber后端云原生容器编排创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考