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 可用容量的完整计算流程,以及驱逐阈值在其中的位置:
4.5 升级前容量评估清单
在升级每个节点前,建议按以下步骤执行容量评估:
- 获取节点当前 Allocatable:
kubectl describe node <node> | grep -A 5 "Allocatable" - 计算已调度 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")})' - 计算剩余容量:
剩余 CPU = Allocatable.cpu − sum(Pod Requests.cpu)
剩余内存 = Allocatable.memory − sum(Pod Requests.memory) - 检查驱逐阈值是否可能触发:
如果剩余内存 < evictionHard.memory.available + 20% 缓冲,标记为高风险节点。 - 记录基线:
将评估结果写入升级前检查报告,升级后对比验证。
📊 生产经验阈值:
• 剩余 CPU < 1 核 → 建议迁移部分 Pod
• 剩余内存 < 2 GiB → 建议迁移部分 Pod
• 剩余节点磁盘(nodefs)< 15% → 清理镜像/日志后再升级
• 节点 inode 使用率 > 85% → 优先清理小文件
• 剩余 CPU < 1 核 → 建议迁移部分 Pod
• 剩余内存 < 2 GiB → 建议迁移部分 Pod
• 剩余节点磁盘(nodefs)< 15% → 清理镜像/日志后再升级
• 节点 inode 使用率 > 85% → 优先清理小文件
4.6 驱逐阈值与节点压力关系图
以下 SVG 展示了驱逐阈值在节点内存压力下的触发顺序与 Pod 驱逐流程:
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 或升级工具链中。