Azure Kubernetes 服务 (AKS) 中的 Pod 沙盒隔离

AKS 上的 Pod 沙盒化使用 Kata Containers,将每个沙盒 Pod 运行在具有其自身来宾内核的轻量级虚拟机(VM)中。 此计算边界将工作负荷与其他 Pod VM 中的主机内核和工作负荷隔离开来。 若要了解体系结构、优势和用例,请参阅 Azure Kubernetes 服务 (AKS) 中的 Pod 沙盒概述。

在本文中,你将在新的或现有的 Azure Linux AKS 群集上部署 Pod 沙盒,使用 Kata 运行时部署应用程序,并选择性地验证内核隔离。

先决条件

  • Azure CLI 2.80.0 或更高版本。 运行 az --version 以查找 Azure CLI 的版本,然后运行 az upgrade 以升级。 有关详细信息,请参阅 安装 Azure CLI 中的步骤。
  • AKS 在 Kubernetes 1.27.0 及更高版本中支持 Pod 沙盒化。
  • 若要管理 Kubernetes 群集,请使用 Kubernetes 命令行客户端 kubectl。 可以使用kubectl命令在本地安装az aks install-cli。
  • 必须在 Microsoft.Network/AllowBringYourOwnPublicIpAddress 订阅中注册该功能。 使用 Kata 运行时的 Pod 沙盒工作负载需要此功能。

注册Microsoft.Network/AllowBringYourOwnPublicIpAddress功能

  1. 使用az feature register命令在订阅中注册此Microsoft.Network/AllowBringYourOwnPublicIpAddress功能。 注册可能需要几分钟时间。

    az feature register --namespace Microsoft.Network --name AllowBringYourOwnPublicIpAddress
    
  2. 在部署 Pod 沙盒化之前,请使用 az feature show 命令验证注册状态为 Registered。

    az feature show --namespace Microsoft.Network --name AllowBringYourOwnPublicIpAddress --query properties.state --output tsv
    
  3. 注册该功能后,使用az provider register命令刷新Microsoft.Network资源提供程序注册。

    az provider register --namespace Microsoft.Network
    

限制

以下约束适用于 Pod 沙盒:

  • Kata 容器可能无法达到传统容器可以在 Azure 文件和高性能本地 SSD 上达到的 IOPS 性能的极限。
  • Microsoft Defender for Containers 不支持评估 Kata 运行时 Pod。
  • 不支持Kata主机网络访问。 不能直接从 VM 内部访问主机网络配置。
  • Pod 沙盒的 CPU 和内存分配不同于 runc。 每个 Kata Pod 在固定内存大小基于 Pod 内存限制的 Pod VM 中运行,如果未指定限制,则默认为 512Mi。 CPU 限制值决定 Pod VM 分配到的 vCPU 数量,非整数限制值在分配时会向上取整到整数个 vCPU。 更多信息,请参阅 Pod 沙盒相关注意事项。
  • Pod 沙盒仅在 Azure Linux 上受支持。 不支持 Ubuntu 和 Windows。 有关详细信息,请参阅 Azure AKS 的 Linux 容器主机。
  • 无法在使用 Pod 沙盒的节点池上启用 联邦信息处理标准(FIPS) 或 受信任的启动 。 更多信息,请参阅 Pod 沙盒相关注意事项。
  • 使用 Pod 沙盒的节点池不支持 Arm64 体系结构。

工作原理

AKS 上的 Pod 沙盒在开源 Kata 容器 项目的基础上生成。 在用于 AKS 的 Azure Linux 容器主机上运行的 Kata Containers 提供基于虚拟机的隔离,并为每个 Pod 提供独立的内核。 Pod 沙盒机制允许为每个 Pod 分配资源,并且这些资源不会与在同一主机上运行的其他 Kata Containers 容器或命名空间容器共享。

解决方案体系结构基于以下主要组件:

使用 Kata 容器部署 Pod 沙盒类似于部署容器的标准 containerd 工作流。 启用了 Pod 沙盒的群集附带了可在 Pod 清单(runtimeClassName: kata-vm-isolation)中引用的特定运行时类。 有关运行时类默认值和自定义的详细信息,请参阅 Pod 沙盒的注意事项。

若要将此功能与 Pod 配合使用,唯一的区别是将 runtimeClassNamekata-vm-isolation 添加到 Pod 规范中。当 Pod 使用 kata-vm-isolation runtimeClass 时,虚拟机监控程序会启动一个带有自己内核的轻型虚拟机,以便工作负荷能够在其中正常运行。

