安全概览
本页面介绍 GKE on Azure 的安全架构,包括加密和节点配置。
GKE 集群提供了多项功能来帮助保护工作负载,包括容器映像的内容、容器运行时、集群网络以及对集群 API 服务器的访问权限。
使用 GKE 集群时,您同意为集群承担某些责任。如需了解详情,请参阅 GKE 集群共担责任。
静态数据加密
静态数据加密是存储的数据加密,与传输中的数据不同。默认情况下,GKE on Azure 使用 Azure 平台管理的密钥来加密 etcd 和存储卷中的静态数据。
GKE on Azure 集群将数据存储在 Azure 磁盘卷中。这些卷始终使用 Azure Key Vault 密钥进行静态加密。创建集群和节点池时,您可以提供客户管理的 Keyvault 密钥以加密集群的底层磁盘卷。如果您没有指定密钥,则 Azure 会在集群运行的 Azure 区域内使用默认的 Azure 管理密钥。
此外,所有 GKE 集群都会为敏感数据启用应用层 Secret 加密,例如存储在 etcd 中的 Kubernetes 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 时,您的集群将执行以下操作:
Kubernetes API 服务器使用随机号码生成器为 Secret 生成唯一的 DEK。
Kubernetes API 服务器使用 DEK 在本地加密 Secret。
Kubernetes API 服务器将 DEK 发送到 Azure Key Vault 进行加密。
Azure Key Vault 使用预先生成的 KEK 来加密 DEK,并将加密的 DEK 返回到 Kubernetes API 服务器的 Azure Key Vault 插件。
Kubernetes API 服务器将加密的 Secret 和加密的 DEK 保存到 etcd。明文 DEK 不会保存到磁盘。
Kubernetes API 服务器会创建一个内存中缓存条目,将加密的 DEK 映射到明文 DEK。这样,API 服务器无需查询 Azure Key Vault 即可解密最近访问的 Secret。
当客户端从 Kubernetes API 服务器请求 Secret 时,会经历以下步骤:
Kubernetes API 服务器从 etcd 中检索加密的 Secret 和加密的 DEK。
Kubernetes API 服务器检查现有映射条目的缓存,如果找到,则使用该缓存解密 Secret。
如果没有匹配的缓存条目,API 服务器会使用 KEK 将 DEK 发送到 Azure Key Vault 进行解密。然后,使用解密的 DEK 对 Secret 进行解密。
最后,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 Controller 或 Gatekeeper 并应用限制条件来限制权限,例如可以使用开源 Gatekeeper 库中提供的 NoUpdateServiceAccount(该库提供了许多有用的安全政策)。
部署政策时,通常需要允许管理集群生命周期的控制器绕过政策。这样控制器才能更改集群,例如应用集群升级。例如,如果您在 GKE on Azure 上部署 NoUpdateServiceAccount
政策,则必须在 Constraint
中设置以下参数:
parameters:
allowedGroups: []
allowedUsers:
- service-PROJECT_NUMBER@gcp-sa-gkemulticloud.iam.gserviceaccount.com
将 PROJECT_NUMBER
替换为托管集群的项目的编号(而非 ID)。
在专用节点池上隔离工作负载
您可以使用 Kubernetes 污点和容忍指定特定节点池来运行特定类型的工作负载。例如,您可以指示 GKE on Azure 将用户工作负载与大多数系统管理的工作负载分开进行安排,或者将具有不同信任级别的工作负载放置在不同节点池上。
使用污点和容忍进行工作负载隔离不是一种有保证的安全措施。请仅将此方法与 GKE on Azure 提供的其他安全强化措施搭配使用。
如需了解详情,请参阅在专用节点池中隔离工作负载。
后续步骤
- 了解密钥轮替。