为 GKE 专用集群配置受限的访问权限

本文档介绍了在 VPC Service Controls 服务边界中使用 Google Kubernetes Engine 专用集群时,如何配置 DNS 条目以使用受限虚拟 IP (VIP) 将请求路由到 pkg.devgcr.io 网域。

这些注册表域通常解析为 。在 GKE 专用集群中,节点默认与互联网隔离。这意味着, 尚未配置到受限 VIP 的 DNS 路由。

您的专用集群应始终访问 Artifact Registry 或 Container Registry 与受限 VIP 搭配使用,以防止受支持的服务发生数据渗漏 一个不受支持的对象。

只有在满足以下条件时,才需要执行这些步骤:

  • 您正在使用 GKE 专用集群。
  • 您尚未配置将 pkg.devgcr.io 注册网域路由到 restricted.googleapis.com

准备工作

在创建服务边界之前,请设置新的专用集群或标识要保护的现有专用集群。

此外,您必须允许通过端口 443 向 199.36.153.4/30 发送出站流量。通常,VPC 网络具有一条隐式规则允许将所有出站流量发送到任何目标。但是,如果您有拒绝此类流量的规则,则必须创建出站防火墙规则,以允许端口 443 上的 TCP 流量发送到 199.36.153.4/30。

配置 DNS

配置您的 DNS 服务器,以便将发送到注册表地址的请求解析为 restricted.googleapis.com(即受限 VIP)。您可以使用 Cloud DNS 专用 DNS 区域执行此操作。

  1. 创建专用代管区域。

    gcloud dns managed-zones create ZONE_NAME \
        --visibility=private \
        --networks=https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/networks/NETWORK \
        --description=DESCRIPTION \
        --dns-name=REGISTRY_DOMAIN \
        --project=PROJECT_ID
    

    其中:

    • ZONE_NAME 是您要创建的区域的名称。例如 registry。下列各个步骤中将使用此名称。

    • PROJECT_ID 是托管 GKE 专用集群的项目的 ID。

    • NETWORK 是您要从中重定向请求的集群网络名称的可选列表。

    • DESCRIPTION 是代管式可用区的直观易懂的说明。

    • REGISTRY_DOMAIN 是注册表的网域:

      • pkg.dev(对于 Artifact Registry)
      • gcr.io(对于 Container Registry)或 托管在 Artifact Registry 中的 gcr.io 代码库
  2. 启动一项事务。

    gcloud dns record-sets transaction start \
      --zone=ZONE_NAME \
      --project=PROJECT_ID
    

    其中:

    • ZONE_NAME 是您在第一步中创建的区域的名称。

    • PROJECT_ID 是托管 GKE 专用集群的项目的 ID。

  3. 为注册表添加 CNAME 记录。

    gcloud dns record-sets transaction add \
      --name=*.REGISTRY_DOMAIN. \
      --type=CNAME REGISTRY_DOMAIN. \
      --zone=ZONE_NAME \
      --ttl=300 \
      --project=PROJECT_ID
    

    其中:

    • ZONE_NAME 是您在第一步中创建的区域的名称。

    • PROJECT_ID 是托管 GKE 专用集群的项目的 ID。

    • REGISTRY_DOMAIN 是注册表的网域:

      • pkg.dev(对于 Artifact Registry)
      • gcr.io(对于 Container Registry)或 托管在 Artifact Registry 中的 gcr.io 代码库
  4. 为受限 VIP 提供 A 记录。

    gcloud dns record-sets transaction add \
      --name=REGISTRY_DOMAIN. \
      --type=A 199.36.153.4 199.36.153.5 199.36.153.6 199.36.153.7 \
      --zone=ZONE_NAME \
      --ttl=300 \
      --project=PROJECT_ID
    

    其中:

    • ZONE_NAME 是您在第一步中创建的区域的名称。

    • PROJECT_ID 是托管 GKE 专用集群的项目的 ID。

    • REGISTRY_DOMAIN 是注册表的网域:

      • pkg.dev(对于 Artifact Registry)
      • gcr.io(适用于 Container Registry 或在 Artifact Registry 中托管的 gcr.io 代码库
  5. 执行事务。

    gcloud dns record-sets transaction execute \
      --zone=ZONE_NAME \
      --project=PROJECT_ID
    

    其中:

    • ZONE_NAME 是您在第一步中创建的区域的名称。

    • PROJECT_ID 是托管 GKE 专用集群的项目的 ID。

配置 DNS 路由后,请确保您的 GKE、注册库和其他所需服务位于 VPC Service Controls 服务边界内。如需配置服务边界,请参阅以下内容 部分。

配置服务边界

配置 DNS 记录后, 创建新的服务边界更新现有边界, 然后将 Container Registry 或 Artifact Registry 服务添加到 监控您想要使用的服务边界保护的服务。

此外:

  • 添加其他支持的服务 迁移到服务边界,例如 Cloud Build Artifact Analysis 和 Binary Authorization。
  • 对于 Container Registry,您还必须将 Cloud Storage 添加到服务边界。

验证边界是否有效

配置服务边界后,GKE 专用集群中的节点可以访问 Artifact Registry 和 Container Registry 中的容器映像,前提是这些映像存储在服务边界内的项目中。

边界外项目中的容器映像仍然无法访问,但某些特定的只读公共代码库除外。

例如,如果 google-samples 项目不在您的服务边界中,运行用于从 hello-app 容器创建部署的命令将会失败:

pkg.dev 域名

kubectl create deployment hello-server --image=us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0

gcr.io 网域

kubectl create deployment hello-server --image=gcr.io/google-samples/hello-app:1.0

使用以下命令检查 pod 的状态:

kubectl get pods

该命令会返回如下例所示的表。Pod 状态 ErrImagePull 表示拉取失败。

NAME                            READY   STATUS         RESTARTS   AGE
hello-server-dbd86c8c4-h5wsf    1/1     ErrImagePull   0          45s

您可以使用 kubectl describe pod 命令查看有关部署的更多详细信息。对于上例中的 pod,命令如下:

kubectl describe pod hello-server-dbd86c8c4-h5wsf