节点强化是 Linux 节点池的一项可选启用功能,当工作负荷将节点置于 CPU、内存或磁盘压力之下时,可保护节点稳定性。 在群集上启用节点强化时,AKS 会更改每个节点如何保留并强制实施 Kubernetes 组件和主机服务的资源,以及 kubelet 在资源不足时如何逐出 Pod。
本文介绍节点强化的更改、将强化的默认值与标准 AKS 默认值进行比较,并演示如何启用、验证、自定义和禁用该功能。
Important
AKS 预览功能可在自助服务和自愿选择的基础上启用。 预览版按“现状”和“视供应情况”提供,它们不包括在服务级别协议和有限保证范围内。 AKS 预览功能是由客户支持尽最大努力部分覆盖。 因此,这些功能并不适合用于生产。 有关详细信息,请参阅以下支持文章:
节点强化的优点
在繁忙或负载突增的节点上,工作负荷可以使用 kubelet、容器运行时和主机服务所需的资源。 发生这种情况时,节点可能会变得无响应、报告 NotReady 状态或突然终止 Pod。 节点强化通过以下方式降低这些风险:
-
强制预留: 默认情况下,AKS 仅使用 kube 保留值来计算计划程序可以分配给 Pod 的容量。 通过使用 Node Hardening,kubelet 还通过 Linux 控制组(cgroups)强制实施 kube-reserved 和系统预留容量。 kubelet 和 containerd 在专用
kubereserved.slicec 组中运行,因此即使 Pod 将节点资源占满,它们也会保留其保留的 CPU 共享和内存。 -
主机服务的专用容量: 节点强化为在
system.slice中运行的主机操作系统服务添加了系统保留的分配。 - 更多内存余量: 可用内存的硬逐出阈值随节点内存而变化,因此 kubelet 会在节点内存严重不足之前逐出 Pod。
- 优雅逐出: 软逐出阈值允许 kubelet 在内存或磁盘空间不足时优雅地逐出 Pod,并带有终止宽限期。 硬逐出会立即终止 Pod,并作为最后的手段使用。
- 使用 Pod 密度缩放的预留: kube-reserved 内存计算随着每个节点的最大 Pod 数的增加而增加,这考虑到了 kubelet 和运行更多 Pod 的 containerd 开销。
启用节点强化时发生哪些更改
下表将运行 Kubernetes 1.29 或更高版本的 Linux 节点的标准默认值与启用节点强化时 AKS 适用的默认值进行比较。
资源预留
| Setting | 无 Node Hardening | 使用节点加固 |
|---|---|---|
| Kube 保留的 CPU | 基于 CPU 核心数。 有关详细信息,请参阅 CPU 预留。 | 不变 |
| Kube 保留内存 |
min(20 × maxPods + 50, 25% of node memory) MiB |
min(35 × maxPods + max(250, 2% of node memory), 25% of node memory) MiB |
| Kube 保留的进程 ID (PID) | 1000 |
非保留 |
| 系统保留的 CPU | None | 100m |
| 系统保留的内存 | None | 200 MiB,以及每个完整 32 GiB 节点内存的 100 MiB,以及 100 MiB 用于使用 Azure CNI 的群集 |
| 系统保留的临时存储 | None | 1Gi |
驱逐阈值
| Setting | 没有节点加固 | 使用节点加固 |
|---|---|---|
强制逐出: memory.available |
100Mi |
250Mi 对于具有 8 GiB 内存或更少内存的节点,375Mi 对于大于 8 GiB 且小于 32 GiB 的节点,以及 512Mi 对于具有 32 GiB 或更多内存的节点 |
硬逐出: nodefs.available 和 nodefs.inodesFree |
10% 和 5% |
不变 |
强制逐出: pid.available |
2000 |
未设置 |
软逐出: memory.available |
None |
500Mi、750Mi 或 1Gi,使用与硬逐出相同的节点内存层级,宽限期为 30 秒 |
软逐出: nodefs.available 和 nodefs.inodesFree |
None |
12% 和 7%,各有 2 分钟的宽限期 |
| 软逐出期间的最大 Pod 终止宽限期 | 未设置 | 60 秒 |
Cgroup 实施
| Setting | 未启用节点加固 | 使用节点加固 |
|---|---|---|
| 强制节点可分配资源 | pods |
pods、 kube-reserved和 system-reserved |
| Kubelet 和 containerd cgroup |
system.slice,没有限制 |
kubereserved.slice,内存限制为 kube 保留内存,CPU 共享与 kube 保留的 CPU 成比例 |
| 主机服务 cgroup |
system.slice,没有限制 |
system.slice,内存限制为系统保留内存,CPU 共享与系统保留的 CPU 成比例 |
由于节点强化保留更多容量,因此节点报告 Pod 的可分配容量更少。 例如,在使用 Azure CNI 的 4 个 vCPU 和 16 GiB 内存的节点上,启用节点强化可减少可分配的容量,如下所示:
- 每个节点的默认 Pod 上限为 250 个,所需资源约为 570 MiB 内存、100 毫核 CPU 和 1 GiB 的临时存储。
- 每个节点最多 30 个 Pod,需要约 1.3 GiB 的内存、100 millicores 的 CPU 和 1 GiB 的临时存储。
软逐出阈值不会降低可分配的容量。 它们仅在 kubelet 开始逐出 Pod 时发生更改。
Considerations
启用节点强化之前,请记住以下注意事项:
- 在群集级别启用节点加固,它适用于群集中的所有 Linux 节点池。 不能为单个节点池启用它,并且不会影响Windows节点池。
- 节点报告的可分配容量较少,因此在启用节点强化之前可在节点上运行的 Pod,之后可能无法运行。 查看 Pod 资源请求和节点池大小。
- 在
system.slice中,主机服务共享一个等于系统保留内存的硬内存限制。 如果在节点上以系统服务(例如安全、监视或日志转发代理)的形式运行自己的代理,这些代理将计入此限制。 在生产环境中使用 Node Hardening 之前,请验证其内存使用情况和稳定性。 - 在节点池的自定义 kubelet 配置中设置的值将替代相应的节点强化默认值。 有关详细信息,请参阅 自定义节点强化设置。
- 如果稍后禁用节点加固,则现有节点池会保留加固后的软逐出设置,即使其节点被重新映像后也是如此。 若要删除这些设置,需要创建新的节点池。 有关更多信息,请参阅 禁用节点强化。
- 此功能处于预览状态时,默认值可能会更改。 从非生产群集开始,并在具有代表性的节点压力条件下验证工作负荷。
Prerequisites
- 一份 Azure 订阅。 如果没有订阅,请创建一个试用帐户。
- 具有 Linux 节点池的 AKS 群集,或创建一个 AKS 群集的权限。
- 以下各节介绍了 Azure CLI
aks-preview扩展和CustomNodeConfigPreview功能标志。
安装 aks-preview Azure CLI 扩展
aks-preview使用az extension add命令安装扩展。az extension add --name aks-preview使用
az extension update命令更新到最新版本的扩展。az extension update --name aks-preview
注册 CustomNodeConfigPreview 功能标志
使用
CustomNodeConfigPreview命令注册az feature register功能标志。az feature register --namespace "Microsoft.ContainerService" --name "CustomNodeConfigPreview"需要几分钟,状态才会显示为已注册。
使用
az feature show命令验证注册状态。az feature show --namespace "Microsoft.ContainerService" --name "CustomNodeConfigPreview"当状态显示为已注册时,使用命令刷新
az provider register资源提供程序的注册。az provider register --namespace "Microsoft.ContainerService"
启用节点强化
在预览期间,默认情况下不会启用节点强化。
在新集群上启用节点强化
使用带有 --enable-node-hardening 参数的 az aks create 命令创建启用了 Node 强化的群集。
此命令需要 aks-preview 扩展和 CustomNodeConfigPreview 功能标志。 有关详细信息,请参阅先决条件。
az aks create \
--resource-group <resource-group-name> \
--name <cluster-name> \
--enable-node-hardening \
--generate-ssh-keys
若要确认更改,请参阅 “验证节点强化设置”。
在现有集群上启用节点加固
使用带有 --enable-node-hardening 参数的 az aks update 命令在现有群集上启用节点强化。
此命令需要 aks-preview 扩展和 CustomNodeConfigPreview 功能标志。 有关详细信息,请参阅先决条件。
az aks update \
--resource-group <resource-group-name> \
--name <cluster-name> \
--enable-node-hardening
若要确认更改,请参阅 “验证节点强化设置”。
验证节点加固设置
使用
az aks get-credentials命令获取群集的凭据。az aks get-credentials --resource-group <resource-group-name> --name <cluster-name>通过查询 kubelet 配置终结点,查看节点上的有效 kubelet 预留和逐出设置。
kubectl get --raw "/api/v1/nodes/<node-name>/proxy/configz" | jq '.kubeletconfig | {kubeReserved, systemReserved, evictionHard, evictionSoft, evictionSoftGracePeriod, evictionMaxPodGracePeriod, enforceNodeAllocatable}'在加固节点上,
systemReserved和evictionSoft包含值,且enforceNodeAllocatable包括kube-reserved和system-reserved。将节点的容量与其可分配的资源进行比较。
kubectl get node <node-name> -o jsonpath='{.status.capacity}{"\n"}{.status.allocatable}{"\n"}'在加固节点上,可分配的 CPU、内存和临时存储低于容量。 差异等于 资源预留中的 kube 保留值和系统保留值,以及 逐出阈值中的硬逐出阈值。 例如,在使用 Azure CNI、具有 4 个 vCPU 和 16 GiB 内存的节点上,可分配 CPU 比容量低 240 毫核:其中 140 毫核为 kube 预留 CPU,100 毫核为系统预留 CPU。
自定义节点安全加固设置
可以使用 自定义 kubelet 配置覆盖 Linux 节点池的 kube-reserved 和 eviction 默认值。 这些设置需要 CustomNodeConfigPreview 功能标志。 无论群集上是否启用了 Node Hardening,都可以使用它们。 AKS 管理系统保留的值和 cgroup 强制实施,你无法自定义它们。
每个设置都会覆盖 资源预留 或 逐出阈值 表中的一行。 Kube 保留行对应于 kubeReserved 设置。 强制逐出行对应于 hardEvictionThreshold 设置。 软驱逐行对应于 softEvictionThreshold 和 softEvictionGracePeriod 设置。 最大 Pod 终止宽限期对应于 evictionMaxPodGracePeriodInSeconds。
可以配置以下设置:
| Setting | Overrides | Description |
|---|---|---|
kubeReserved.cpuMillicores |
Kube 保留的 CPU | 以毫核为单位为 Kubernetes 系统守护程序保留的 CPU。 |
kubeReserved.memoryMB |
Kube 保留内存 | 为 Kubernetes 系统守护程序保留的内存(单位:MiB)。 |
hardEvictionThreshold.memoryAvailable |
强制逐出: memory.available |
可用内存的硬驱逐阈值。 |
hardEvictionThreshold.nodeFsAvailable |
硬逐出: nodefs.available |
可用节点文件系统空间的硬逐出阈值。 |
hardEvictionThreshold.nodeFsInodesFree |
强制逐出: nodefs.inodesFree |
节点文件系统可用 inode 的硬逐出阈值。 |
softEvictionThreshold.memoryAvailable |
软逐出: memory.available |
可用内存的软逐出阈值。 |
softEvictionThreshold.nodeFsAvailable |
软逐出: nodefs.available |
可用节点文件系统空间的软逐出阈值。 |
softEvictionThreshold.nodeFsInodesFree |
软逐出: nodefs.inodesFree |
节点文件系统可用 inode 的软驱逐阈值。 |
softEvictionGracePeriod.memoryAvailable |
软驱逐:memory.available宽限期 |
在 kubelet 逐出 Pod 之前,可用内存必须保持在其软阈值以下的时间。 |
softEvictionGracePeriod.nodeFsAvailable |
软驱逐:nodefs.available宽限期 |
在 kubelet 逐出 Pod 之前,可用节点文件系统空间必须保持在其软阈值以下的时间。 |
softEvictionGracePeriod.nodeFsInodesFree |
软驱逐:nodefs.inodesFree宽限期 |
在 kubelet 逐出 Pod 之前,节点文件系统可用 inode 必须保持在其软阈值以下的时间。 |
evictionMaxPodGracePeriodInSeconds |
软逐出期间的最大 Pod 终止宽限期 | kubelet 允许 Pod 在软逐出期间终止的最大秒数。 |
- 有关每个设置的允许值、最小值和验证规则,请参阅 AKS 的自定义节点配置参数。
- 对于每个逐出信号,请同时设置软逐出阈值及其匹配宽限期,并确保每个软逐出阈值大于同一信号的硬逐出阈值。
创建 kubelet 配置文件,例如
nodehardening-kubelet.json,并设置要自定义的配置项。 以下示例设置每个可配置值。 它将 kube-reserved 设置为 200 毫核 CPU 和 1,024 MiB 内存。 它设置10%可用内存、5%可用文件系统空间和512Mi空闲 inode 的硬逐出阈值。 它将1Gi、12%和7%设置为软逐出阈值,其宽限期分别为 30 秒、2 分钟和 2 分钟。 它还设置 60 秒的最大 Pod 终止宽限期。{ "kubeReserved": { "cpuMillicores": 200, "memoryMB": 1024 }, "hardEvictionThreshold": { "memoryAvailable": "512Mi", "nodeFsAvailable": "10%", "nodeFsInodesFree": "5%" }, "softEvictionThreshold": { "memoryAvailable": "1Gi", "nodeFsAvailable": "12%", "nodeFsInodesFree": "7%" }, "softEvictionGracePeriod": { "memoryAvailable": "30s", "nodeFsAvailable": "2m", "nodeFsInodesFree": "2m" }, "evictionMaxPodGracePeriodInSeconds": 60 }使用
az aks nodepool add命令和--kubelet-config参数创建使用配置文件的 Linux 节点池。az aks nodepool add \ --resource-group <resource-group-name> \ --cluster-name <cluster-name> \ --name <node-pool-name> \ --kubelet-config ./nodehardening-kubelet.json还可以将
--kubelet-config参数与az aks create命令结合使用,将配置应用到群集的初始节点池。
禁用节点加固
使用--disable-node-hardening命令和az aks update参数来禁用节点强化。
此命令需要 aks-preview 扩展和 CustomNodeConfigPreview 功能标志。 有关详细信息,请参阅先决条件。
az aks update \
--resource-group <resource-group-name> \
--name <cluster-name> \
--disable-node-hardening
禁用节点强化会关闭群集级别设置,但它不会立即更改现有节点。 现有节点将保留所有强化设置,直到重新制作映像,例如在升级节点映像期间。 节点重新制作映像后,将应用以下更改:
- 还原为标准 AKS 默认值: Kube 保留和系统保留的资源、硬逐出阈值和 cgroup 强制实施。 节点的可分配容量相应地增加。
- 保留: 软逐出阈值、软逐出宽限期和软逐出期间的最大 Pod 终止宽限期。
只能在创建群集或节点池时设置自定义 kubelet 配置,因此无法从现有节点池中删除保留的软逐出设置。 若要移除它们,请创建一个新的节点池,显式取消设置这些配置,将工作负载迁移到新的节点池,然后删除旧的节点池。
创建 kubelet 配置文件,例如
remove-soft-eviction.json。 以下示例将每个软驱逐阈值和宽限期设置为空字符串,这会关闭该信号的软驱逐。 它还将最大 Pod 终止宽限期设置为0,即标准 AKS 默认值。{ "softEvictionThreshold": { "memoryAvailable": "", "nodeFsAvailable": "", "nodeFsInodesFree": "" }, "softEvictionGracePeriod": { "memoryAvailable": "", "nodeFsAvailable": "", "nodeFsInodesFree": "" }, "evictionMaxPodGracePeriodInSeconds": 0 }使用
az aks nodepool add命令和--kubelet-config参数创建使用配置文件的 Linux 节点池。az aks nodepool add \ --resource-group <resource-group-name> \ --cluster-name <cluster-name> \ --name <node-pool-name> \ --kubelet-config ./remove-soft-eviction.json将工作负荷移动到新节点池,然后删除旧节点池。 有关详细信息,请参阅 调整 AKS 中的节点池大小。
若要确认节点上的设置,请参阅 验证节点强化设置。 在新节点池中的节点上, evictionSoft 为空。