共用方式為

Pod 沙盒注意事项

对于 Azure Kubernetes 服务(AKS)上的 Pod 沙盒部署,需要考虑资源管理、内存管理、CPU 管理和安全性。

资源管理

某些用户可能不熟悉 Pod 沙盒的内存和 CPU 管理行为。 在部署中指定资源时,这些注意事项是相关的,尤其是对于较大的和资源敏感的工作负荷。

Kata 组件

在 Kata 部署中,通常有两个组件系列可以部署。 你有 主机组件客户组件

  • 主要主机组件Kata 适配层云管理程序virtiofsd组成。
    • Kata shim 管理 Pod VM 生命周期。
    • Cloud Hypervisor 是 Kata shim 所用的虚拟机监控程序(VMM)。
    • virtiofsd 是一个守护程序,用于在每个 Pod VM 与其容器主机之间共享文件。
  • 主要 来宾组件 包括 用户的工作负载Pod VM 内核Kata 代理
    • Kata 代理管理 Pod VM 内的容器

内存管理

使用 Kata Pod,可以指定托管工作负荷的 Pod VM 的内存量。 必须相应地配置值,使 Pod 有足够的资源,但不会导致未使用的内存分配给 Pod。

Pod VM 内存大小

为每个运行容器的 Pod VM 分配了一定数量的内存。 此虚拟机内存大小包含运行 Kata 客户端组件所需的所有内存。 用户应注意预留超出工作负荷预期消耗的一些额外内存,以应对其他虚拟机组件(例如 kata 代理或 VM 内核)的消耗。 本文稍后将提供有关典型内存值的示例。

Pod VM 内存大小相当于用户指定的 Kubernetes Pod 内存限制 。 用户可以通过更改 Pod 内存限制来更改值;如果未指定任何值,则应用默认大小 512Mi。 启动 Pod 后,此大小将变为固定。

随着 Pod VM 内存大小的增加,运行时类内存开销应随它一起增加。

运行时类内存开销

Pod 沙盒工作负载附带默认的 kata 运行时类(kata-vm-isolation),其中包含资源的默认开销。 想要对其资源配额进行精细控制的用户可以设置具有特定资源开销的 自定义运行时类 。 当执行此操作时,用户应确保运行时类的内存开销值足够涵盖 kata 部署中 主机组件 的所有预期使用情况。 运行时类内存开销 不需要 考虑 来宾组件的预期内存消耗。

可以创建专门的运行时,并在 overhead 清单的 RuntimeClass 字段中为运行时类指定内存开销。 例如,假设我想为消耗量较小的工作负荷创建运行时:

apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: small-kata-pods
handler: kata
overhead:
  podFixed:
    memory: "120Mi"

不需要指定开销,如果希望更好地控制为工作负荷预留的资源,则建议使用。 如果使用默认 kata-vm-isolation 运行时类且未在 YAML 中指定任何开销,Pod VM 大小的开销默认为 512Mi,运行时类开销默认为 600Mi。 此默认运行时开销通过将默认 Pod VM 大小(512Mi)与此类 VM 大小所需的主机组件的大约内存(约88Mi)相加来进行计算。

用户工作负荷

当用户部署 Kata 工作负荷时,可以使用的内存是配置的 Pod VM 内存大小 减去其他来宾组件的内存,例如 Kata 代理或来宾 VM 内核。

如果要获取这些组件使用的内存的近似值:

  1. 连接到 Pod VM(通过 kubectl execkubectl debug 打开 Pod 中的 shell)。
  2. 运行 free 命令。
  3. 检查输出中的“used”列,以了解虚拟机内核/kata agent 消耗的内存。

内存控制组

计划运行 Kata Pod 时,kubelet 会将 Pod 分配给内存 cgroup。 这会 cgroup 强制实施 Pod 的内存限制/请求,允许用户定义 Pod 可用的资源配额。

在内存 cgroup中,需要考虑两个重要字段:

  • memory.current 定义主机组件和 Pod VM 内存大小分配的内存字节数。
  • memory.max(可选)用户为希望施加内存限制的 Pod 定义的“memory.current”上限。
    • kubelet 将此值计算为 Pod 的内存限制及其运行时类内存开销的总和。

在任何时间点,如果 memory.current 值超过 memory.max 值,内核可能在检测到内存压力时对 Pod 触发 OOMKill

引用使用值

用户可以利用这些值来引用所涵盖的不同变量中的典型内存使用情况和值。 不支持低于 128Mi 的 Pod VM 内存大小。

Pod VM 内存大小 运行时类开销 内存.当前 memory.max 主机组件可用内存
128Mi 16Mi 133Mi 144Mi(兆字节) 11Mi
256Mi 32Mi 263Mi 288兆字节 (MiB) 25Mi
1Gi 128Mi 1034Mi 1152Mi 118Mi
2Gi 256Mi 2063Mi 2304Mi 241Mi
4Gi 374兆字节 (MiB) 4122Mi 4470Mi 348Mi
8Gi 512Mi 8232Mi 8704Mi 472Mi
32Gi 640Mi 32918Mi 33408Mi 490兆字节
64Gi 768Mi 65825Mi 66304Mi 479Mi
96Gi 896Mi 98738Mi 99200Mi 462Mi
128Gi 1Gi 131646Mi 132096Mi 450Mi

CPU 管理

与内存类似,还可以将 CPU 资源分配给 Kata 工作负载。 建议这样做;如果不声明 Kata Pod 的 CPU 限制,Kata 容器主机组件就能够使用节点上可用的任何 CPU 容量。

保留 CPU

为 Kata 工作负载保留 CPU 时,可以选择设置两个字段。

  • 运行时类的 CPU 开销
  • Pod CPU 限制

