Azure Kubernetes 服务 (AKS) 上的 Pod 沙盒化需要考虑资源管理、内存管理、CPU 管理和安全性。
Pod 沙盒化中的资源管理
在为部署指定资源(尤其是对于大型或资源敏感型工作负荷)时,请查看这些注意事项。
Kata 组件
Kata 部署包括 AKS 节点上运行的组件以及 Pod 虚拟机(VM)中运行的组件。 这种主机与来宾的划分决定了内存和 CPU 使用情况的统计方式。
| 组件 | 运行位置 | Purpose | 资源影响 |
|---|---|---|---|
| 卡塔垫片 | AKS 节点(主机) | 管理 Pod VM 生命周期。 | 使用由 RuntimeClass 开销考虑的主机端资源。 |
| 云虚拟机监控器 | AKS 节点(主机) | 提供用于创建和运行 Pod VM 的虚拟机监视器(VMM)。 | 使用由 RuntimeClass 开销考虑的主机端资源。 |
virtiofsd |
AKS 节点(主机) | 在 Pod VM 与其容器主机之间共享文件。 | 使用由 RuntimeClass 开销考虑的主机端资源。 |
| Kata 代理 | Pod VM (来宾) | 管理 Pod VM 中的容器。 | 使用 Pod VM 分配的内存和 CPU 中的客户机端资源。 |
| Pod VM 内核 | Pod VM (来宾) | 提供客户机操作系统内核。 | 使用 Pod VM 分配的内存和 CPU 中的客户机端资源。 |
| 工作负荷容器 | Pod VM (来宾) | 运行用户工作负荷。 | 使用剩余的来宾侧资源,但受 Pod 的资源限制。 |
Pod 沙盒化中的内存管理
将 Pod VM 内存限制设置为足够高,以支持工作负荷和 Kata 来宾组件,而无需分配未使用的内存。
Pod VM 内存大小
每个 Pod VM 都会为工作负载和所有 Kata 来宾组件分配内存。 除预期工作负载消耗的内存外,还应将 Kata 代理和 VM 内核等客户机组件所需的内存计算在内。 请参阅参考使用值,了解典型内存值。
Kubernetes Pod 内存限制确定 Pod VM 内存大小。 更改 Pod 内存限制以更改 Pod VM 内存大小。
Important
如果未指定 Pod 内存限制,AKS 将应用默认 Pod VM 内存大小 512Mi。 Pod 启动后,Pod VM 的内存大小就固定了。
RuntimeClass 内存开销通常随 Pod VM 内存大小增加。
RuntimeClass 内存开销
Pod 沙盒化工作负载使用默认的 Kata RuntimeClass(kata-vm-isolation),其中包含默认的资源开销值。 若要更细粒度地控制资源配额,请设置具有特定资源开销的 自定义配置RuntimeClass。 Pod 内存限制决定了 Pod VM 可用的来宾侧内存大小。
RuntimeClass 开销会为主机端 Kata 组件预留节点容量,因此无需将客户机组件的预期内存消耗考虑在内。
您可以创建专用运行时,并通过您的 overhead 清单中的 RuntimeClass 字段指定内存开销。
例如,以下清单为预期资源消耗较低的工作负荷创建运行时:
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: small-kata-pods
handler: kata
overhead:
podFixed:
memory: "120Mi"
当 Kubernetes 计划 Pod 并调整其大小cgroup时,该值memory: "120Mi"将增加 120Mi 的固定 Pod 开销。 该值 handler: kata 必须与 AKS 节点上配置的 Kata 运行时处理程序匹配。
在使用自定义 RuntimeClass之前,请运行 kubectl get runtimeclass 并验证其处理程序是否在 AKS 群集中受支持。
不需要指定开销,但如果希望更精细地控制为工作负荷保留的资源,建议这样做。 如果使用默认值 kata-vm-isolationRuntimeClass 且未指定 Pod 内存限制,则 Pod VM 大小默认为 512Mi。 默认的 RuntimeClass 会给主机组件额外增加约 88Mi 的内存开销,因此 Pod cgroup 的限制为 600Mi。
用户工作负荷
Kata 工作负荷可以使用配置的 Pod VM 内存大小 减去来宾组件(如 Kata 代理和来宾 VM 内核)使用的内存。
若要估计这些组件使用的内存:
- 连接到 Pod VM(通过
kubectl exec或kubectl debug打开 Pod 中的 shell)。 - 运行
free命令。 - 检查 已用 列来估算来宾内核和 Kata 代理占用的内存。
内存控制组
Kubernetes 计划 Kata Pod 时,kubelet 会将 Pod 分配到内存 cgroup。
cgroup 会强制执行 Pod 的内存请求和限制,从而定义 Pod 可用的资源。
内存 cgroup 有两个重要字段:
| cgroup 字段 | Description |
|---|---|
memory.current |
报告 Pod VM 当前使用的内存,包括客户机组件和 Kata 主机组件。 |
memory.max |
定义 Pod cgroup的内存上限。 kubelet 将此值计算为 Pod 内存限制和 RuntimeClass 内存开销的总和。 |
在任何时间点,如果 memory.current 值超过 memory.max 值,内核可能在检测到内存压力时对 Pod 触发 OOMKill。
引用使用值
使用以下值作为典型的内存使用示例。 不支持 128 MiB 以下的 Pod VM 内存大小。
如何读取此表: memory.current 包括 Pod VM 内存分配和当前主机组件使用情况。 kubelet 根据 Pod 内存限制和 RuntimeClass 开销计算出 memory.max。 这些值之间的差值表示可供额外主机组件使用的容量。
| Pod VM 内存大小 |
RuntimeClass 开销 |
内存.当前 | 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 |
内存管理最佳做法
- 通过在清单中设置
limits.memory来指定 Pod VM 内存大小,并为所有部署定义合适的资源配额。- 使用非零的 Pod 内存请求值,在 VM 启动前为 Pod VM 预留节点容量。 请求应将 Pod VM 及其中运行的容器考虑在内。
- 使用非零
RuntimeClass内存开销,以计入 Kata 主机组件消耗的节点容量。
- 对于资源密集型工作负载,请将 Pod 的内存限制设置为足以为工作负载和客户机组件提供足够内存。
- 将
RuntimeClass内存开销设置得足够高,以满足 Kata 主机组件的需求,同时又不会预留远超这些组件实际所需的节点容量。
Pod 沙盒中的 CPU 管理
通过设置 Pod CPU 限制和 RuntimeClass 开销,为 Kata 工作负载分配 CPU 资源。 如果没有 CPU 限制,Kata 主机组件可以使用节点上可用的任何 CPU 容量。
保留 CPU
设置以下一个或两个字段,以便为 Kata 工作负荷保留 CPU 容量:
-
RuntimeClassCPU 的开销 - Pod 的 CPU 限制
当至少指定两个值之一时,控制平面会在节点上为工作负荷保留指定的 CPU 数。 同一节点上的其他 Pod 无法访问此预留容量。
Pod CPU 限制
在应用程序的清单文件中声明pod CPU 限制。 此限制控制关联 Pod VM 中容器可以使用的 CPU 数。
Important
非整数的 Pod CPU 限制在为 pod VM 分配资源时,会向上取整到下一个整数 vCPU。 Pod 的 CPU cgroup 仍会对工作负载执行小数限制。 规划成本和节点密度时,将这种舍入情况考虑在内。
如果未声明 Pod CPU 限制,AKS 会在节点有足够的容量时将一个 vCPU 分配给 Pod VM。 Kata 宿主机组件没有 CPU 使用限制。
RuntimeClass CPU 开销
在部署工作负载之前,请指定用于为 Kata 主机组件预留节点容量的 RuntimeClass 开销。
可以通过您overhead清单中的 RuntimeClass 字段指定 CPU 开销。
例如:
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: custom-kata-runtime
handler: kata
overhead:
podFixed:
cpu: "250m"
当 Kubernetes 计划 Pod 并调整其大小cgroup时,该值cpu: "250m"会增加固定 Pod 开销的 0.25 vCPU。 根据 Kata 主机组件的预期 CPU 消耗量调整此值。
CPU 管理最佳做法
- 如果节点通常具有大量的可用 CPU 容量,则这些预留可能不必要。
- 如果节点的 CPU 消耗量通常达到极限,那么进行非零资源预留可确保 Pod 可以更可靠地执行。
- Pod CPU 请求可帮助 Kubernetes 计划程序为工作负荷保留足够的节点容量。 特定工作负荷的预留容量不适用于节点上的其他工作负荷。
- 指定基础结构可以容纳的 CPU 请求。 如果可用容量接近为零,或者请求过大,工作负载可能无法启动。
- 使 CPU 请求与 CPU 限制保持一致。 请求会影响 Kubernetes 的调度,但 Kata shim 不会用这些请求来确定 Pod VM 的大小。 CPU 限制确定 Pod VM 的 vCPU 分配。 如果未声明 CPU 限制,Pod VM 将接收一个 vCPU,而 Kata 主机组件没有 CPU 消耗限制。
示例声明
RuntimeClass CPU 开销 |
Pod CPU 请求或限制 | 预期行为 |
|---|---|---|
| 1 | 1 | 控制平面在节点上保留两个 CPU。 Pod VM 获取一个 vCPU,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。 Kata 主机组件和 Pod VM 一起最多可以使用预留节点容量中的一个 CPU。 CPU 请求使一个 CPU 可供 Pod VM 使用。 |
| 1 | None | 控制平面在节点上保留一个 CPU。 Pod VM 获取一个 vCPU,Pod VM 中的容器最多可以使用一个 vCPU。 Kata 主机组件和 Pod VM 可以使用节点上可用的任何 CPU 容量。 开销预留确保至少有一个 CPU 可用。 |
Pod 沙箱的安全注意事项
Pod 沙盒将工作负荷与其他工作负载和主机隔离开来,但你仍必须考虑以下安全风险。
特权容器组
某些工作负载需要特权 Pod。 可以创建特权 Pod,但 主机设备不会附加到 Pod。
使用特权容器可在来宾 VM 中提供根访问权限,但容器与主机保持隔离。
即使启用了 Pod 沙盒机制,也仅应在必要时使用特权 Pod。 仅允许受信用户管理特权 Pod。
主机路径存储卷
将 hostPath 卷挂载到 Kata Pod 中会将主机文件系统的一部分直接暴露给容器,并且可能会削弱 Pod 沙箱隔离。 将 上游 hostPath 安全指南 应用于 Pod 沙盒工作负载。
/dev 下的文件是个例外,因为它们是从来宾系统而非主机系统挂载到容器中的。 当工作负荷需要此路径时,此行为会保持 Pod 隔离。
警告
除非您的工作负载需要hostPath存储卷,否则请避免使用此类存储卷。
使用 Azure Policy 阻止 hostPath 卷
Azure Policy为群集组件提供集中、一致的强制措施和安全措施。
AKS 提供内置策略定义,用于强制实施最佳做法。 分配 Kubernetes 群集 Pod 应仅使用允许的卷类型 策略,并将效果设置为 Deny,然后从允许的卷类型中排除 hostPath,以阻止尝试挂载 hostPath 卷的 Pod。
后续步骤
了解如何 在 AKS 上部署 Pod 沙盒。