使用 Pod 沙盒创建群集

执行以下步骤,使用 Azure CLI 来部署 Azure Linux AKS 群集。

  1. 使用以下参数运行 az aks create 命令来创建 AKS 群集:

    参数 所需的值 备注
    --workload-runtime KataVmIsolation 为节点池启用 Pod 沙盒机制。
    --os-sku AzureLinux Pod 沙盒仅支持 Azure Linux OS SKU。
    --node-vm-size 支持嵌套虚拟化的第 2 代 VM 大小 例如,使用 Dsv3 系列 VM 大小。
    --node-count 3 为此示例创建三个节点。 调整工作负载值。

    以下示例在 myResourceGroup 中创建一个名为 myAKSCluster 的群集,其中包含三个节点:

    az aks create \
        --name myAKSCluster \
        --resource-group myResourceGroup \
        --os-sku AzureLinux \
        --workload-runtime KataVmIsolation \
        --node-vm-size Standard_D4s_v3 \
        --node-count 3 \
        --generate-ssh-keys
    
  2. 运行以下命令以获取 Kubernetes 群集的访问凭据。 使用 az aks get-credentials 命令,并替换群集名称和资源组名称的值。

    az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
    
  3. 运行 kubectl get pods 命令,以列出所有命名空间中的所有 Pod。

    kubectl get pods --all-namespaces
    

在现有集群上启用 Pod 沙盒化

若要将此功能用于现有 AKS 群集,必须满足以下要求:

  • 群集运行 Kubernetes 版本 1.27.0 或更高版本。

  • 使用以下命令创建一个用于承载 Pod 沙盒的节点池,以启用 Pod 沙盒化。

  1. 使用具有以下参数的命令将 az aks nodepool add 节点池添加到 AKS 群集:

    参数 所需的值 备注
    --resource-group 包含现有 AKS 群集的资源组 例如,使用 myResourceGroup。
    --cluster-name 现有 AKS 群集的名称 例如,使用 myAKSCluster。
    --name 唯一的节点池名称 例如,使用 nodepool2。
    --workload-runtime KataVmIsolation 为节点池启用 Pod 沙盒机制。
    --os-sku AzureLinux Pod 沙盒仅支持 Azure Linux OS SKU。
    --node-vm-size 支持嵌套虚拟化的第 2 代 VM 大小 例如,使用 Dsv3 系列 VM 大小。
    --node-count 1 为此示例创建一个节点。 调整工作负载值。

    以下示例将节点池添加到 myAKSCluster,其中一个节点位于 myResourceGroup 的 nodepool2 中:

    az aks nodepool add --cluster-name myAKSCluster --resource-group myResourceGroup --name nodepool2 --os-sku AzureLinux --workload-runtime KataVmIsolation --node-vm-size Standard_D4s_v3 --node-count 1
    
  2. 运行 az aks update 命令以同步集群配置,使集群能够识别带有 KataVmIsolation 工作负载运行时的新节点池。

    az aks update --name myAKSCluster --resource-group myResourceGroup
    
  3. 验证群集更新是否已成功完成,Pod 沙盒节点池是否使用预期的工作负荷运行时、OS SKU 和 VM 大小。

    az aks show \
        --name myAKSCluster \
        --resource-group myResourceGroup \
        --query provisioningState \
        --output tsv
    
    az aks nodepool show \
        --cluster-name myAKSCluster \
        --resource-group myResourceGroup \
        --name nodepool2 \
        --query "{workloadRuntime:workloadRuntime, osSKU:osSKU, vmSize:vmSize}" \
        --output table
    

    群集预配状态应为 Succeeded。 节点池输出应显示 KataVmIsolation, AzureLinux以及所选的 VM 大小。

使用 Pod 沙盒部署应用程序

通过使用 Pod 沙盒,您可以混合部署不使用 Kata 运行时的标准 Pod,以及使用该运行时的 Kata Pod。 Kata Pod 在其 Pod 规范中指定 runtimeClassName: kata-vm-isolation 。

运行时类选择 Kata 运行时,但当您需要工作负载在特定的 Pod 沙盒节点池上运行时,还应定义调度约束。 例如,在 nodeSelector 中使用内置的 AKS 节点池标签。 用您的 Pod 沙盒节点池名称替换 nodepool2。

