4、节点资源容量评估:计算节点可分配资源、预留资源(kube-reserved/system-reserved)、驱逐阈值设置

节点资源容量评估是集群升级前最关键的容量规划步骤之一。Kubernetes 节点上的资源并非全部可供 Pod 使用,系统组件(kubelet、容器运行时、操作系统守护进程)需要预留一部分资源,同时 kubelet 通过驱逐阈值来保障节点在资源紧张时的稳定性。理解这三层资源模型,才能准确判断升级后集群是否仍有足够的余量承载工作负载。

4.1 节点资源三层模型

Kubernetes 节点资源从物理总量到 Pod 可用量,经历三层扣除:

层级 含义 扣除方式 典型占比(16C/64G 节点)
Node Capacity 节点物理资源总量(CPU / 内存 / 磁盘) — 16 CPU / 64 GiB 内存
system-reserved 操作系统守护进程(sshd、systemd、监控 Agent)预留 从 Capacity 中扣除 CPU: 200m / 内存: 1 GiB
kube-reserved Kubernetes 组件(kubelet、容器运行时、Node Problem Detector)预留 从 Capacity 中扣除 CPU: 500m / 内存: 1.5 GiB
eviction-thresholds kubelet 驱逐 Pod 的硬性水位线(硬驱逐) 从 Capacity 中扣除(隐式) 内存: 500 MiB(memory.available<500Mi)
Allocatable 实际可供调度 Pod 使用的资源上限 Capacity − system-reserved − kube-reserved − eviction-thresholds ≈ 13.3 CPU / 61 GiB 内存
核心公式:
Allocatable = NodeCapacity − [system-reserved] − [kube-reserved] − [eviction-thresholds]
调度器只认 Node.Status.Allocatable,超出该值的 Pod 无法被调度到该节点。

4.2 预留资源配置与计算

kubelet 通过启动参数或 kubelet 配置文件设置预留量。以下为生产环境推荐配置示例:

# /var/lib/kubelet/config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
evictionHard:
  memory.available: "500Mi"
  nodefs.available: "10%"
  nodefs.inodesFree: "5%"
  imagefs.available: "15%"
kubeReserved:
  cpu: "500m"
  memory: "1.5Gi"
  ephemeral-storage: "2Gi"
systemReserved:
  cpu: "200m"
  memory: "1Gi"
  ephemeral-storage: "1Gi"
kubeReservedCgroup: "/kubelet.slice"
systemReservedCgroup: "/system.slice"
enforceNodeAllocatable:
  - pods
  - kube-reserved
  - system-reserved
⚠️ 常见陷阱: 如果未设置 kubeReservedCgroup 和 systemReservedCgroup,kubelet 无法强制限制这些预留资源的使用量,预留配置将退化为“软预留”,实际 Pod 仍可能挤占系统组件资源。

4.3 驱逐阈值(Eviction Thresholds)

驱逐阈值是 kubelet 在节点资源耗尽前的最后防线。分为硬驱逐(evictionHard)和软驱逐(evictionSoft + evictionSoftGracePeriod)。

类型 信号 典型阈值 行为
硬驱逐 memory.available <500Mi 立即驱逐 Pod,不可协商
硬驱逐 nodefs.available <10% 立即驱逐 Pod
硬驱逐 nodefs.inodesFree <5% 防止 inode 耗尽导致文件系统故障
软驱逐 memory.available <1Gi 等待宽限期(默认 2m)后驱逐
软驱逐 nodefs.available <15% 等待宽限期后驱逐
💡 升级前检查: 使用 kubectl describe node <node> 查看 Allocatable 字段,对比当前 Pod 资源请求总和。如果 Allocatable - sum(Pod Requests) < 10%,建议先扩容或迁移 Pod 再升级。

4.4 节点资源容量评估流程图

以下 SVG 展示了从节点物理容量到 Pod 可用容量的完整计算流程,以及驱逐阈值在其中的位置:

节点资源容量评估流程 节点资源容量评估流程 Node Capacity(物理总量) system-reserved(OS 守护进程) kube-reserved(K8s 组件) eviction-thresholds(驱逐水位) Allocatable(Pod 可用量) 公式说明 Allocatable = Capacity − system-reserved − kube-reserved − eviction-thresholds 调度器只认 Allocatable 超出则 Pod 无法调度 升级前必查 • 当前 Allocatable 值 • 已调度 Pod 请求总和 • 驱逐阈值是否合理

4.5 升级前容量评估清单

在升级每个节点前,建议按以下步骤执行容量评估:

  1. 获取节点当前 Allocatable:
    kubectl describe node <node> | grep -A 5 "Allocatable"
  2. 计算已调度 Pod 资源请求总和:
    kubectl get pods --all-namespaces --field-selector spec.nodeName=<node> -o json | jq '[.items[] | .spec.containers[] | .resources.requests] | group_by(.) | map({cpu: (.[0].cpu // "0"), memory: (.[0].memory // "0")})'
  3. 计算剩余容量:
    剩余 CPU = Allocatable.cpu − sum(Pod Requests.cpu)
    剩余内存 = Allocatable.memory − sum(Pod Requests.memory)
  4. 检查驱逐阈值是否可能触发:
    如果剩余内存 < evictionHard.memory.available + 20% 缓冲,标记为高风险节点。
  5. 记录基线:
    将评估结果写入升级前检查报告,升级后对比验证。
📊 生产经验阈值:
• 剩余 CPU < 1 核 → 建议迁移部分 Pod
• 剩余内存 < 2 GiB → 建议迁移部分 Pod
• 剩余节点磁盘(nodefs)< 15% → 清理镜像/日志后再升级
• 节点 inode 使用率 > 85% → 优先清理小文件

4.6 驱逐阈值与节点压力关系图

以下 SVG 展示了驱逐阈值在节点内存压力下的触发顺序与 Pod 驱逐流程:

驱逐阈值触发流程 驱逐阈值触发流程(以内存为例) 正常状态 内存可用 > 软驱逐阈值 软驱逐触发 内存可用 < 1Gi 硬驱逐触发 内存可用 < 500Mi 驱逐行为说明 1. 软驱逐:kubelet 记录事件,等待 evictionSoftGracePeriod(默认 2m) 2. 若宽限期内资源恢复,取消驱逐;否则标记 Pod 为驱逐候选 3. 硬驱逐:立即驱逐 Pod,不等待宽限期 4. 驱逐顺序:先驱逐 BestEffort Pod → Burstable Pod → Guaranteed Pod 5. 升级前建议调低硬驱逐阈值,避免升级过程中触发大规模驱逐

4.7 升级前容量评估检查表

检查项 命令 / 方法 合格标准
Allocatable CPU kubectl describe node | grep cpu 剩余 ≥ 1 核
Allocatable 内存 kubectl describe node | grep memory 剩余 ≥ 2 GiB
驱逐阈值配置 kubectl describe node | grep -A 10 "Eviction" 硬驱逐阈值不低于默认值
节点磁盘使用率 df -h /var/lib/kubelet 使用率 < 85%
inode 使用率 df -i /var/lib/kubelet 使用率 < 80%
kube-reserved 是否生效 检查 cgroup 路径 /sys/fs/cgroup/kubelet.slice cgroup 存在且限制生效
🔧 自动化脚本建议: 将上述检查项写入 pre-upgrade-check.sh,在升级每个节点前自动执行,输出 JSON 格式报告,便于集成到 CI/CD 或升级工具链中。