本页面介绍如何将 Cloud Key Management Service (Cloud KMS) 加密密钥与 Dataflow 配合使用。借助 CMEK,您可以使用自己能够通过 Cloud KMS 控制的密钥对静态数据进行加密。您可以创建受 CMEK 保护的批处理或流处理流水线,或者访问来源和接收器中受 CMEK 保护的数据。
您还可以使用 Cloud EKM 或 Cloud HSM 密钥。在 Dataflow 中使用 CMEK 时,您的项目可以使用 Cloud KMS 加密请求配额。例如,当流水线访问来源和接收器中受 CMEK 保护的数据或者系统检索使用 CMEK 加密的流水线状态时,Dataflow 流水线会消耗这些配额。如需了解详情,请参阅本页面中的流水线状态位置加密部分。仅当您使用硬件 (Cloud HSM) 或外部 (Cloud EKM) 密钥时,使用 CMEK 密钥执行的加密和解密操作才会影响 Cloud KMS 配额。如需了解详情,请参阅 Cloud KMS 配额。
借助 Cloud External Key Manager (Cloud EKM),您可以使用您在支持的外部密钥管理合作伙伴内管理的密钥来保护 Google Cloud 中的数据。您可以通过支持的 CMEK 集成服务或直接调用 Dataflow API 来保护静态数据。
如需了解详情,请参阅 Google Cloud 上的加密选项。
支持和限制
以下 Apache Beam SDK 版本支持 Cloud KMS:
- Java SDK 2.13.0 版及更高版本
- Python SDK 2.13.0 版及更高版本
- Go SDK 2.40.0 版及更高版本
将 Cloud KMS 与 Dataflow 搭配使用支持区域级密钥。如果您替换流水线的工作器区域或可用区以使用与密钥关联的区域不同的区域,则区域级密钥不起作用。
您的 CMEK 区域和 Dataflow 作业的区域必须相同。
不支持多区域和全球位置。您不能将全球级密钥和多区域级密钥与 Dataflow 流水线搭配使用。
流水线状态工件加密
除了您为流式作业中的基于密钥的转换指定的数据密钥以外,Dataflow 流水线从用户指定的数据源读取的数据均已加密。
对于批处理作业,所有数据(包括您为基于密钥的转换指定的数据密钥)始终受 CMEK 加密保护。
对于 2024 年 3 月 7 日之后创建的流处理作业,所有用户数据都使用 CMEK 进行加密。
对于在 2024 年 3 月 7 日之前创建的流处理作业,基于密钥的操作(例如数据选取、分组和联接)中使用的数据密钥不受 CMEK 加密保护。如需为作业启用此加密,请排空或取消作业,然后重启作业。
作业元数据未使用 Cloud KMS 密钥进行加密。作业元数据包括以下数据:
- 用户提供的数据,例如作业名称、作业参数值和流水线图表
- 系统生成的数据,例如作业 ID 和工作器的 IP 地址
流水线状态位置加密
以下存储位置受 Cloud KMS 密钥保护:
- 挂接到 Dataflow 工作器且用于基于永久性磁盘的 shuffle 和流处理状态存储的永久性磁盘。
- 批处理流水线的 Dataflow Shuffle 状态。
- 存储临时导出或导入数据的 Cloud Storage 存储桶。Dataflow 仅支持用户在存储桶级别设置的默认密钥。
- 用于存储包含流水线代码的二进制文件的 Cloud Storage 存储桶。Dataflow 仅支持用户在存储桶级别设置的默认密钥。
- 启用数据采样后,用于存储采样流水线数据的 Cloud Storage 存储桶。
- 流处理流水线的 Dataflow Streaming Engine 状态。
外部密钥
您可以通过 Cloud External Key Manager (Cloud EKM) 使用您管理的外部密钥加密 Google Cloud 中的数据。
当您使用 Cloud EKM 密钥时,Google 无法控制外部管理的密钥的可用性。如果密钥在作业或流水线创建期间不可用,则系统会取消作业或流水线。
如需了解使用外部密钥的更多注意事项,请参阅 Cloud External Key Manager。
准备工作
确认您有 Java 版 Apache Beam SDK 2.13.0 或更高版本、Python 版 Apache Beam SDK 2.13.0 或更高版本,或者 Go 版 Apache Beam SDK 2.40.0 或更高版本。
如需了解详情,请参阅安装 Apache Beam SDK。
确定您要在同一个 Google Cloud 项目中还是在不同项目中运行 Dataflow 和 Cloud KMS。本页面使用以下约定:
PROJECT_ID
是运行 Dataflow 的项目的 ID。PROJECT_NUMBER
是运行 Dataflow 的项目的编号。KMS_PROJECT_ID
是运行 Cloud KMS 的项目的 ID。
如需了解 Google Cloud 项目 ID 和项目编号,请参阅识别项目。
在要运行 Cloud KMS 的 Google Cloud 项目中,执行以下操作:
- 启用 Cloud KMS API。
- 按照创建对称密钥中的说明创建密钥环和密钥。Cloud KMS 和 Dataflow 都是区域化服务。您的 CMEK 区域和 Dataflow 作业的区域必须相同。请勿将全球级密钥或多区域级密钥与 Dataflow 流水线搭配使用。应改为使用区域级密钥。
授予 Encrypter/Decrypter 权限
将
Cloud KMS CryptoKey Encrypter/Decrypter
角色分配给 Dataflow 服务账号。此权限会向您的 Dataflow 服务账号授予使用您指定的 CMEK 进行加密和解密的权限。如果您使用 Google Cloud 控制台和基于模板创建作业页面,则系统会自动授予此权限,您可以跳过此步骤。使用 Google Cloud CLI 分配该角色:
gcloud projects add-iam-policy-binding KMS_PROJECT_ID \ --member serviceAccount:service-PROJECT_NUMBER@dataflow-service-producer-prod.iam.gserviceaccount.com \ --role roles/cloudkms.cryptoKeyEncrypterDecrypter
将
KMS_PROJECT_ID
替换为运行 Cloud KMS 的 Google Cloud 项目的 ID,并将PROJECT_NUMBER
替换为运行 Dataflow 资源的 Google Cloud 项目的编号(而非项目 ID)。将
Cloud KMS CryptoKey Encrypter/Decrypter
角色分配给 Compute Engine 服务账号。此权限会向您的 Compute Engine 服务账号授予使用您指定的 CMEK 进行加密和解密的权限。使用 Google Cloud CLI 分配该角色:
gcloud projects add-iam-policy-binding KMS_PROJECT_ID \ --member serviceAccount:service-PROJECT_NUMBER@compute-system.iam.gserviceaccount.com \ --role roles/cloudkms.cryptoKeyEncrypterDecrypter
将
KMS_PROJECT_ID
替换为运行 Cloud KMS 的 Google Cloud 项目的 ID,并将PROJECT_NUMBER
替换为运行 Compute Engine 资源的 Google Cloud 项目的编号(而非项目 ID)。
创建受 Cloud KMS 保护的流水线
创建批处理或流处理流水线时,您可以选择 Cloud KMS 密钥来对流水线状态进行加密。流水线状态是 Dataflow 在临时存储空间中存储的数据。
命令行界面
如需使用受 Cloud KMS 密钥保护的流水线状态创建新的流水线,请向流水线参数添加相关的标志。以下示例演示了如何使用 Cloud KMS 运行字数统计流水线。
Java
使用 Cloud KMS 密钥时,Dataflow 不支持为临时文件创建默认的 Cloud Storage 路径。必须指定 gcpTempLocation
。
mvn compile exec:java -Dexec.mainClass=org.apache.beam.examples.WordCount \ -Dexec.args="--inputFile=gs://dataflow-samples/shakespeare/kinglear.txt \ --output=gs://STORAGE_BUCKET/counts \ --runner=DataflowRunner --project=PROJECT_ID \ --gcpTempLocation=gs://STORAGE_BUCKET/tmp \ --dataflowKmsKey=KMS_KEY" -Pdataflow-runner
Python
使用 Cloud KMS 密钥时,Dataflow 不支持为临时文件创建默认的 Cloud Storage 路径。必须指定 gcpTempLocation
。
python -m apache_beam.examples.wordcount \ --input gs://dataflow-samples/shakespeare/kinglear.txt \ --output gs://STORAGE_BUCKET/counts \ --runner DataflowRunner \ --region HOST_GCP_REGION \ --project PROJECT_ID \ --temp_location gs://STORAGE_BUCKET/tmp/ \ --dataflow_kms_key=KMS_KEY
Go
使用 Cloud KMS 密钥时,Dataflow 不支持为临时文件创建默认的 Cloud Storage 路径。必须指定 gcpTempLocation
。
wordcount --project HOST_PROJECT_ID \ --region HOST_GCP_REGION \ --runner dataflow \ --staging_location gs://STORAGE_BUCKET/staging \ --temp_location gs://STORAGE_BUCKET/temp \ --input gs://dataflow-samples/shakespeare/kinglear.txt \ --output gs://STORAGE_BUCKET/output \ --dataflow_kms_key=KMS_KEY
Google Cloud 控制台
- 打开 Dataflow 监控界面。
前往 Dataflow 网页界面 - 选择基于模板创建作业。
- 在加密部分中,选择客户管理的密钥。
第一次尝试使用特定的 Cloud KMS 密钥运行作业时,您的 Compute Engine 服务账号或 Dataflow 服务账号可能尚未获得使用该密钥进行加密和解密的权限。在这种情况下,系统会显示警告消息,提示您向服务账号授予权限。
验证 Cloud KMS 密钥使用情况
您可以使用 Google Cloud 控制台或 Google Cloud CLI 来验证流水线是否使用了 Cloud KMS 密钥。
控制台
- 打开 Dataflow 监控界面。
前往 Dataflow 网页界面 - 如需查看作业详细信息,请选择 Dataflow 作业。
- 在作业信息侧边栏中,如需查看密钥类型,请勾选加密类型字段。
- 对于加密类型:“Google 管理的密钥”
- 对于加密类型:“客户管理的密钥”
CLI
使用 gcloud CLI 运行 describe
命令:
gcloud dataflow jobs describe JOB_ID
搜索包含 serviceKmsKeyName
的行。此信息表明,Cloud KMS 密钥已用于 Dataflow 流水线状态加密。
您可以使用 Pub/Sub、Cloud Storage 和 BigQuery 等源和接收器的 Google Cloud 控制台页面和工具来验证 Cloud KMS 密钥是否用于加密源和接收器。您还可以查看 Cloud KMS 审核日志来验证 Cloud KMS 密钥的使用情况。
停用或销毁密钥
如果由于任何原因您可能需要停用或销毁密钥,您可以使用 Google Cloud 控制台。停用和销毁操作都会使用该密钥取消作业。此操作是永久性的。
如果您使用的是 Cloud EKM,请在外部密钥管理器中停用或销毁密钥。
如果您使用的是 Streaming Engine 选项,建议您在停用密钥之前先截取作业的快照。
移除 Dataflow 对 Cloud KMS 密钥的访问权限
您可以按照以下步骤移除 Dataflow 对 Cloud KMS 密钥的访问权限:
- 使用 Google Cloud 控制台或 gcloud CLI 撤消 Dataflow 服务账号的
Cloud KMS CryptoKey Encrypter/Decrypter
角色。 - 使用 Google Cloud 控制台或 gcloud CLI 撤消 Compute Engine 服务账号的
Cloud KMS CryptoKey Encrypter/Decrypter
角色。 - 或者,您也可以选择销毁密钥版本材料,以进一步防止 Dataflow 和其他服务访问流水线状态。
虽然您可以销毁密钥版本资料,但无法删除密钥和密钥环。密钥环和密钥没有可结算费用或配额限制,因此它们的持续存在不会影响费用或生产环境限制。
Dataflow 作业会定期验证 Dataflow 服务账号能否成功使用给定的 Cloud KMS 密钥。如果加密或解密请求失败,Dataflow 服务会尽快停止所有数据注入和处理。Dataflow 会立即开始清理附加到作业的 Google Cloud 资源。
使用受 Cloud KMS 密钥保护的来源和接收器
Dataflow 可以访问受 Cloud KMS 密钥保护的 Google Cloud 来源和接收器。如果您不创建新对象,则无需指定这些来源和接收器的 Cloud KMS 密钥。如果 Dataflow 流水线可能在接收器中创建新对象,则您必须定义流水线参数。这些参数会为该接收器指定 Cloud KMS 密钥,并将此 Cloud KMS 密钥传递给适当的 I/O 连接器方法。
对于不支持由 Cloud KMS 管理的 CMEK 的 Dataflow 流水线来源和接收器,Dataflow CMEK 设置无关紧要。
Cloud KMS 密钥权限
在访问受 Cloud KMS 密钥保护的服务时,请验证您是否已为该服务分配了 Cloud KMS CryptoKey Encrypter/Decrypter
角色。相关账号的格式如下:
- Cloud Storage:
service-{project_number}@gs-project-accounts.iam.gserviceaccount.com
- BigQuery:
bq-{project_number}@bigquery-encryption.iam.gserviceaccount.com
- Pub/Sub:
service-{project_number}@gcp-sa-pubsub.iam.gserviceaccount.com
Cloud Storage
如果您希望保护自己使用 TempLocation
/temp_location
和 stagingLocation
/staging_location
流水线参数指定的临时存储桶和暂存存储桶,请参阅设置受 CMEK 保护的 Cloud Storage 存储桶。
BigQuery
Java
对来自 BigQueryIO.readTableRows()
、BigQueryIO.read()
、BigQueryIO.writeTableRows()
、BigQueryIO.write()
的返回值使用 with_kms_key()
方法。
您可以在 Apache Beam GitHub 代码库中找到示例。
Python
使用 BigQuerySource 和 BigQuerySink 中的 kms_key
参数。
您可以在 Apache Beam GitHub 代码库中找到示例。
Go
BigQuery IO 不支持在 Go 中使用 KMS 密钥。
Pub/Sub
Dataflow 使用您的主题 CMEK 配置来处理对受 CMEK 保护的主题的访问权限。
如需对受 CMEK 保护的 Pub/Sub 主题执行读写操作,请参阅有关使用 CMEK 的 Pub/Sub 说明。
Cloud KMS 密钥使用情况的审核日志记录
Dataflow 允许 Cloud KMS 使用 Cloud Audit Logs 来记录密钥操作,例如加密和解密。Dataflow 将作业 ID 作为上下文提供给 Cloud KMS 调用方。借助此 ID,您可以跟踪每个实例,因为 Dataflow 作业使用特定的 Cloud KMS 密钥。
Cloud Audit Logs 会为每个 Google Cloud 项目、文件夹和组织维护审核日志。您可以通过多种方式查看 Cloud KMS 审核日志。
Cloud KMS 会为采用 CMEK 加密的 Dataflow 作业写入管理员活动审核日志。这些日志记录了修改资源配置或资源元数据的操作。您无法停用管理员活动审核日志。
在明确启用的情况下,Cloud KMS 会为采用 CMEK 加密的 Dataflow 作业写入数据访问审核日志。数据访问审核日志包含用于读取资源配置或元数据的 API 调用。这些日志还包含用户进行的用于创建、修改或读取用户所提供资源数据的 API 调用。如需了解如何启用部分或全部数据访问审核日志,请参阅配置数据访问日志。
价格
在 Cloud KMS 可用的所有 Dataflow 区域中,您都可以将 Cloud KMS 加密密钥与 Dataflow 搭配使用。
除了密钥操作费用(会计入您的 Google Cloud 项目)以外,这种集成不会产生额外的费用。每当 Dataflow 服务账号使用您的 Cloud KMS 密钥时,相应的操作均按 Cloud KMS 密钥操作的费率计费。
如需了解详情,请参阅 Cloud KMS 价格详细信息。
问题排查
请按照本部分中的建议来排查错误。
无法验证 Cloud KMS
您的工作流可能会失败,并显示以下错误:
Workflow failed. Causes: Cloud KMS key <key-name> cannot be validated.
如需解决此问题,请验证您是否传递了完整的密钥路径。该路径类似于 projects/<project-id>/locations/<gcp-region>/keyRings/<key-ring-name>/cryptoKeys/<key-name>
。查找密钥路径中可能存在的拼写错误。
Cloud KMS 密钥权限被拒绝
您的工作流可能会失败,并显示以下错误:
Workflow failed. Causes: Cloud KMS key Permission 'cloudkms.cryptoKeyVersions.useToEncrypt' denied on resource
'projects/<project-id>/locations/<gcp-region>/keyRings/<key-ring-name>/cryptoKeys/<key-name>' (or it may not exist). cannot be validated.
如需解决此问题,请验证密钥路径中出现的项目 ID 正确无误。此外,请确保您拥有使用该密钥的权限。
Cloud KMS 密钥位置与 Dataflow 作业位置不匹配
您的工作流可能会失败,并显示以下错误:
Workflow failed. Causes: Cloud KMS key projects/<project-id>/locations/<gcp-region>/keyRings/<key-ring-name>/cryptoKeys/<key-name>
can't protect resources for this job. Make sure the region of the KMS key matches the Dataflow region.
如需解决此问题,请验证 Cloud KMS 密钥与 Dataflow 作业是否位于同一区域(如果您使用的是区域级密钥)。