安全概览

Google Kubernetes Engine (GKE) 提供许多帮助保护工作负载的方法。在 GKE 中保护工作负载涉及堆栈的多个层,包括容器映像的内容、容器运行时环境、集群网络以及对集群 API 服务器的访问权限。

最好采用分层方法来保护集群和工作负载。您可以针对提供给用户及应用的访问权限级别,应用最小权限原则。在每一层中,您可能必须做出不同的取舍,以提供适当的灵活性和安全性级别,让组织能够安全地部署和维护其工作负载。例如,一些安全设置对于某些类型的应用或使用场景而言约束性太强,若不进行重大重构,则将无法正常工作。

本文档概述了基础架构的每一层,并介绍如何配置每一层的安全功能才最符合您的需求。

身份验证和授权

Kubernetes 支持两种类型的身份验证

  1. 用户帐号是 Kubernetes 已知的帐号,但不由 Kubernetes 管理,例如,您无法使用 kubectl 创建或删除它们。
  2. 服务帐号是由 Kubernetes 创建和管理的帐号,但只能由 Kubernetes 创建的实体(如 Pod)使用。

在 GKE 集群中,Kubernetes 用户帐号由 Google Cloud 管理,可以是以下两种类型之一:

  1. Google 帐号
  2. Google Cloud 服务帐号

通过身份验证后,您需要授权这些身份以创建、读取、更新或删除 Kubernetes 资源。

尽管名称相似,但 Kubernetes 服务帐号和 Google Cloud 服务帐号是不同的实体。Kubernetes 服务帐号是定义它们的集群的一部分,通常在该集群中使用。相比之下,Google Cloud 服务帐号是 Google Cloud 项目的一部分,可以轻松地在集群和 Google Cloud 项目集群本身以及使用 Identity and Access Management (IAM) 的任何 Google Cloud 资源中授予权限。这使得 Google Cloud 服务帐号比 Kubernetes 服务帐号更强大;为了遵循最小权限的安全原则,您应该考虑仅在需要其功能时使用 Google Cloud 服务帐号。

要在集群级层或 Kubernetes 命名空间内配置对 Kubernetes 资源的更精细的访问权限,您可以使用基于角色的访问控制 (RBAC)。 通过 RBAC,您可以制定详细的政策,以定义您允许用户及服务帐号访问的操作和资源。您可以使用 RBAC 来控制 Google 帐号、Google Cloud 服务帐号和 Kubernetes 服务帐号的访问权限。如需进一步简化和精简 GKE 的身份验证和授权策略,您应该确保旧版基于特性的访问权限控制处于停用状态,以使 Kubernetes RBAC 和 Cloud IAM 成为可靠来源。

如需了解详情,请执行以下操作:

控制层面安全

在 GKE 中,Kubernetes 控制层面组件由 Google 管理和维护。控制层面组件托管用于运行 Kubernetes 控制层面的软件,包括 API 服务器、调度器、控制器管理器和 Kubernetes 配置持久保存所在的 etcd 数据库

默认情况下,控制层面组件使用公共 IP 地址。要保护 Kubernetes API 服务器,您可以使用授权网络专用集群,以允许您将专用 IP 地址分配给控制层面并停用对公共 IP 地址的访问权限。

您可以使用 IAM 作为身份提供商,在 Google Kubernetes Engine 中处理集群身份验证。如需了解身份验证,请参阅向 Kubernetes API 服务器进行身份验证

帮助保护控制层面的另一个方法是确保定期执行凭据轮替。启动凭据轮替后,SSL 证书和集群证书授权机构会轮替。此过程由 GKE 自动执行,并且还确保您的控制层面 IP 地址会轮替。

如需了解详情,请执行以下操作:

节点安全

GKE 将工作负载部署到 Google Cloud 项目中运行的 Compute Engine 实例上。这些实例会作为节点关联到 GKE 集群。以下各个部分介绍如何利用 Google Cloud 中提供给您的节点级层安全功能。

Container-Optimized OS