当至少指定两个值之一时,控制平面会在节点上为工作负荷保留指定的 CPU 数。 同一节点上的其他 Pod 无法访问此预留容量。

Pod CPU 限制

可以在应用程序的配置清单中声明 pod CPU 限制。 指定的 Pod CPU 限制定义关联的 Pod VM 中容器可以使用的 CPU 限制。

如果为 Pod CPU 限制指定 CPU 的分数,这些分数将向上舍入到下一个整数。 向上舍入的数字将成为分配给 Pod VM 的 vCPU 数,但 cgroup 会将工作负载限制为只能使用 Pod CPU 限制中指定的分数。

如果未声明任何数字,则如果节点上的容量可用,将向 Pod VM 分配一个 vCPU。 Kata 主机组件的 CPU 使用没有限制。

运行时类 CPU 开销

如果您希望为 Kata 主机组件预先保留一些节点容量,则应指定运行时类的开销。

可以在您的overhead清单中,通过 RunTimeClass 字段来指定运行时类的内存开销。 例如

apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: custom-kata-runtime
handler: kata
overhead:
  podFixed:
    cpu: "250m"

最佳做法

内存管理

  • 请确保为所有部署指定 Pod VM 的内存大小(在清单文件中由 limits.memory 定义)和适当的资源配额。
    • 如果要确保在启动该 VM 之前为 Pod VM 保留某些节点容量,请确保使用非零 Pod 请求 。 请求应考虑到应在其中运行的 Pod VM 和容器。
    • 如果您希望在这些组件启动之前为 Kata 主机组件预留一些节点容量,请确保使用非零的 运行时类开销
  • 如果预期 Pod 工作负载对资源需求特别高,可以为 Pod VM 相应指定限制,以确保工作负载有足够的资源。
  • 声明适当的运行时类内存开销,以便为主机组件提供足够的内存,但不需要太多来避免分配未使用的内存。

CPU 管理

  • 如果节点通常具有大量的可用 CPU 容量,则这些预留可能不必要。

  • 如果节点的 CPU 消耗量通常达到极限,那么进行非零资源预留可确保 Pod 可以更可靠地执行。

    • 可以利用 Pod CPU 请求来确保为 Kata 主机组件保留一些 CPU 节点容量。 特定工作负荷的预留容量 不适用于 节点上的其他工作负荷。
  • 请确保指定基础结构可以容纳的 CPU 请求。 如果可用容量接近 0,或者请求太大,则工作负荷可能无法 启动

  • 使 CPU 请求与 CPU 限制保持一致。 Kata 垫片没有可见性来查看请求。 因此,如果未声明 CPU 限制,Pod VM 将限制为一个 vCPU。 对请求值有可见性的 Kata 主机组件会占用所请求的 CPU 计数的其余部分,并且对 CPU 消耗没有限制。

  • 特定工作负荷的预留容量 不适用于 节点上的其他工作负荷。

示例声明

运行时类 CPU 开销 Pod CPU 请求/限制 预期行为
1 1 控制平面在节点上保留两个 CPU。 Pod VM 获取一个 CPU,Pod 上的容器最多可以使用一个 vCPU 容量。 Kata 主机组件和 Pod VM 在一起最多可以使用节点上预留容量中的两个 CPU。
1 2.5 控制平面在节点上保留 3.5 个 CPU。 Pod VM 获取三个 vCPU,但 Pod VM 上的容器最多可以使用 2.5 个 vCPU 容量。 Kata 主机组件和 Pod VM 一起最多可以使用节点上预留容量中的 3.5 个 CPU。
None 1 控制平面在节点上保留一个 CPU。 Pod VM 获取一个 vCPU,Pod VM 上的容器最多可以使用一个 vCPU 容量。 允许卡塔主机组件和 Pod VM 一起使用节点上预留容量中的最多一个 CPU。 由于 CPU 请求,一个 CPU 始终可用于 Pod VM。
1 None 控制平面在节点上保留一个 CPU。 Pod VM 获取一个 vCPU,Pod VM 上的容器最多可以使用一个 vCPU 容量。 Kata 容器主机组件和 Pod VM 可以使用节点上任何可用的 CPU 容量。 由于开销预留,至少有一个 CPU 始终可用。

安全性

Pod 沙盒为用户提供了一个令人信服的选项,用于将工作负荷与其他工作负载和主机隔离开来。 尽管如此,还应考虑到重要的安全问题。

特权容器组

在某些情况下,可能需要特权 Pod。 用户能够创建特权容器,但不会将主机设备附加到容器。

使用特权容器会导致来宾 VM 拥有 root 权限,同时与主机保持隔离。

特权 Pod 即使在 Pod 沙箱中,也应该仅在必要时使用。 特权 Pod 应继续 由受信任的用户管理

主机路径存储卷

hostPath 卷可以装载到 Kata Pod 中。 在 Pod 沙盒中,使用 hostPath 卷可能会破坏 Kata 提供的隔离;由于主机文件系统的一部分直接向容器公开,因此打开潜在的攻击途径。 上游提出的警告也应考虑与 Pod 沙盒相关。

存在一些例外情况;下面的 /dev 文件从来宾系统而不是主机系统装载到容器中。 必须装载此路径才能正常运行的情况下,这起到保持 Pod 隔离的作用。

警告

除非有必要,否则建议 避免 使用 hostPath 存储卷。

通过 Azure Policy 阻止 hostPath

Azure Policy 允许用户以集中、一致的方式对其群集组件应用大规模强制措施和安全措施。

AKS 有一组 内置策略集 ,用于强制实施最佳做法。 用户可以利用其中一个策略来阻止尝试装载 hostPath 的部署。

后续步骤

准备就绪后,了解如何 在 AKS 上部署 Pod 沙盒