GKE Sandbox


本页面介绍 GKE Sandbox 在 Pod 中的容器执行未知或不可信代码时如何保护节点上的主机内核。例如,软件即服务 (SaaS) 提供商这样的多租户集群常常会执行其用户提交的未知代码。

GKE Sandbox 使用开源项目 gVisor。本主题广泛讨论了 gVisor,但您可以通过阅读官方 gVisor 文档来了解详情。

如需详细了解如何启用 GKE Sandbox,请参阅配置 GKE Sandbox

概览

GKE Sandbox 提供了一道额外的安全保障,可防止不可信代码影响集群节点上的主机内核。在讨论 GKE Sandbox 的工作原理之前,了解它有助于缓解的潜在风险的特性非常有用。

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

潜在威胁

多租户集群以及容器运行不可信工作负载的集群比其他集群更容易出现安全漏洞。相关的例子包括 SaaS 提供商、网站托管服务提供商或允许其用户上传和运行代码的其他组织。容器运行时或主机内核中的缺陷可能允许容器内运行的进程“逃离”容器并影响节点的内核,从而可能导致节点停机。

恶意租户也可能带来潜在风险,比如,该租户通过利用此类缺陷,可以访问并窃取内存或磁盘中其他租户的数据。

最后,不可信工作负载可能会访问其他 Google Cloud 服务或集群元数据。

GKE Sandbox 如何缓解这些威胁

gVisor 是 Linux 内核 API 的用户空间重新实现,不需要提升权限。通过与 containerd 之类的容器运行时搭配使用,该用户空间内核可重新实现大多数系统调用并代表主机内核为它们提供服务。对主机内核的直接访问会受到限制。请参阅 gVisor 架构指南,详细了解其工作原理。从容器的角度来看,gVisor 几乎是透明的,并且不需要对容器化应用进行任何更改。

对节点池启用 GKE Sandbox 后,系统会为该节点池中的节点上运行的每个 Pod 创建一个沙盒。此外,系统会阻止运行沙盒化 Pod 的节点访问其他 Google Cloud 服务或集群元数据。

每个沙盒都会使用自己的用户空间内核。考虑到这一点,您可以根据所需的隔离级别以及应用的特征,决定如何将容器分组到 Pod 中。

GKE Sandbox 特别适合以下类型的应用。请参阅限制,了解帮助您确定要将哪些应用放入沙盒中的详情。

  • 使用 Rust、Java、Python、PHP、Node.js 或 Golang 等运行时的不可信应用或第三方应用
  • Web 服务器前端、缓存或代理
  • 使用 CPU 处理外部媒体或数据的应用
  • 使用 CPU 的机器学习工作负载
  • CPU 密集型或内存密集型应用

其他安全建议

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

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

  • 如果您使用的是 Workload Identity,我们建议您使用网络政策阻止集群元数据访问,从而阻止访问 IP 169.254.169.254。这样可以防范恶意应用访问项目 ID、节点名称和可用区等可能涉及用户隐私数据信息所带来的风险。

限制

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

节点池配置

  • 您无法在 Windows Server 节点池上使用 GKE Sandbox。
  • 您无法对默认节点池启用 GKE Sandbox。
  • 使用 GKE Sandbox 时,您的集群必须至少具有两个节点池。您必须始终至少有一个节点池停用 GKE Sandbox。此节点池必须至少包含一个节点,即使您的所有工作负载都已放入沙盒也是如此。
  • 节点池不能使用 e2-micro、e2-small、e2-medium 机器类型。

集群元数据访问权限

  • 系统会阻止运行沙盒化 Pod 的节点访问节点上操作系统级别的集群元数据。
  • 您可以在启用了 GKE Sandbox 的节点上运行常规 Pod。不过,默认情况下,这些常规 Pod 无法访问 Google Cloud 服务或集群元数据。
  • 请使用 Workload Identity 向 Pod 授予访问 Google Cloud 服务的权限。

超线程已停用

gVisor 节点默认会停用所有架构上的超线程,以缓解利用超线程之间共享的核心状态的边信道漏洞。例如,微架构数据抽样 (MDS) 漏洞。如需为节点池启用超线程,请执行以下操作:

  1. 在集群中使用节点标签 cloud.google.com/gke-smt-disabled=false 创建一个新的节点池:

    gcloud container node-pools create smt-enabled --cluster=cluster-name \
        --machine-type=machine-type \
        --node-labels=cloud.google.com/gke-smt-disabled=false \
        --image-type=cos_containerd \
        --sandbox type=gvisor
    
  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
    
  4. 您应该会收到类似如下的响应:

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

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

功能

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

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

外部依赖项

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

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

不兼容的功能

目前,无法将 GKE Sandbox 与以下 Kubernetes 功能搭配使用:

  • GPU 或 TPU 等加速器
  • 监控 Pod 或容器级别的统计信息
  • Hostpath 存储空间
  • CPU 和内存限制仅应用于 Guaranteed Pod 和 Burstable Pod,并且仅当为 Pod 中运行的所有容器指定了 CPU 和内存限制时才会应用。
  • 使用 PodSecurityPolicy(用于指定主机命名空间,例如 hostNetworkhostPIDhostIPC)的 Pod
  • 使用 PodSecurityPolicy 设置(例如特权模式)的 Pod
  • VolumeDevices
  • Portforward
  • Linux 内核安全模块,例如 Seccomp、Apparmor、Selinux SysctlNoNewPrivileges双向 MountPropagationFSGroupProcMount
  • Traffic Director
  • 1.18.6-gke.4801 之前的集群版本不支持 Istio。1.18.6-gke.4801 及更高版本支持 Istio。

工作负载特性

为访问节点内核的操作施加额外的间接处理会导致性能受到影响。GKE Sandbox 为非常需要隔离的大型多租户集群提供了最切实的好处。使用 GKE Sandbox 测试工作负载时,请牢记以下准则。

系统调用

生成大量低开销系统调用的工作负载(例如大量的小型 IO 操作)在沙盒中运行时可能需要更多系统资源,因此您可能需要使用功能更强大的节点或向集群添加额外的节点。

直接访问硬件或虚拟化

如果您的工作负载需要使用以下任一功能,则 GKE Sandbox 可能不太合适,因为它会阻止直接访问节点上的主机内核:

  • 直接访问节点的硬件
  • 内核级虚拟化功能
  • 特权容器

后续步骤