默认情况下,GKE 节点使用 Google 的 Container-Optimized OS 作为运行 Kubernetes 及其组件的操作系统。Container-Optimized OS 实现了多项高级功能来增强 GKE 集群的安全性,其中包括:

  • 锁定防火墙
  • 只读文件系统(如果可能)
  • 受限用户帐号和停用 root 登录

节点升级

最佳做法是定期修补您的操作系统。容器运行时、Kubernetes 本身或节点操作系统中的安全问题可能会不时地要求您升级节点,而且更加迫切。升级节点时,节点的软件会升级到最新版本。

您可以手动升级集群中的节点,但 GKE 也允许您启用自动升级

保护节点以免受到不受信任的工作负载影响

对于运行未知或不可信工作负载的集群,良好的做法是保护节点上的操作系统,使其免受 Pod 中不受信任的工作负载的影响。

例如,软件即服务 (SaaS) 提供商等多租户集群通常会执行其用户提交的未知代码。安全研究则是工作负载可能需要比节点默认设置更强力的隔离的另一种应用。

您可以在集群上启用 GKE Sandbox,在节点上将不受信任的工作负载隔离到沙盒中。 GKE Sandbox 是通过开源项目 gVisor 构建的。

保护实例元数据

GKE 节点作为 Compute Engine 实例运行,因此默认情况下,它们可以访问实例元数据。实例元数据用于为节点提供引导和连接控制层面节点时所用的凭据和配置。但是,在节点上运行的 Pod 不一定需要该信息,该信息包含敏感数据,如节点的服务帐号密钥。 您可以通过停用旧版 API 和通过使用元数据隐藏来锁定敏感实例元数据路径。元数据隐藏可过滤对 kube-env 等字段的请求,从而确保在集群中运行的 Pod 无法访问敏感数据。

网络安全

在 GKE 中运行的大多数工作负载需要与其他服务通信,这些服务可能在集群内部运行,也可能在集群外部运行。您可以使用多种不同方法来控制允许流经集群及其 Pod 的流量。

限制 Pod 到 Pod 的通信

默认情况下,您可以通过网络藉由 Pod IP 地址访问集群中的所有 Pod。同样,默认情况下,只要地址可在部署集群所在的 VPC 中进行访问,出站流量就允许建立连到该地址的出站连接。

创建进出 Pod 的入站和出站连接后,集群管理员和用户可以使用网络政策在命名空间中锁定这些连接。 默认情况下,如果未定义网络政策,则允许所有入站和出站流量流入和流出所有 Pod。网络政策允许您使用标签来定义流经 Pod 的流量。

在命名空间中应用了网络政策后,进出 Pod 的流量如果与所配置标签不相符,则全都删除。作为创建集群和/或命名空间的一部分,您可以对每个 Pod 应用默认拒绝入站和出站流量,以确保添加到集群的所有新工作负载必须向它们所需的流量明确授权。

如需了解详情,请执行以下操作:

过滤负载平衡的流量

要通过网络负载平衡器对您的 Kubernetes Pod 进行负载平衡,您需要创建类型为 LoadBalancer 且与 Pod 标签匹配的 Service。创建 Service 后,您将获得面向外部的 IP,该 IP 映射到 Kubernetes Pod 上的端口。您可以使用 kube-proxy 在节点级别上根据 IP 地址过滤经过授权的流量。

要配置此过滤条件,您可以使用 Service 对象的 loadBalancerSourceRanges 配置。借助此配置参数,您可以提供一份想要允许访问 Service 的 CIDR 范围列表。如果您未配置 loadBalancerSourceRanges,则系统允许所有地址通过其外部 IP 地址访问 Service。

如果不需要访问 Service,请考虑使用内部负载平衡器。 如果需过滤掉 VPC 内部的流量,则内部负载平衡器也遵循 loadBalancerSourceRanges

如需了解详情,请参阅内部负载平衡教程

保护工作负载

Kubernetes 可让用户快速预配、扩缩和更新基于容器的工作负载。本部分介绍的策略可供管理员和用户用来限制正在运行的容器对同一集群中的其他容器、容器在其中运行的节点,以及用户项目中启用的 Google Cloud 服务产生的影响。

