使用客户管理的加密密钥

本主题介绍了如何使用 Cloud KMS 客户管理的加密密钥 (CMEK) 保护部署到 Cloud Run 服务的容器映像。您可以使用此功能通过静态 CMEK 密钥保护 Cloud Run 导入的容器。

请注意以下几点:

  • 文件元数据(例如文件路径)未加密。
  • Cloud Run 服务的元数据(例如名称或环境变量)不使用提供的密钥进行加密,而是使用 Google 拥有且 Google 管理的密钥进行加密。
  • 在运行时,不会加密内存和文件内容。
  • 如果 CMEK 密钥被停用,则使用该密钥的现有 Cloud Run 修订版本的新实例将无法启动。
  • 如果 CMEK 密钥被停用,则部署新的 Cloud Run 修订版本将失败,除非使用新的有效密钥。

由于 CMEK 密钥在您的控制之下,不受 Google 控制,因此在密钥停用或销毁时,任何密钥(包括 Google)都无法访问受这些加密密钥保护的数据。

使用 CMEK 会生成审核日志。如需了解详情,请参阅了解审核日志和错误消息

Cloud KMS 配额和 Cloud Run

您可以将 CMEK 设置为某个可用的保护级别,以指明加密操作的执行方式。在 Cloud Run 中使用 CMEK 时,您的项目可能会消耗 Cloud KMS 加密请求配额。例如,由 CMEK 加密的制品库可为每次上传或下载消耗这些配额。

使用 CMEK 密钥执行的加密和解密操作通过以下方式影响 Cloud KMS 配额:

  • 对于在 Cloud KMS 中生成的软件 CMEK 密钥,不会消耗 Cloud KMS 配额。
  • 对于硬件 CMEK 密钥(有时称为 Cloud HSM 密钥),加密和解密操作会计入包含密钥的项目中的 Cloud HSM 配额
  • 对于外部 CMEK 密钥(有时称为 Cloud EKM 密钥),加密和解密操作会计入包含该密钥的项目中的 Cloud EKM 配额

如需了解详情,请参阅 Cloud KMS 配额

受 CMEK 影响的自动扩缩行为

使用客户管理的加密密钥时,您的 Cloud Run 服务的预期自动扩缩可能会受到影响。例如,由于在密钥操作期间联系外部密钥管理系统的延迟,启动新实例的延迟可能会增加。

下表显示了使用 CMEK 密钥时的行为可能的变化:

与 CMEK 相关的操作 自动扩缩行为
密钥已停用/销毁/撤消 新实例不会启动。
无法联系外部密钥管理器 如果可以重试密钥请求,则在重试期间不会关停任何实例,并且不会启动任何新实例。横向扩容的显示速度可能低于预期。
如果密钥请求无法重试,则不会启动任何新实例,并且正在运行的实例会在等待一段时间后关停。
已超出 KMS 配额 如果超出此配额,则系统会记录 RESOURCE_EXHAUSTED 错误,并且新实例将无法启动。您可以申请更多配额来解决此问题。

准备工作

允许 Cloud Run 访问密钥

如需将 CMEK 用于 Cloud Run,请执行以下步骤:

  1. 配置 Artifact Registry 以使用 CMEK

  2. 使用 Artifact Registry Docker 快速入门作为参考,创建 Docker 代码库以将映像推送到其中。

  3. 使用现有的 Cloud KMS 对称密钥创建新的对称密钥

  4. 如需允许 Cloud Run 访问密钥,请向 Cloud Run 服务代理授予 Cloud KMS CryptoKey Encrypter/Decrypter 角色:

    控制台

    1. 转到“加密密钥”页面

    2. 点击密钥对应的密钥环,以打开其密钥列表页面。

    3. 选择密钥,然后在右侧的“权限”标签页中,点击添加主账号

    4. 新的主账号字段中,复制 Cloud Run 服务代理电子邮件。它具有以下后缀:

      PROJECT_NUMBER@serverless-robot-prod.iam.gserviceaccount.com.

    5. 选择角色字段中,选择 Cloud KMS CryptoKey Encrypter/Decrypter

    6. 点击保存

    gcloud

    使用以下 gcloud kms 命令:

    gcloud kms keys add-iam-policy-binding KEY_NAME \
    --keyring=KEYRING \
    --location=LOCATION) \
    --member serviceAccount:PROJECT_NUMBER@serverless-robot-prod.iam.gserviceaccount.com \
    --role='roles/cloudkms.cryptoKeyEncrypterDecrypter'

    替换

    • KEY_NAME 替换为您的密钥名称。
    • KEYRING 替换为您的密钥环名称。
    • LOCATION 替换为您的区域名称。
    • PROJECT_NUMBER 替换为您要在其中部署 Cloud Run 服务的项目编号。

    您需要具备管理 Google Cloud 项目中 Cloud KMS 资源的权限,才能授予 IAM 角色 roles/cloudkms.cryptoKeyEncrypterDecrypter。只有具有 Owner (roles/owner) 或 Cloud KMS Admin (roles/cloudkms.admin) 角色的 IAM 成员才能授予或撤消对 Cloud KMS 资源的访问权限。

为 Cloud Run 服务配置 CMEK

任何配置更改都会导致新修订版本的创建。后续修订版本也将自动采用此配置设置,除非您进行了明确更新。

控制台

  1. 在 Google Cloud 控制台中,前往 Cloud Run:

    转到 Cloud Run

  2. 点击部署容器,然后选择服务以配置新服务。如果您要配置现有服务,请点击该服务,然后点击修改和部署新的修订版本

  3. 如果您要配置新服务,请根据需要填写初始服务设置页面,然后点击容器、网络、安全性以展开服务配置页面。

  4. 点击安全性标签。

    图片

    • 加密下:
      1. 选择客户管理的加密密钥 (CMEK)
      2. 选择客户管理的密钥菜单中,选择以下选项之一:
        • 如果您需要使用来自其他项目的密钥,请选择切换项目。如果项目的服务账号可以访问用于加密和解密操作的密钥,则可以引用来自其他项目的密钥。

        • 选择手动输入密钥,按照以下格式输入来自某个项目的密钥:projects/PROJECT_NAME/locations/LOCATION/keyRings/KEYRING_NAME/cryptoKeys/KEY_NAME

        如需从您有权访问的其他项目复制和粘贴资源名称,请执行以下操作:

        • 转到“加密密钥”页面
        • 点击密钥环
        • 选择所选密钥环名称,然后点击操作
        • 从菜单中选择复制资源名称,并将其粘贴到上一步的密钥资源名称字段中。

      3. 密钥撤销操作菜单中,选择以下选项之一:
        • 阻止新容器实例:CMEK 密钥撤消后,任何新实例都不会启动。

        • 尽快关闭:CMEK 密钥撤消后,任何新实例都不会启动,并且现有实例会关闭。

        • 自定义关闭延迟时间:指定服务关闭前的小时数。

  5. 点击创建部署

gcloud

如需在服务上设置密钥,请使用以下任一命令:

gcloud run deploy SERVICE \
--image IMAGE_URL \
--key KEY \
--post-key-revocation-action-type KEY_REVOCATION_ACTION
--encryption-key-shutdown-hours SHUTDOWN_HOURS
gcloud run services update SERVICE --key KEY
--post-key-revocation-action-type KEY_REVOCATION_ACTION
--encryption-key-shutdown-hours SHUTDOWN_HOURS

替换

  • SERVICE 替换为您的服务名称。
  • IMAGE_URL 替换为对容器映像的引用,例如 us-docker.pkg.dev/cloudrun/container/hello:latest。 如果您使用 Artifact Registry,则必须预先创建制品库 REPO_NAME。网址格式为 LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG
  • KEY 替换为完全限定的密钥名称,格式如下:projects/PROJECT_NAME/locations/LOCATION/keyRings/KEYRING_NAME/cryptoKeys/KEY_NAME
  • KEY_REVOCATION_ACTION 替换为 shut-downprevent-new,具体取决于您的密钥撤消偏好设置
  • SHUTDOWN_HOURS 替换为撤消后,服务关闭前的小时数。

YAML

  1. 如果您要创建新的服务,请跳过此步骤。如果您要更新现有服务,请下载其 YAML 配置

    gcloud run services describe SERVICE --format export > service.yaml
  2. 将以下 CMEK 注释更新为所需值:

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: SERVICE
    spec:
      template:
        metadata:
          annotations:
            run.googleapis.com/encryption-key: projects/PROJECT_NAME/locations/LOCATION/keyRings/KEYRING_NAME/cryptoKeys/KEY_NAME
            run.googleapis.com/post-key-revocation-action-type: KEY_REVOCATION_ACTION
            run.googleapis.com/encryption-key-shutdown-hours: SHUTDOWN_HOURS
          name: REVISION

    替换

    • SERVICE 替换为您的 Cloud Run 服务的名称。
    • PROJECT_NAME 替换为创建密钥时所用的项目的名称。
    • LOCATION 替换为密钥的创建位置。必须与 Cloud Run 服务位置一致。
    • KEYRING_NAME 替换为密钥环的名称。
    • KEY_NAME 替换为密钥的名称。
    • KEY_REVOCATION_ACTION 替换为 shut-downprevent-new,具体取决于您的密钥撤消偏好设置
    • SHUTDOWN_HOURS 替换为撤消后,服务关闭前的小时数。
    • REVISION 替换为新的修订版本名称或者将其删除(如果存在)。如果您提供新的修订版本名称,则该名称必须满足以下条件:
      • 开头为 SERVICE-
      • 仅包含小写字母、数字和 -
      • 不以 - 结尾
      • 不超过 63 个字符
  3. 使用以下命令将服务替换为其新配置:

    gcloud run services replace service.yaml

查看安全设置

如需查看 Cloud Run 服务的当前安全设置,请执行以下操作:

控制台

  1. 在 Google Cloud 控制台中,前往 Cloud Run:

    转到 Cloud Run

  2. 点击您感兴趣的服务以打开“服务详细信息”页面。

  3. 点击修订版本标签页。

  4. 在右侧的详细信息面板中,“安全性”标签页下列出了安全设置。

gcloud

  1. 使用以下命令:

    gcloud run services describe SERVICE
  2. 在返回的配置中找到安全设置。

测试 CMEK 撤消

  1. 运行以下命令以确认服务可访问:

    curl SERVICE_URL
    

    SERVICE_URL 替换为服务网址。部署后,您可以在控制台界面中找到此信息:容器网址显示在文本网址:旁边。

  2. 停用密钥版本

  3. 等待您指定的 SHUTDOWN_HOURS 数量。如果未指定重新启用密钥,修改或重新部署您的服务,并将该值设置为至少一小时。

  4. 等待您设置的 SHUTDOWN_HOURS 时长后,重新运行以下命令并确认无法再访问服务:

curl SERVICE_URL

了解审核日志和错误消息

如果您负责监控审核日志,则其中一个任务可能是验证 Cloud Run 服务中的 CMEK 操作。在这种情况下,您需要了解相关的审核日志。

如果您负责解决和修复 Cloud Run 服务的运行时错误,则可能需要排查 Cloud Run 服务操作期间记录的 CMEK 相关错误。

以下部分提供了执行上述任务所需的信息。

审核日志

KMS 审核日志会为使用密钥执行的每个操作提供审核跟踪。对于启用了 CMEK 的 Cloud Run 服务,Cloud Run 会添加特定于 Cloud Run 的调用方上下文,其中详细说明了系统访问客户密钥的原因。下表列出了您可能会在审核日志中看到的上下文:

密钥访问的原因 说明
Decrypting CMEK-encrypted layer during container clone start. 每当启动新实例时进行记录。
Encrypting a newly created data-encryption-key w/ the customer-managed-encryption-key. 在部署启用了 CMEK 的服务期间进行记录,其中 CMEK 密钥由 KMS 密钥封装。
Decrypting an existing encrypted data-encryption-key, under the same customer-managed-encryption-key, to be used to encrypt container contents. 在新实例启动时记录,该实例需要解密映像。
Performing an encrypt operation on dummy data to check the customer-managed-encryption-key status and access. 当密钥存在验证检查时进行记录,该检查会定期进行。
Performing a decrypt operation on dummy data to check the customer-managed-encryption-key status and access. 当密钥存在验证检查时进行记录,该检查会定期进行。

如需详细了解审核日志格式和内容,请参阅 KMS 审核日志记录页面。

错误消息

请注意,外部密钥管理器提供的错误消息会直接传递到服务的 Cloud Run 日志

下表列出了您可能会看到的与 CMEK 相关的错误消息,以及说明和可能的补救措施。

消息 说明
User's service account does not have CMEK decrypter permission. Service account: %s 补救:允许服务访问密钥
User's KMS operation quota has been exceeded. CMEK key: %s 启用了 CMEK 的服务已超出 KMS 配额。补救措施:申请更多 KMS 配额
User's CMEK key has been disabled. CMEK key: %s CMEK 密钥已被撤消。补救措施:更改服务的 CMEK 密钥并重新部署服务。
User's CMEK key has been destroyed. CMEK key: %s CMEK 密钥已删除。补救措施:更改服务的 CMEK 密钥并重新部署服务。
User's CMEK key has been scheduled for deletion. CMEK Key: %s CMEK 密钥已安排删除。补救措施:更改服务的 CMEK 密钥并重新部署服务。

后续步骤