Azure Kubernetes 服务 (AKS)中的节点强化(预览版)

节点强化是 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.slice c 组中运行,因此即使 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 扩展

  1. aks-preview使用az extension add命令安装扩展。

    az extension add --name aks-preview
    
  2. 使用 az extension update 命令更新到最新版本的扩展。

    az extension update --name aks-preview
    

注册 CustomNodeConfigPreview 功能标志

  1. 使用 CustomNodeConfigPreview 命令注册 az feature register 功能标志。

    az feature register --namespace "Microsoft.ContainerService" --name "CustomNodeConfigPreview"
    

    需要几分钟,状态才会显示为已注册。

  2. 使用 az feature show 命令验证注册状态。

    az feature show --namespace "Microsoft.ContainerService" --name "CustomNodeConfigPreview"
    
  3. 当状态显示为已注册时,使用命令刷新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

若要确认更改,请参阅 “验证节点强化设置”。

验证节点加固设置

  1. 使用 az aks get-credentials 命令获取群集的凭据。

    az aks get-credentials --resource-group <resource-group-name> --name <cluster-name>
    
  2. 通过查询 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。

  3. 将节点的容量与其可分配的资源进行比较。

    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 的自定义节点配置参数。
  • 对于每个逐出信号,请同时设置软逐出阈值及其匹配宽限期,并确保每个软逐出阈值大于同一信号的硬逐出阈值。
  1. 创建 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
    }
    
  2. 使用 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 配置,因此无法从现有节点池中删除保留的软逐出设置。 若要移除它们,请创建一个新的节点池,显式取消设置这些配置,将工作负载迁移到新的节点池,然后删除旧的节点池。

  1. 创建 kubelet 配置文件,例如 remove-soft-eviction.json。 以下示例将每个软驱逐阈值和宽限期设置为空字符串,这会关闭该信号的软驱逐。 它还将最大 Pod 终止宽限期设置为 0,即标准 AKS 默认值。

    {
      "softEvictionThreshold": {
        "memoryAvailable": "",
        "nodeFsAvailable": "",
        "nodeFsInodesFree": ""
      },
      "softEvictionGracePeriod": {
        "memoryAvailable": "",
        "nodeFsAvailable": "",
        "nodeFsInodesFree": ""
      },
      "evictionMaxPodGracePeriodInSeconds": 0
    }
    
  2. 使用 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
    
  3. 将工作负荷移动到新节点池,然后删除旧节点池。 有关详细信息,请参阅 调整 AKS 中的节点池大小。

若要确认节点上的设置,请参阅 验证节点强化设置。 在新节点池中的节点上, evictionSoft 为空。