限制 Pod 容器进程权限

限制容器化进程的权限对于集群的总体安全性十分重要。GKE 允许您通过安全上下文对 Pod 和容器设置安全相关选项。通过这些设置,您可以更改进程的安全设置,例如:

  • 以其身份运行的用户和组
  • 可用的 Linux 功能
  • 提升权限的能力

要在集群级别更改这些设置,而不是在 Pod 或容器中更改设置,您需要实现 PodSecurityPolicy。 集群管理员可以使用 PodSecurityPolicy 来确保集群中的所有 Pod 均遵循您定义的最低基准政策。

GKE 节点操作系统(Container-Optimized OS 和 Ubuntu)会针对 Kubernetes 启动的所有容器应用默认的 Docker AppArmor 安全政策。您可以在 GitHub 上查看配置文件的模板。除此之外,配置文件会拒绝向容器提供以下能力:

  • 直接将文件写入 /proc/
  • 写入至不在进程 ID 目录 (/proc/<number>) 中的文件
  • 写入至 /proc/sys 中的文件(/proc/sys/kernel/shm* 除外)
  • 装载文件系统

如需了解详情,请执行以下操作:

向 Pod 授予访问 Google Cloud 资源的权限

您的容器和 Pod 可能需要访问 Google Cloud 中的其他资源。您可以通过三种方法实现此目的。

如需授权 Pod 访问 Google Cloud 资源,最简单安全的方法就是 Workload Identity。Workload Identity 允许您将 Kubernetes 服务帐号作为 Google Cloud 服务帐号运行。以 Kubernetes 服务帐号运行的 Pod 拥有 Google Cloud 服务帐号的权限。

Workload Identity 可与 GKE Sandbox 搭配使用。

节点服务帐号

您的 Pod 还可以使用来自元数据的 Kubernetes 集群服务帐号凭据向 Google Cloud 进行身份验证。但是,如果未启用 Workload Identity,则集群中运行的任何 Pod 都可以访问这些凭据。请创建并配置具有最低权限 IAM 角色的自定义服务帐号,并保证这些角色满足集群中运行的所有 Pod 的需求。

这种方法与 GKE Sandbox 不兼容,因为 GKE Sandbox 会阻止对元数据服务器的访问。

服务帐号 JSON 密钥

如需向应用授予允许其访问 Google Cloud 资源的凭据,第三种方法是手动使用服务帐号密钥。这种方法会造成您很难安全管理帐号密钥,因此强烈不建议使用。

您应该使用应用专用的 Google Cloud 服务帐号来提供凭据,以使应用具有最小的必要权限。系统仅会为每个服务帐号分配配对应用成功运行所需的 IAM 角色。通过使服务帐号成为应用专用的服务帐号,您可以在服务帐号被盗用时轻松撤消其访问权限,而不影响其他应用。为您的服务帐号分配了正确的 IAM 角色后,您可以创建 JSON 服务帐号密钥,然后使用 Kubernetes Secret 将该密钥装载到您的 Pod。

使用 Binary Authorization

Binary Authorization 是 Google Cloud 中的一项服务,为在云端运行的应用提供软件供应链安全性。Binary Authorization 适用于从 Container Registry 或其他容器映像注册表部署到 GKE 的映像。通过 Binary Authorization,您可以确保在将应用部署到生产环境之前,已成功完成保护软件质量和完整性的内部过程。

如需了解如何创建启用了 Binary Authorization 的集群,请参阅 Binary Authorization 文档中的创建集群

审核日志记录

通过审核日志记录,管理员可以针对 GKE 环境中发生的事件进行保留、查询、处理和提醒。管理员可以使用日志中记录的信息执行取证分析、实时提醒,或者对一组 GKE 集群的使用方式和用户进行编目。

默认情况下,GKE 会记录管理员活动日志。您还可以选择记录数据访问事件,具体取决于您有兴趣检查的操作类型。

如需了解详情,请执行以下操作: