GKE Sandbox

在 Google Kubernetes Engine (GKE) 集群中执行未知或不可信代码的容器可能会对节点的主机内核造成安全风险。您可以通过将代码与内核隔离来保护主机内核免受这些威胁。本文档介绍了 GKE Sandbox 如何使用 gVisor 和微虚拟机等技术来创建此隔离层。

本文档面向希望减小 GKE 节点中的攻击面并保护节点免受不受信任的代码攻击的安全专家。您应该已经熟悉以下内容:

GKE 中的沙盒化简介

安装在节点上的容器运行时(例如 containerd)会在容器的进程与节点上运行的内核之间提供一定程度的隔离。不过,容器运行时通常以特权用户身份在节点上运行,有权访问针对主机内核的大多数系统调用。

在 Kubernetes 和 GKE 中,沙盒会隔离正在运行的容器,以限制影响其他容器或容器运行时的漏洞或错误的潜在影响。您可以在沙盒中运行容器,以保护底层 Compute Engine 实例的内核免受不受信任或未知代码的侵害。沙盒也是一种很好的深度防御措施,可保护高价值容器免受其他工作负载的影响。您可以使用 GKE Sandbox 在沙盒中运行工作负载。

潜在威胁

容器运行时或主机内核中的缺陷可能会导致在容器内运行的进程“逃逸”容器并影响节点的内核。与其他集群相比,多租户集群和容器运行不受信任的工作负载的集群更容易受到安全漏洞的影响。示例如下:

  • 允许用户上传和运行代码的组织,例如 SaaS 提供商和网站托管提供商。
  • 可生成和执行代码的 AI 智能体,通常无需监督。

GKE Sandbox 使用的沙盒技术有助于缓解容器逃逸可能造成的以下影响:

  • 导致主机内核崩溃并使节点瘫痪的恶意或有缺陷的代码。
  • 恶意租户窃取内存或磁盘中其他租户的数据。
  • 访问其他 Google Cloud 服务或集群元数据的不可信工作负载。

GKE 中的沙盒技术

GKE Sandbox 支持以下沙盒技术,每种技术都使用不同的方法来隔离工作负载,并且适用于不同的使用情形:

  • gVisor:Linux 内核 API 的用户空间重新实现,不需要提升权限。用户空间内核和容器运行时会重新实现大多数系统调用,并代表主机内核为这些调用提供服务。对主机内核的直接访问会受到限制。如需详细了解客机内核的工作原理,请参阅 gVisor 架构指南。

  • MicroVMs:运行完整 Linux 内核和操作系统的轻量级虚拟机。每个 Pod 都在自己的微型虚拟机中运行,可与其他 Pod 和宿主节点严格隔离。GKE Sandbox 使用开源 Kata Containers 软件和 Cloud Hypervisor 虚拟机监控器 (VMM) 来创建和管理微型虚拟机。

下表总结了 gVisor 和微型虚拟机之间的主要区别。 您可以根据这些信息为您的应用场景选择合适的沙盒技术。

gVisor MicroVMs
内核访问权限 Linux 内核系统调用的子集 完整 Linux 内核
隔离级别 用户空间内核中的系统调用拦截 具有专用客户内核的完整硬件虚拟化
CPU 和内存开销 用户空间内核的动态开销(基本内存较低) 每个 Pod 的固定开销为 250 mCPU 和 130 MiB 内存
开始时间 低于 200 毫秒 大约 1 到 2 秒
GKE 节点配置 适用于任何 Standard 节点池和 Autopilot 节点。在 Autopilot 集群中默认处于启用状态。 仅在启用嵌套虚拟化的节点中可用。
节点映像支持 仅限 Container-Optimized OS Container-Optimized OS 或 Ubuntu
机器类型兼容性 大多数 CPU、Arm 架构和加速器机器类型都支持此功能。 仅受支持嵌套虚拟化的机器类型支持。
加速器支持 支持特定的 GPU 型号和 TPU 版本。 不支持 GPU 或 TPU。
特权容器 不受支持。 支持。特权容器仅获得对微虚拟机中的客机操作系统的根访问权限,而不会获得对宿主节点的根访问权限。
应用场景示例
  • 使用 Rust、Java、Python、PHP、Node.js 或 Golang 等运行时的不受信任应用或第三方应用
  • Web 服务器前端、缓存或代理
  • 使用 CPU 处理外部媒体或数据的应用
  • GPU 和 TPU 密集型工作负载
  • 处理任意输入或运行代码的 AI 推理工作负载
  • 处理大型第三方数据集和模型的训练工作负载
  • AI 智能体,无需监督即可生成和执行代码
  • 在浏览器中运行的自主代码,例如 Puppeteer
  • 需要访问完整 Linux 内核的工作负载
  • 生成大量低开销系统调用的工作负载,例如大量的小型 I/O 操作

