安全概览

本页面介绍了 GKE on Azure 的安全架构,包括加密和节点配置。

GKE 集群提供了帮助保护工作负载的功能,包括容器映像的内容、容器运行时、集群网络以及对集群 API 服务器的访问权限。

使用 GKE 集群时,即表示您同意为您的集群承担某些责任。如需了解详情,请参阅 GKE 集群共担责任

静态数据加密

静态数据加密是存储的数据加密,与传输中的数据不同。默认情况下,GKE on Azure 使用 Azure 平台管理的密钥对 etcd 和静态存储卷中的数据进行加密。

GKE on Azure 集群将数据存储在 Azure 磁盘卷中。这些卷始终使用 Azure Key Vault 密钥进行静态加密。创建集群和节点池时,您可以提供客户管理的 Keyvault 密钥以加密集群的底层磁盘卷。如果您没有指定密钥,则 Azure 会在集群运行的 Azure 区域内使用默认的 Azure 管理密钥

此外,所有 GKE 集群都会为敏感数据(例如存储在 etcd 中的 Kubernetes Secret 对象)启用应用层 Secret 加密。即使攻击者可以访问存储 etcd 数据的底层卷,这些数据也会进行加密。

创建集群时,您可以在 --database-encryption-kms-key-arn 参数中提供 Azure Key Vault 密钥。此密钥用于加密应用数据。如果您在创建集群期间未提供密钥,GKE on Azure 会自动为您的集群创建一个密钥。此资源字段是不可变的,创建集群后无法修改。

您还可以手动创建 Key Vault 密钥或使用硬件安全模块 (HSM) 自带密钥 (BYOK)。如需了解详情,请参阅自带密钥

应用级加密的工作原理

Kubernetes 使用一种称为信封加密的技术提供应用级加密。本地密钥通常称为 DEK(数据加密密钥),用于加密 Secret。然后,DEK 本身使用名为 KEK(密钥加密密钥)的第二个密钥进行加密。KEK 不由 Kubernetes 存储。创建新的 Kubernetes Secret 时,您的集群将执行以下操作:

  1. Kubernetes API 服务器使用随机号码生成器为 Secret 生成唯一的 DEK。

  2. Kubernetes API 服务器使用 DEK 在本地加密 Secret。

  3. Kubernetes API 服务器将 DEK 发送到 Azure Key Vault 进行加密。

  4. Azure Key Vault 使用预先生成的 KEK 来加密 DEK,并将加密的 DEK 返回到 Kubernetes API 服务器的 Azure Key Vault 插件。

  5. Kubernetes API 服务器将加密的 Secret 和加密的 DEK 保存到 etcd。明文 DEK 不会保存到磁盘。

  6. Kubernetes API 服务器会创建一个内存中缓存条目,将加密的 DEK 映射到明文 DEK。这样,API 服务器无需查询 Azure Key Vault 即可解密最近访问的 Secret。

当客户端从 Kubernetes API 服务器请求 Secret 时,会经历以下步骤:

  1. Kubernetes API 服务器从 etcd 中检索加密的 Secret 和加密的 DEK。

  2. Kubernetes API 服务器检查现有映射条目的缓存,如果找到,则使用该缓存解密 Secret。

  3. 如果没有匹配的缓存条目,API 服务器会使用 KEK 将 DEK 发送到 Azure Key Vault 进行解密。然后,使用解密的 DEK 对 Secret 进行解密。

  4. 最后,Kubernetes API 服务器将解密的 Secret 返回给客户端。

使用密钥保险柜防火墙的配置加密

如果您传递公钥进行加密,则服务主账号无需加密权限,但需要管理角色分配的权限。执行此操作最简单的方法是为您的服务主账号分配 Azure User Access Administrator 内置角色。

为进一步保护 Azure Key Vault,您可以启用 Azure Key Vault 防火墙。然后,GKE on Azure 可以使用公钥进行加密,并避免网络访问密钥保管库。

如需配置防火墙,请使用 Azure CLI 下载 Key Vault 密钥。使用 Google Cloud CLI 创建集群时,请将密钥传递给 --config-encryption-public-key

您仍然需要在用于集群的所有子网中为 Key Vault 启用服务端点。如需了解详情,请参阅 Azure Key Vault 的虚拟网络服务端点

密钥轮替

与证书轮替相比,密钥轮替就是更改 KEK 中包含的底层加密材料的行为。它可作为计划轮替的一部分自动触发,也可手动触发。通常是在出现安全突发事件,导致密钥可能已遭破解之后进行手动触发。密钥轮替仅替换包含原始加密/解密密钥数据的密钥中的单个字段。

如需了解详情,请参阅密钥轮替

集群信任

所有集群通信都使用传输层安全协议 (TLS)。每个集群均预配以下主要自签名根证书授权机构 (CA):

  • 集群根 CA 用于验证发送到 API 服务器的请求。
  • etcd 根 CA 用于验证发送到 etcd 副本的请求。

每个集群都有唯一的根 CA。如果某个集群的 CA 被盗用,也不会影响其他集群的 CA。所有根 CA 的有效期均为 30 年。

节点安全

GKE on Azure 可将您的工作负载部署到 Azure 虚拟机实例的节点池上。以下部分介绍节点的安全功能。

Ubuntu

您的节点运行优化版 Ubuntu 操作系统来运行 Kubernetes 控制层面和节点。如需了解详情,请参阅 Ubuntu 文档中的安全功能

GKE 集群实现了多项安全功能,包括:

其他适用于 Ubuntu 的安全指南,例如:

保护您的工作负载

Kubernetes 可让用户快速预配、扩缩和更新基于容器的工作负载。本部分介绍的策略可用于限制在集群和 Google Cloud 服务上运行容器时产生的副作用。

限制 Pod 容器进程权限

限制容器化进程的权限对于集群的安全性至关重要。您可以使用安全上下文来设置与安全相关的选项。通过这些设置,您可以更改进程的安全设置,如下所示:

  • 运行该进程的用户和群组
  • 可用的 Linux 功能
  • 提升权限

默认的 GKE on Azure 节点操作系统 Ubuntu 对所有容器使用默认的 Docker AppArmor 安全政策。您可以在 GitHub 上查看配置文件的模板。除此之外,此配置文件会拒绝容器以下功能:

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

限制工作负载自行修改的能力

某些 Kubernetes 工作负载(尤其是系统工作负载)有权执行自行修改。例如,某些工作负载会自行纵向自动扩缩。虽然很方便,但这会使得已入侵节点的攻击者能够在集群中进行进一步的操作。例如,攻击者可能会使节点上的工作负载自行更改,以将其作为在同一命名空间内具有更高权限的服务账号运行。

理想情况下,不应最初便为工作负载授予自行修改的权限。如果确实需要自行修改,您可以通过在集群中安装 Policy ControllerGatekeeper 并应用限制条件(例如开源 Gatekeeper 库中的 NoUpdateServiceAccount)来限制权限,以提供多项有用的安全政策。

部署政策时,通常需要允许管理集群生命周期的控制器绕过政策。这样控制器才能更改集群,例如应用集群升级。例如,如果您在 GKE on Azure 上部署 NoUpdateServiceAccount 政策,则必须在 Constraint 中设置以下参数:

parameters:
  allowedGroups: []
  allowedUsers:
  - service-PROJECT_NUMBER@gcp-sa-gkemulticloud.iam.gserviceaccount.com

PROJECT_NUMBER 替换为托管集群的项目的编号(而非 ID)。

后续步骤