spec:
  runtimeClassName: kata-vm-isolation
  nodeSelector:
    kubernetes.azure.com/agentpool: nodepool2

为了实现更强的隔离,您可以为 Pod 沙箱节点池添加污点,并为 Kata 工作负载添加匹配的容忍度。 带有没有匹配容忍的污点会导致其他工作负载无法调度到该节点池上。 有关详细信息,请参阅 在 AKS 群集中使用节点污点。

使用 Kata 运行时部署应用程序

若要在 AKS 群集上使用 Kata 运行时部署 Pod,请执行以下步骤。

  1. 创建名为 kata-app.yaml 的文件来描述你的 Kata Pod,然后粘贴以下的清单。

    kind: Pod
    apiVersion: v1
    metadata:
      name: isolated-pod
    spec:
      runtimeClassName: kata-vm-isolation
      containers:
      - name: kata
        image: mcr.azk8s.cn/aks/fundamental/base-ubuntu:v0.0.11
        command: ["/bin/sh", "-ec", "while :; do echo '.'; sleep 5 ; done"]
    

    runtimeClassName 的 Pod 规范值为 kata-vm-isolation。

  2. 通过运行 kubectl apply 命令并指定 kata-app.yaml 文件来部署 Kubernetes Pod:

    kubectl apply -f kata-app.yaml
    

    该命令的输出类似于以下示例:

    pod/isolated-pod created
    

验证内核隔离(可选)

  1. 若要比较 Kata 和非 Kata Pod 的内核,请创建名为 normal-app.yaml 的文件。 以下配置清单定义了一个不使用 Kata 运行时的标准 Pod:
kind: Pod
apiVersion: v1
metadata:
  name: normal-pod
spec:
  containers:
  - name: non-kata
    image: mcr.azk8s.cn/aks/fundamental/base-ubuntu:v0.0.11
    command: ["/bin/sh", "-ec", "while :; do echo '.'; sleep 5 ; done"]
  1. 使用 kubectl apply 命令部署标准 Pod。

    kubectl apply -f normal-app.yaml
    
  2. 若要访问 AKS 群集内的容器,请通过运行 kubectl exec 命令启动 shell 会话。 在此示例中,你正在访问 isolated-pod 内部的容器。

    kubectl exec -it isolated-pod -- /bin/sh
    

    Kubectl 连接到您的群集,在第一个容器内运行/bin/sh,并将您的终端的输入和输出流转发到isolated-pod的进程。 还可以启动托管非 Kata Pod 的容器的 shell 会话,以查看差异。

  3. 从 isolated-pod 启动到容器的 shell 会话后,运行命令以验证 kata 容器是否在 Pod 沙盒中运行。 与沙盒外部的非 Kata 容器相比,它的内核版本不同。

    若要查看内核版本,请运行以下命令:

    uname -r
    

    以下示例类似于 Pod 沙盒内核的输出:

    [user]/# uname -r
    6.6.96.mshv1
    
  4. 从 normal-pod 启动到容器的 shell 会话,以验证内核输出:

    kubectl exec -it normal-pod -- /bin/bash
    

    若要查看内核版本,请运行以下命令:

    uname -r
    

    以下示例类似于运行 normal-pod 的 VM 的输出,该内核与 Pod 沙盒中运行的 Kata Pod 不同:

    6.6.100.mshv1-1.azl3
    

清理资源

  1. 评估完此功能后,清理不再需要的资源以避免Azure费用。 如果将新群集部署为评估或测试的一部分,请 az aks delete 运行以下命令以删除 AKS 群集。

    az aks delete --resource-group myResourceGroup --name myAKSCluster
    
  2. 如果在现有群集上部署了 Pod 沙盒,则可以使用 kubectl delete pod 命令删除 Pod。

    kubectl get pods
    kubectl delete pod <kata-pod-name>
    
  3. 若要删除 Pod 沙盒计算资源,还可以使用 az aks nodepool delete 命令删除 Kata 节点池。 在删除节点池之前,请确保要保留的工作负荷不会在节点上运行。

    az aks nodepool delete \
      --cluster-name myAKSCluster \
      --resource-group myResourceGroup \
      --name nodepool2
    

后续步骤

  • 详细了解如何对 AKS 群集中的节点使用 Azure 专用主机,以便对 Azure 平台维护事件使用硬件隔离和控制。
  • 若要进一步探索 Pod 沙盒隔离并探索工作负荷方案,请尝试 Pod 沙盒实验室。