如需了解更多可能有助于您决定在特定类型的沙盒中运行哪些应用的信息,请参阅限制。

如何请求沙盒

如需在沙盒中运行应用,请执行以下操作:

  1. 通过使用 ComputeClass 自动创建节点或手动创建节点池,在节点中启用沙盒技术。
  2. 使用相应沙盒类型的 RuntimeClass(例如 gvisor 或 microvm)为 Pod 请求沙盒。如需了解详情,请参阅利用 GKE Sandbox 强化工作负载隔离。

GKE 会在使用所请求的沙盒技术的节点上调度 Pod,然后由该节点负责在沙盒中运行应用。您可以选择使用节点选择器和容忍设置,在启用了 GKE Sandbox 的节点上运行不请求沙盒的 Pod,这对于您希望在每个节点上运行的监控工具等受信任的工作负载非常有用。

其他安全建议

此外,我们建议您在使用 GKE Sandbox 时遵循以下建议:

  • 为沙盒中运行的所有容器指定资源限制。这样可以防范有缺陷的应用或恶意应用所带来的风险。此类应用会消耗节点的资源,并对节点上运行的其他应用或系统进程产生负面影响。

  • 如果您使用的是适用于 GKE 的工作负载身份联合,请使用网络政策阻止集群元数据访问,从而阻止访问 169.254.169.254。这样可以防范恶意应用访问项目 ID、节点名称和可用区等可能涉及用户隐私数据信息所带来的风险。GKE Autopilot 集群中会始终启用适用于 GKE 的工作负载身份联合。

限制

GKE Sandbox 适合许多应用,但并不适合所有应用。本部分详细介绍了 GKE Sandbox 的当前限制。

GKE Sandbox 中的 GPU

您可以使用 gVisor 在沙盒中运行 GPU 工作负载。gVisor 无法缓解所有 NVIDIA 驱动程序漏洞,但仍可防范 Linux 内核漏洞。请勿在沙盒化 Pod 中使用 GPU 分时,因为 GPU 在 Pod 之间并非完全隔离。如需详细了解 gVisor 如何保护 GPU 工作负载,请参阅 GPU 支持指南。

以下限制适用于 GKE Sandbox 中的 GPU 工作负载:

  • MicroVM 不支持 GPU。
  • 对于 gVisor,存在以下限制:
    • 仅支持 CUDA 工作负载。
    • 仅支持部分可用的 GPU 型号。如需了解详情,请参阅 GPU 型号支持。
    • 每个 GKE 版本仅支持 latest 和 default NVIDIA 驱动程序版本。其他驱动程序版本可能无法正常运行。
    • 不支持所有 GPU 功能,例如 RDMA 或 IMEX。根据客户需求,gVisor 可能会视具体情况支持特定功能。如需针对特定功能请求支持,请提交支持请求或提交 gVisor 功能请求。

GPU 型号支持

下表介绍了 GKE Sandbox 对不同 GPU 型号的支持情况:

