本页面介绍了 GKE on AWS 的安全架构,包括加密和节点配置。
GKE 集群提供了多项功能来帮助保护工作负载,包括容器映像的内容、容器运行时、集群网络以及对集群 API 服务器的访问权限。
使用 GKE 集群时,您同意为集群承担某些责任。如需了解详情,请参阅 GKE 集群共担责任。
AWS KMS 加密
GKE on AWS 使用客户管理的 AWS Key Management Service (KMS) 对称密钥进行加密:
在生产环境中,我们建议为配置和卷加密使用不同的密钥。为了进一步降低密钥泄露的风险,您还可以为以下每个项目创建不同的密钥:
为了提高安全性,您可以创建 AWS KMS 密钥政策,并仅分配最小权限集。如需了解详情,请参阅创建具有特定权限的 KMS 密钥。
静态数据加密
静态数据加密是存储的数据加密,与传输中的数据不同。默认情况下,GKE on AWS 使用 AWS 平台管理的密钥来加密 etcd 和存储卷中的静态数据。
GKE on AWS 集群将数据存储在 AWS Elastic Block Storage (EBS) 卷中。这些 EBS 卷始终使用 AWS Key Management System (AWS KMS) 密钥进行加密。创建集群和节点池时,您可以提供客户管理的 KMS 密钥 (CMK) 来加密底层 EBS 卷。如果未指定密钥,AWS 会在运行集群的 AWS 区域中使用AWS 管理的默认密钥。
此外,所有 GKE 集群都会为敏感数据启用应用层 Secret 加密,例如存储在 etcd 中的 Kubernetes Secret 对象。即使攻击者可以访问存储 etcd 数据的底层卷,这些数据也会进行加密。
创建集群时,您必须将 AWS KMS 密钥传递给 --database-encryption-kms-key-arn
字段。此密钥用于对应用数据进行信封加密。由于此资源字段是不可变的,并且集群一旦创建便无法修改,因此我们建议您使用 KMS 密钥别名。您可以使用密钥别名在集群的整个生命周期内轮替用于静态加密的密钥。
应用级加密的工作原理
Kubernetes 使用一种称为信封加密的技术提供应用级加密。本地密钥通常称为 DEK(数据加密密钥),用于加密 Secret。然后,DEK 本身使用名为 KEK(密钥加密密钥)的第二个密钥进行加密。KEK 不由 Kubernetes 存储。创建新的 Kubernetes Secret 时,您的集群将执行以下操作:
Kubernetes API 服务器使用随机号码生成器为 Secret 生成唯一的 DEK。
Kubernetes API 服务器使用 DEK 在本地加密 Secret。
Kubernetes API 服务器将 DEK 发送到 AWS KMS 进行加密。
AWS KMS 使用预先生成的 KEK 来加密 DEK,并将加密的 DEK 返回到 Kubernetes API 服务器的 AWS KMS 插件。
Kubernetes API 服务器将加密的 Secret 和加密的 DEK 保存到 etcd。明文 DEK 不会保存到磁盘。
Kubernetes API 服务器会创建一个内存中缓存条目,将加密的 DEK 映射到明文 DEK。这样,API 服务器无需查询 AWS KMS 即可解密最近访问的 Secret,而。
当客户端从 Kubernetes API 服务器请求 Secret 时,会经历以下步骤:
Kubernetes API 服务器从 etcd 中检索加密的 Secret 和加密的 DEK。
Kubernetes API 服务器检查现有映射条目的缓存,如果找到,则使用该缓存解密 Secret。
如果没有匹配的缓存条目,API 服务器会使用 KEK 将 DEK 发送到 AWS KMS 进行解密。然后,使用解密的 DEK 对 Secret 进行解密。
最后,Kubernetes API 服务器将解密的 Secret 返回给客户端。
密钥轮替
与证书轮替相比,密钥轮替就是更改 KEK 中包含的底层加密材料的行为。它可作为计划轮替的一部分自动触发,也可手动触发。通常是在出现安全突发事件,导致密钥可能已遭破解之后进行手动触发。密钥轮替仅替换包含原始加密/解密密钥数据的密钥中的单个字段。
KMS 密钥轮替
AWS KMS 支持自动轮替 KMS 密钥。启用后,AWS 每年自动为您的密钥生成一次新的加密密钥材料。您无需采取任何手动操作。
如需了解详情,请参阅密钥轮替。
集群信任
所有集群通信都使用传输层安全协议 (TLS)。每个集群均预配以下主要自签名根证书授权机构 (CA):
- 集群根 CA 用于验证发送到 API 服务器的请求。
- etcd 根 CA 用于验证发送到 etcd 副本的请求。
每个集群都有唯一的根 CA。如果某个集群的 CA 被盗用,也不会影响其他集群的 CA。所有根 CA 的有效期均为 30 年。
节点安全
GKE on AWS 将您的工作负载部署到 AWS EC2 实例的节点池上。以下部分介绍节点的安全功能。
Ubuntu
您的节点运行优化版 Ubuntu 操作系统来运行 Kubernetes 控制平面和节点。如需了解详情,请参阅 Ubuntu 文档中的安全功能。
GKE 集群实现了几项安全功能,包括下列各项:
其他适用于 Ubuntu 的安全指南,例如:
保护您的工作负载
Kubernetes 可让用户快速预配、扩缩和更新基于容器的工作负载。本部分介绍的策略可用于限制在集群和 Google Cloud 服务上运行容器时产生的副作用。
限制 Pod 容器进程权限
限制容器化进程的权限对于集群的安全性至关重要。您可以使用安全上下文来设置与安全相关的选项。通过这些设置,您可以更改进程的安全设置,如下所示:
- 运行该进程的用户和群组
- 可用的 Linux 功能
- 提升权限
默认的 GKE on AWS 节点操作系统 Ubuntu 对所有容器使用默认的 Docker AppArmor 安全政策。您可以在 GitHub 上查看配置文件的模板。除此之外,此配置文件会拒绝容器以下功能:
- 直接写入至进程 ID 目录 (
/proc/
) 中的文件 - 写入至不在
/proc/
中的文件 - 写入至
/proc/sys
中的文件(/proc/sys/kernel/shm*
除外) - 装载文件系统
限制工作负载自行修改的能力
某些 Kubernetes 工作负载(尤其是系统工作负载)有权执行自行修改。例如,某些工作负载会自行纵向自动扩缩。虽然很方便,但这会使得已入侵节点的攻击者能够在集群中进行进一步的操作。例如,攻击者可能会使节点上的工作负载自行更改,以将其作为在同一命名空间内具有更高权限的服务账号运行。
理想情况下,不应最初便为工作负载授予自行修改的权限。如果需要自行修改,您可以通过在集群中安装 Policy Controller 或 Gatekeeper 并应用限制条件来限制权限,例如可以使用开源 Gatekeeper 库中提供的 NoUpdateServiceAccount(该库提供了许多有用的安全政策)。
部署政策时,通常需要允许管理集群生命周期的控制器绕过政策。这样控制器才能更改集群,例如应用集群升级。例如,如果您在 GKE on AWS 上部署 NoUpdateServiceAccount
政策,则必须在 Constraint
中设置以下参数:
parameters:
allowedGroups: []
allowedUsers:
- service-PROJECT_NUMBER@gcp-sa-gkemulticloud.iam.gserviceaccount.com
将 PROJECT_NUMBER
替换为托管集群的项目的编号(而非 ID)。
使用 Binary Authorization
另一种保护工作负载的方法是启用 Binary Authorization。Binary Authorization 是一项安全功能,可确保在 GKE 集群上仅部署受信任的容器映像。
具体流程如下:
管理员创建一项政策来定义部署映像的要求。这包括指定可对映像签名的可信和已获授权的实体(证明者),还可能包括映像被视为部署安全所必须满足的其他条件。
证明者(例如开发者或自动化系统)使用加密算法生成密钥对(私钥和公钥)。
私钥是保密的,用于为映像生成数字签名(即一组唯一的字符)。此签名充当批准印章,表明映像已通过所有必要的检查和验证。
然后,数字签名会“附加”到映像。换句话说,该签名存储在映像的元数据中,通常存储在映像注册表中。
公钥随后注册到 Binary Authorization 系统,以便系统可以使用公钥进行签名验证。
发出部署容器的请求后,Binary Authorization 系统会检索注册表中的映像附加的数字签名。
Binary Authorization 系统使用注册的公钥来验证附加到映像的数字签名。它还会检查映像是否符合政策中定义的所有其他条件。如果使用公钥和映像数据可以成功验证数字签名,并且映像满足政策中定义的所有其他条件,则 Binary Authorization 系统允许部署容器。如果使用公钥和映像数据无法成功验证数字签名,或者映像不符合政策中的其他条件,Binary Authorization 系统会拒绝容器部署。
如需详细了解 Binary Authorization 的工作原理,请参阅 Binary Authorization 概览。
如需在现有集群上启用 Binary Authorization 或者在创建集群时启用,请参阅如何启用 Binary Authorization。
在专用节点池上隔离工作负载
您可以使用 Kubernetes 污点和容忍设置指定特定节点池来运行特定类型的工作负载。例如,您可以指示 GKE on AWS 将用户工作负载与大多数系统管理的工作负载分开进行调度,或者将具有不同信任级别的工作负载放置在不同节点池上。
使用污点和容忍设置进行工作负载隔离不是一种有保证的安全措施。请仅将此安全措施与 GKE on AWS 提供的其他安全加固措施搭配使用。
如需了解详情,请参阅在专用节点池中隔离工作负载。
后续步骤
- 了解密钥轮替。