本页面介绍了如何使用您在 Cloud Key Management Service (Cloud KMS) 中管理的密钥对存储在 Google Kubernetes Engine (GKE) 控制平面中的数据进行加密。您应当已经熟悉 etcd、GKE 集群架构和 Cloud KMS 等概念。
本页面介绍了 GKE 中一组可选控制平面功能的一部分,这些功能可让您执行各种任务,例如验证控制平面的安全状况,或使用您管理的密钥在控制平面中配置加密和凭据签名。如需了解详情,请参阅关于 GKE control plane authority。
默认情况下, Google Cloud 会对托管式控制平面应用各种安全措施。本页面介绍了一些可选功能,让您更好地了解或控制 GKE 控制平面。
关于控制平面启动磁盘和 etcd 加密
默认情况下,GKE 会使用 Google Cloud管理的加密密钥对控制平面节点的启动磁盘、在 etcd 中存储数据的磁盘以及 etcd 的 Google Cloud 内部操作备份进行加密。如需详细了解此默认加密功能,请参阅默认静态加密。您可以选择性地使用您自己通过 Cloud KMS 来管理的加密密钥对这些资源进行加密。如需了解详情,请参阅控制平面启动磁盘和 etcd 加密。
您可以在 Cloud KMS 中创建密钥,GKE 会使用这些密钥来加密您的控制平面资源。创建这些资源时,请考虑以下事项:
- 您可以对集群中的所有密钥使用一个密钥环,无论各个密钥的用途如何。如果您有现有的密钥环,并且已将其用于其他用途(例如设置自己的证书授权机构),可以将该密钥环用于本指南。
- 您应在与集群相同的 Google Cloud 位置创建密钥,以便缩短延迟时间。
- 对于大多数应用场景,您可以使用软件 Cloud KMS 密钥保护级别。您还可以将硬件密钥与 Cloud HSM 搭配使用。
- 您必须使用 encryption值指定--purpose标志,因为这些密钥用于对称加密。
- 您不应修改密钥销毁的默认时长。
与其他 GKE control plane authority 功能搭配使用
GKE control plane authority 提供以下与自行管理的密钥相关的功能,您在创建集群时必须同时启用这些功能:
- 加密控制平面组件(本页面)
- 运行您自己的证书授权机构 (CA) 和密钥
您只能在创建新的 GKE 集群时启用这些功能。您无法更新现有集群来使用这些功能。如需在同一集群中使用这两种功能,请执行这两篇指南中的所有密钥和 CA 配置程序,然后运行集群创建命令以启用创建集群部分中所述的两组功能。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行 gcloud components update命令以获取最新版本。较早版本的 gcloud CLI 可能不支持运行本文档中的命令。
- 确保您的密钥项目具有用于您的集群的 Cloud KMS 密钥环。您可以在集群位置使用任何现有密钥环。如需创建新的密钥环,请参阅创建密钥环。
- 
  
  
    
      Enable the Cloud Key Management Service API. Roles required to enable APIs To enable APIs, you need the Service Usage Admin IAM role ( roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles.
确定项目
我们建议您使用单独的 Google Cloud 项目,如下所示:
- 密钥项目:包含所有密钥。
- 集群项目:包含您的 GKE 集群。
您可以选择为密钥和 GKE 集群使用同一项目,但我们建议您使用单独的项目,以便管理密钥和加密操作的团队与管理集群的团队分开。
所需的角色和权限
如需获得运行您自己的加密密钥所需的权限,请让您的管理员为您授予以下 IAM 角色:
- 
            创建 Cloud KMS 密钥:密钥项目的 Cloud KMS Admin (roles/cloudkms.admin)
- 
            创建 GKE 集群:集群项目的 Kubernetes Engine Cluster Admin (roles/container.clusterAdmin)
如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
要求
您的集群必须运行 GKE 1.31.1-gke.1846000 版或更高版本。
限制
- 您只能在创建集群期间配置启动磁盘和 etcd 加密密钥。
- 对于区域级 Standard 模式集群和 Autopilot 集群,您创建集群的区域必须在该区域的至少三个可用区中具有适用于 Hyperdisk Balanced 的机密模式的容量。 - 对于可用区级 Standard 模式集群,集群可用区必须具有 Hyperdisk Balanced 容量。如需容量方面的帮助,请与 Cloud Customer Care 团队联系。 
- GKE 仅支持来自 Cloud KMS 的密钥。您不能使用其他 Kubernetes KMS 提供方或其他加密提供方。 
- 不支持 Cloud External Key Manager (Cloud EKM) 密钥。 
- 您无法访问 etcd 的 Google Cloud 内部操作备份或与之进行交互,这些备份仅用于灾难恢复。 
- 不支持多区域级密钥环。您必须使用区域级密钥环。 
- 您可以使用 GKE control plane authority 的区域和可用区取决于您是否还想使用特定功能,具体如下: - 如需使用客户管理的加密密钥对控制平面启动磁盘进行加密,您的集群必须位于以下区域之一:
    - asia-east1
- asia-northeast1
- asia-southeast1
- europe-west1
- europe-west4
- us-central1
- us-east1
- us-east4
- us-east5
- us-south1
- us-west1
- us-west3
- us-west4
 
- 如需将机密 GKE 节点与 GKE control plane authority 搭配使用,您的集群必须位于支持 Hyperdisk Balanced 机密模式的区域。
 - 如果您不使用这些功能,则可以在任何 Google Cloud 位置使用 GKE control plane authority。 
- 如需使用客户管理的加密密钥对控制平面启动磁盘进行加密,您的集群必须位于以下区域之一:
    
创建密钥
在本部分中,您将为控制平面中的启动盘和 etcd 盘创建加密密钥,并为 etcd 的 Google Cloud内部操作备份创建单独的加密密钥。您可以使用一个密钥环来存储所有这些密钥以及集群的任何其他密钥。
- 为控制平面启动磁盘和 etcd 磁盘创建加密密钥: - gcloud kms keys create KCP_DISK_KEY_NAME \ --keyring=KEYRING_NAME \ --location=LOCATION \ --purpose="encryption" \ --protection-level=PROTECTION_LEVEL \ --project=KEY_PROJECT_ID- 替换以下内容: - KCP_DISK_KEY_NAME:控制平面启动磁盘和 etcd 磁盘的加密密钥的名称。
- KEYRING_NAME:用于存储集群加密密钥的密钥环的名称。
- LOCATION:密钥环的 Google Cloud 位置。此位置必须与您的集群位置相同。如需查看区域列表,请在 Cloud KMS 位置表中针对“区域”进行过滤。
- PROTECTION_LEVEL:密钥的保护级别,例如- software或- hsm。
- KEY_PROJECT_ID:您的密钥项目的项目 ID。
 
- 创建 etcd 内部备份加密密钥: - gcloud kms keys create ETCD_BACKUP_KEY_NAME \ --keyring=KEYRING_NAME \ --location=LOCATION \ --purpose="encryption" \ --protection-level=PROTECTION_LEVEL \ --project=KEY_PROJECT_ID- 将 - ETCD_BACKUP_KEY_NAME替换为 etcd 内部备份加密密钥的名称。
向 GKE 服务代理授予 IAM 角色
在本部分中,您将为集群项目中的 GKE 服务代理授予您创建的密钥的 IAM 角色。GKE 服务代理需要这些角色来使用这些密钥对相应的控制平面资源进行加密。
- 查找集群项目编号: - gcloud projects describe CLUSTER_PROJECT_ID \ --format='value(projectNumber)'- 将 - CLUSTER_PROJECT_ID替换为您的 GKE 集群项目的项目 ID。- 输出内容类似如下: - 1234567890
- 为集群项目中的 GKE 服务代理授予启动磁盘和 etcd 磁盘的加密密钥的 Cloud KMS CryptoKey Encrypter/Decrypter ( - roles/cloudkms.cryptoKeyEncrypterDecrypter) 角色:- gcloud kms keys add-iam-policy-binding KCP_DISK_KEY_NAME \ --location=LOCATION \ --keyring=KEYRING_NAME \ --member="serviceAccount:service-CLUSTER_PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com" \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter \ --project=KEY_PROJECT_ID- 替换以下内容: - KCP_DISK_KEY_NAME:磁盘加密密钥的名称。
- LOCATION:密钥的 Google Cloud 位置。
- KEYRING_NAME:包含加密密钥的密钥环的名称。
- CLUSTER_PROJECT_NUMBER:集群项目的数字项目编号(在上一步中获得该编号)。
- KEY_PROJECT_ID:您的密钥项目的项目 ID。
 
- 为集群项目中的 GKE 服务代理授予启动磁盘和 etcd 磁盘的加密密钥的 Cloud KMS CryptoKey Encrypter/Decrypter Via Delegation ( - roles/cloudkms.cryptoKeyEncrypterDecrypterViaDelegation) 角色:- gcloud kms keys add-iam-policy-binding KCP_DISK_KEY_NAME \ --location=LOCATION \ --keyring=KEYRING_NAME \ --member="serviceAccount:service-CLUSTER_PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com" \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypterViaDelegation \ --project=KEY_PROJECT_ID
- 为集群项目中的 GKE 服务代理授予启动磁盘和 etcd 磁盘的加密密钥的 Cloud KMS Key User 角色,以便进行密钥轮替: - gcloud kms keys add-iam-policy-binding KCP_DISK_KEY_NAME \ --location=LOCATION \ --keyring=KEYRING_NAME \ --member="serviceAccount:service-CLUSTER_PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com" \ --role=roles/container.cloudKmsKeyUser \ --project=KEY_PROJECT_ID
- 为集群项目中的 GKE 服务代理授予 etcd 内部备份加密密钥的 Cloud KMS CryptoKey Encrypter ( - roles/cloudkms.cryptoKeyEncrypter) 角色:- gcloud kms keys add-iam-policy-binding ETCD_BACKUP_KEY_NAME \ --location=LOCATION \ --keyring=KEYRING_NAME \ --member="serviceAccount:service-CLUSTER_PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com" \ --role=roles/cloudkms.cryptoKeyEncrypter \ --project=KEY_PROJECT_ID- 将 - ETCD_BACKUP_KEY_NAME替换为 etcd 操作备份加密密钥的名称。- 授予 - roles/cloudkms.cryptoKeyEncrypter角色会阻止 GKE 代表您执行数据库恢复,并且会在出现数据库问题时显著增加恢复功能所需的时间量。如需允许 GKE 为您执行恢复操作,请改为授予- roles/cloudkms.cryptoKeyEncrypterDecrypter角色。
在集群中使用加密密钥
本部分介绍如何确定加密密钥的路径。
- 确定磁盘加密密钥的路径: - gcloud kms keys describe KCP_DISK_KEY_NAME \ --keyring=KEYRING_NAME \ --location=LOCATION \ --project=KEY_PROJECT_ID \ --format="value(name)"- 替换以下内容: - KCP_DISK_KEY_NAME:控制平面启动磁盘和 etcd 磁盘的加密密钥的名称。
- KEYRING_NAME:包含密钥的密钥环的名称。
- LOCATION:密钥的 Google Cloud 位置。
- KEY_PROJECT_ID:您的密钥项目的项目 ID。
 - 输出内容类似如下: - projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/KEYRING_NAME/cryptoKeys/disk-encryption-key
- 确定 etcd 内部备份加密密钥的路径: - gcloud kms keys describe ETCD_BACKUP_KEY_NAME \ --keyring=KEYRING_NAME \ --location=LOCATION \ --project=KEY_PROJECT_ID \ --format="value(name)"- 将 - ETCD_BACKUP_KEY_NAME替换为 etcd 操作备份加密密钥的名称。- 输出内容类似如下: - projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/KEYRING_NAME/cryptoKeys/etcd-backup-encryption-key
创建集群
在本部分中,您将创建一个集群,并根据要配置的 GKE control plane authority 功能指定不同的选项。您只能在创建集群期间对集群配置这些功能。以下命令可创建 Standard 模式集群。如需改为创建 Autopilot 模式集群,请将相同的标志与 gcloud container clusters create-auto 命令搭配使用。
- 如需创建会配置磁盘加密并运行您自己的 CA 和服务账号签名密钥的集群,请执行以下操作: - 执行运行您自己的证书授权机构和密钥中的所有密钥和 CA 配置步骤。
- 按照在新的集群上设置 CA 和密钥中的说明,找到每个服务账号密钥和 CA 的路径。
- 创建集群: - gcloud container clusters create CLUSTER_NAME \ --location=LOCATION \ --project=CLUSTER_PROJECT_ID \ --control-plane-disk-encryption-key=PATH_TO_DISK_KEY \ --gkeops-etcd-backup-encryption-key=PATH_TO_ETCD_BACKUP_KEY \ --service-account-signing-keys=PATH_TO_SIGNING_KEY_VERSION \ --service-account-verification-keys=PATH_TO_VERIFICATION_KEY_VERSION \ --cluster-ca=PATH_TO_CLUSTER_CA \ --etcd-peer-ca=PATH_TO_ETCD_PEER_CA \ --etcd-api-ca=PATH_TO_ETCD_API_CA \ --aggregation-ca=PATH_TO_AGGREGATION_CA- 替换以下内容: - CLUSTER_NAME:新集群的名称。
- LOCATION:新集群的位置。
- CLUSTER_PROJECT_ID:您的集群项目的项目 ID。
- PATH_TO_DISK_KEY:本页上前面步骤中磁盘加密密钥的路径。
- PATH_TO_ETCD_BACKUP_KEY:本页上前面步骤中 etcd 内部备份加密密钥的路径。
- PATH_TO_SIGNING_KEY_VERSION:Cloud KMS 中 Kubernetes ServiceAccount 签名密钥版本的路径。
- PATH_TO_VERIFICATION_KEY_VERSION:Cloud KMS 中 Kubernetes ServiceAccount 验证密钥版本的路径。
- PATH_TO_CLUSTER_CA:集群 CA 池的路径。
- PATH_TO_ETCD_PEER_CA:etcd 对等 CA 池的路径。
- PATH_TO_ETCD_API_CA:etcd API CA 池的路径。
- PATH_TO_AGGREGATION_CA:汇总 CA 池的路径。
 
 
- 如需创建仅使用您在本指南中创建的密钥来配置磁盘加密的集群,请运行以下命令: - gcloud container clusters create CLUSTER_NAME \ --location=LOCATION \ --project=CLUSTER_PROJECT_ID \ --control-plane-disk-encryption-key=PATH_TO_DISK_KEY \ --gkeops-etcd-backup-encryption-key=PATH_TO_ETCD_BACKUP_KEY- 替换以下内容: - CLUSTER_NAME:新集群的名称。
- LOCATION:新集群的位置。
- CLUSTER_PROJECT_ID:您的集群项目的项目 ID。
- PATH_TO_DISK_KEY:前面步骤中磁盘加密密钥的路径。
- PATH_TO_ETCD_BACKUP_KEY:前面步骤中 etcd 内部备份加密密钥的路径。
 
您还可以在创建新的 Standard 模式集群时指定所有这些标志。
验证加密密钥状态
本部分介绍如何验证在创建集群期间使用的加密密钥。您可以使用 Cloud Logging 或 Google Cloud CLI 执行此验证。
使用 Logging 验证密钥
如需使用 Logging 验证密钥,请执行以下操作:
- 在 Google Cloud 控制台中,前往 Logs Explorer 页面: 
- 通过指定以下查询来获取集群创建日志: - resource.type="gke_cluster" resource.labels.cluster_name="CLUSTER_NAME" resource.labels.location="CLUSTER_LOCATION" protoPayload.serviceName="container.googleapis.com" protoPayload.methodName=~"google.container.v(1|1alpha1|1beta1).ClusterManager.CreateCluster" protoPayload.request.cluster.userManagedKeysConfig:*
- 点击运行查询。 
在输出中,检查集群创建参数是否包含与您在 Cloud KMS 中设置的密钥对应的密钥路径,如以下示例所示:
# lines omitted for clarity
userManagedKeysConfig: {
  controlPlaneDiskEncryptionKey: "projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING_NAME/cryptoKeys/KCP_DISK_KEY_NAME"
  gkeopsEtcdBackupEncryptionKey: "projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING_NAME/cryptoKeys/ETCD_BACKUP_KEY_NAME"
}
使用 gcloud CLI 验证密钥
如需使用 gcloud CLI 验证加密密钥,请执行以下操作:
- 对于磁盘加密密钥,请运行以下命令: - gcloud container clusters describe CLUSTER_NAME \ --location=LOCATION \ --format="value(userManagedKeysConfig.controlPlaneDiskEncryptionKey)"
- 对于 etcd 内部备份加密密钥,请运行以下命令: - gcloud container clusters describe CLUSTER_NAME \ --location=LOCATION \ --format="value(userManagedKeysConfig.gkeopsEtcdBackupEncryptionKey)"
轮替 etcd 和控制平面磁盘加密密钥
您创建的加密密钥不会过期。为了改善安全状况,请定期轮替这些密钥,并使用新的密钥版本重新加密资源。如需了解详情,请参阅轮替 etcd 和控制平面启动磁盘加密密钥。