型号 预览版 Google Analytics 支持 备注
  • NVIDIA RTX PRO 6000
  • 具有一个或多个 GPU 的机器类型:1.34.1-gke.2037001 及更高版本
  • GPU 数量少于 1 个的机器类型:不支持
  • - -
  • NVIDIA GB200
  • NVIDIA B200
  • NVIDIA H200 141GB
  • 1.34.0-gke.1713000 及更高版本
  • - -
  • NVIDIA H100 80GB
  • NVIDIA A100 80GB
  • NVIDIA A100 40GB
  • NVIDIA L4
  • NVIDIA T4
  • -
  • 1.29.15-gke.1134000 及更高版本
  • 1.30.11-gke.1093000 及更高版本
  • 1.31.7-gke.1149000 及更高版本
  • 1.32.2-gke.1182003 及更高版本
  • 自最初发布以来一直受支持。
  • NVIDIA V100
  • NVIDIA P100(即将停止提供支持)
  • 不支持 不支持 V100 和 P100 使用专有驱动程序,因此不受支持。
  • NVIDIA T4 VWS
  • NVIDIA L4 VWS
  • - - GKE Sandbox 不支持 Windows 或 Ubuntu 节点类型,而虚拟工作站节点需要这些节点类型。

    GKE Sandbox 中的 TPU

    在 GKE 1.31.3-gke.1111001 及更高版本中,您可以使用 gVisor 在沙盒中运行 TPU 工作负载。gVisor 无法解决所有 TPU 驱动程序漏洞,但仍然可以防范 Linux 内核漏洞。如需详细了解 gVisor 项目如何保护 TPU 工作负载,请参阅 TPU 支持指南。

    以下限制适用于 GKE Sandbox 中的 TPU 工作负载:

    • MicroVM 不支持 TPU。
    • gVisor 支持以下 TPU 版本:

      • V4pod
      • V4lite
      • V5litepod
      • V5pod
      • V6e

    节点配置

    以下限制适用于使用 GKE Sandbox 的节点:

    • gVisor 和 microVM 仅支持 Linux 节点。不支持 Windows Server 节点。
    • gVisor 仅支持 Container-Optimized OS 节点映像。微虚拟机支持 Container-Optimized OS 和 Ubuntu 节点映像。
    • MicroVM 需要在节点上启用嵌套虚拟化。需遵守嵌套虚拟化的所有要求和限制。
    • 在 Standard 集群中,您无法在默认节点池池上启用 GKE Sandbox。集群必须始终至少有一个不使用 GKE Sandbox 的节点池。该节点池必须至少包含一个节点,即使您的所有工作负载都已放入沙盒也是如此。此限制旨在将系统服务与不受信任的工作负载分开。

    集群元数据访问权限

    如果您的节点使用 gVisor 沙盒类型,则节点上的 Pod 无法在节点操作系统级访问集群元数据。Pod 也无法访问 Google Cloud服务,除非您使用 Workload Identity Federation for GKE 向 Pod 身份授予角色。

    此限制不适用于 microVM 沙盒类型。如需防止微虚拟机的 Pod 访问集群元数据,请使用拒绝出站流量的 NetworkPolicy,以阻止 Pod 访问端口 988 上的 169.254.169.252/32 或(在使用 GKE Dataplane V2 的集群中)端口 80 上的 169.254.169.254/32。

    SMT 可能已停用

    并发多线程 (SMT) 设置(在 Intel CPU 上也称为超线程)可用于缓解利用共享核心状态的线程的边信道漏洞,例如微架构数据抽样 (MDS) 漏洞。

    为缓解旁道攻击,gVisor 使用 Linux 核心调度。SMT 设置保留为默认值。Linux 核心调度仅适用于在 gVisor 沙盒中运行的 Pod。

    机器类型的默认 SMT 或超线程设置取决于机器受 MDS 漏洞影响的程度,如下所示:

    • 使用 Scale-Out ComputeClass 的 Autopilot Pod:始终停用 SMT。
    • 使用 Intel 处理器的机器类型:默认停用超线程。
    • 使用 AMD 处理器的机器类型:默认启用 SMT。
    • 每个核心仅使用一个线程的机器类型,例如 Arm 处理器:不支持 SMT。请求的所有 vCPU 都可见。

    启用 SMT

    在 GKE Standard 节点池中,如果所选机器类型默认停用了 SMT,您可以将其启用。无论您是启用 SMT 还是停用 SMT,您都需要为每个 vCPU 支付费用。如需了解详情,请参阅更改每个核心的线程数时的价格。如需更改 SMT 设置,请执行以下操作之一:

    • 创建使用 gVisor 的 GKE Sandbox 节点池时,请设置 --threads-per-core 标志:

      gcloud container node-pools create smt-enabled \
          --cluster=CLUSTER_NAME \
          --location=LOCATION \
          --machine-type=MACHINE_TYPE \
          --threads-per-core=2 \
          --sandbox=type=gvisor
      
      • CLUSTER_NAME:要在其中创建新节点池的现有集群的名称。
      • LOCATION:集群的 Compute Engine 区域或可用区。
      • MACHINE_TYPE:机器类型。
    • 使用 DaemonSet 在现有节点池池上启用 SMT:

      1. 将 cloud.google.com/gke-smt-disabled=false 节点标签添加到使用 gVisor 的现有节点池:

        gcloud container node-pools update NODE_POOL_NAME \
            --cluster=CLUSTER_NAME \
            --location=LOCATION \
            --node-labels=cloud.google.com/gke-smt-disabled=false
        

        替换以下内容:

        • NODE_POOL_NAME:现有节点池的名称。
        • CLUSTER_NAME:要在其中创建新节点池的现有集群的名称。
        • LOCATION:集群的 Compute Engine 区域或可用区。
      2. 部署 DaemonSet。DaemonSet 仅在具有 cloud.google.com/gke-smt-disabled=false 标签的节点上运行。

        kubectl create -f \
            https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-node-tools/master/disable-smt/gke/enable-smt.yaml
        
      3. 确保 DaemonSet Pod 处于运行状态。

        kubectl get pods --selector=name=enable-smt -n kube-system
        

        输出类似于以下内容:

        NAME               READY     STATUS    RESTARTS   AGE
        enable-smt-2xnnc   1/1       Running   0          6m
        
      4. 检查 Pod 的日志中是否出现 SMT has been enabled:

        kubectl logs enable-smt-2xnnc enable-smt -n kube-system
        

    功能

    适用于 Standard 集群

    默认情况下,系统会阻止容器打开原始套接字,以降低恶意攻击的可能性。某些与网络相关的工具(例如 ping 和 tcpdump)会在其核心操作中创建原始套接字。如需启用原始套接字,您必须向容器的安全上下文明确添加 NET_RAW 功能:

    spec:
      containers:
      - name: my-container
        securityContext:
          capabilities:
            add: ["NET_RAW"]
    

    如果您使用 GKE Autopilot, Google Cloud 会阻止您向容器添加 NET_RAW 权限,因为此功能会带来安全隐患。

    外部依赖项

    适用于 Autopilot 和 Standard 集群

    在沙盒内运行的不可信代码可以访问数据库服务器、API、其他容器和 CSI 驱动程序等外部服务。 这些服务在沙盒边界之外运行,需要单独进行保护。攻击者可能尝试利用这些服务中的漏洞来攻击沙盒。您必须考虑沙盒内运行的代码可以访问这些服务时所存在的风险和影响,并采取必要的措施来保护这些服务。

    这包括 ext4 和 CSI 驱动程序等容器卷的文件系统实现。CSI 驱动程序在沙盒隔离机制外部运行,可能拥有访问主机和服务的特权。这些驱动程序中的漏洞会影响主机内核,并危及整个节点。我们建议您在具有最少必需权限的容器内运行 CSI 驱动程序,以降低因漏洞而引发的数据泄露风险。GKE Sandbox 支持使用 Compute Engine Persistent Disk CSI 驱动程序。

    不兼容的功能

    GKE Sandbox 存在以下功能限制:

    • 以下限制同时适用于 gVisor 沙盒和微型虚拟机沙盒:

    • 以下限制仅适用于 gVisor 沙盒:

    • 以下限制仅适用于 microVM 沙盒:

      • 不支持使用 hostNetwork: true 设置的 Pod。 在微型虚拟机沙盒中运行并使用 hostNetwork: true 设置的 Pod 无法访问 Pod 之外的任何资源。
      • 任何依赖于套接字级跟踪的诊断工具都只能访问连接到 microVM 的网络接口。

    后续步骤