使用 Cloud Build 专用池访问专用 Google Kubernetes Engine 集群


本教程介绍如何使用 Cloud Build 专用池访问专用 Google Kubernetes Engine (GKE) 集群。此访问权限可让您使用 Cloud Build 在专用 GKE 集群上部署应用。本教程面向网络管理员,适用于 Cloud Build 专用池需要与在对等互连的虚拟私有云 (VPC) 网络中运行的服务进行通信的所有情况。例如,专用池工作器可以与以下服务通信:

  • 专用 GKE 集群
  • Cloud SQL 数据库
  • Memorystore 实例
  • 在与 Cloud Build 专用池对等互连的 VPC 网络不同的 VPC 网络中运行的 Compute Engine 实例

Cloud Build 专用池和 GKE 集群控制层面均在 Google 拥有的 VPC 网络中运行。这些 VPC 网络与 Google Cloud 上您自己的 VPC 网络对等互连。但是,VPC 网络对等互连不支持传递性对等互连,这会使得在使用 Cloud Build 专用池时存在限制。本教程介绍的解决方案使用 Cloud VPN 以允许 Cloud Build 专用池中的工作器访问专用 GKE 集群的控制层面。

本教程假定您熟悉 Google Kubernetes Engine、Cloud Build、gcloud 命令、VPC 网络对等互连和 Cloud VPN。

架构概览

当您创建没有公共端点的客户端访问权限的专用 GKE 集群时,客户端只能使用其专用 IP 地址访问GKE 集群控制层面。仅当 kubectl 等客户端在有权访问 VPC 网络且位于已获授权的网络中的实例上运行时,这些客户端才能与控制层面通信。

如果要使用 Cloud Build 在此专用 GKE 集群上部署应用,则需要使用 Cloud Build 专用池来访问 GKE 集群。专用池是在 Google 拥有的 Google Cloud 项目中运行的一组工作器实例,这些实例使用 VPC 网络对等互连连接与您的 VPC 网络对等互连。在此设置中,允许工作器实例与 GKE 集群控制层面的专用 IP 地址通信。

但是,GKE 集群控制层面也在 Google 拥有的项目中运行,并使用对等互连连接与您的 VPC 网络对等互连。VPC 网络对等互连不支持传递性对等互连,因此无法在 Cloud Build 专用池和 GKE 集群控制层面之间直接路由数据包。

为了使 Cloud Build 工作器实例能够访问 GKE 集群控制层面,您可以将专用池和 GKE 集群控制层面与您拥有的两个 VPC 网络对等互连,然后使用 Cloud VPN 连接这两个 VPC 网络。此对等互连和连接允许 VPC 隧道的每一端通告专用池和 GKE 集群控制层面网络,从而完成路由。

以下架构图展示了在本教程中使用的资源:

完成 Cloud Build 专用池和 GKE 集群控制层面之间的路由的 VPN 隧道。

我们建议在同一 Google Cloud 区域中创建本教程中使用的所有资源,以缩短延迟时间。如果您自己的实现需要此区域间通信,VPN 隧道可以遍历两个不同的区域。您拥有的两个 VPC 网络也可以属于不同的项目。

目标

  • 创建专用 GKE 集群
  • 设置 Cloud Build 专用池。
  • 在两个 VPC 网络之间创建一个高可用性 VPN 连接。
  • 启用跨两个 VPC 网络对等互连和 VPC 连接的数据包路由。

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用

完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理

准备工作

  1. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  2. 确保您的 Google Cloud 项目已启用结算功能

  3. 启用 Cloud Build, Google Kubernetes Engine, and Service Networking API。

    启用 API

  4. 在 Google Cloud 控制台中,激活 Cloud Shell。

    激活 Cloud Shell

    Cloud Shell 会话随即会在 Google Cloud 控制台的底部启动,并显示命令行提示符。Cloud Shell 是一个已安装 Google Cloud CLI 且已为当前项目设置值的 Shell 环境。该会话可能需要几秒钟时间来完成初始化。

在您自己的项目中创建两个 VPC 网络

在本部分中,您将为 GKE 集群节点创建两个 VPC 网络和一个子网。

  1. 在 Cloud Shell 中,创建第一个 VPC 网络(在上图中称为“专用池对等互连 VPC 网络”)。您无需在此网络中创建子网。

    gcloud compute networks create PRIVATE_POOL_PEERING_VPC_NAME \
        --subnet-mode=CUSTOM
    

    PRIVATE_POOL_PEERING_VPC_NAME 替换为要与 Cloud Build 专用池网络建立对等互连的 VPC 网络的名称。

  2. 创建第二个 VPC 网络(在上图中称为“GKE 对等互连 VPC 网络”):

    gcloud compute networks create GKE_PEERING_VPC_NAME \
        --subnet-mode=CUSTOM
    

    GKE_PEERING_VPC_NAME 替换为要与 GKE 集群控制层面建立对等互连的 VPC 网络的名称。

  3. 为 GKE 集群节点创建子网:

    gcloud compute networks subnets create GKE_SUBNET_NAME \
        --network=GKE_PEERING_VPC_NAME \
        --range=GKE_SUBNET_RANGE \
        --region=REGION
    

    替换以下内容:

    • GKE_SUBNET_NAME:预期用于托管 GKE 集群节点的子网的名称。
    • GKE_PEERING_VPC_NAME:要与 GKE 集群控制平面建立对等互连的 VPC 网络的名称。
    • GKE_SUBNET_RANGEGKE_SUBNET_NAME 的 IP 地址范围。在本教程中,您可以使用 10.244.252.0/22
    • REGION:托管 GKE 集群的 Google Cloud 区域。在本教程中,您可以使用 us-central1

现在,您已经在自己的项目中设置了两个 VPC 网络,并已准备好与其他服务建立对等互连。

创建专用 GKE 集群

在本部分中,您将创建专用 GKE 集群。

  1. 在 Cloud Shell 中,创建一个对控制层面公共端点没有客户端访问权限的 GKE 集群。

    gcloud container clusters create PRIVATE_CLUSTER_NAME \
        --region=REGION \
        --enable-master-authorized-networks \
        --network=GKE_PEERING_VPC_NAME \
        --subnetwork=GKE_SUBNET_NAME \
        --enable-private-nodes \
        --enable-private-endpoint \
        --enable-ip-alias \
        --master-ipv4-cidr=CLUSTER_CONTROL_PLANE_CIDR
    

    替换以下内容:

    • PRIVATE_CLUSTER_NAME:专用 GKE 集群的名称。
    • REGION:GKE 集群的区域。在本教程中,使用 us-central1 作为区域,该区域与您用于 VPC 网络的区域相同。
    • GKE_PEERING_VPC_NAME:要与 GKE 集群控制平面建立对等互连的 VPC 网络的名称。
    • GKE_SUBNET_RANGEGKE_SUBNET_NAME 的 IP 地址范围。在本教程中,您可以使用 10.244.252.0/22
    • CLUSTER_CONTROL_PLANE_CIDR:GKE 集群控制层面的 IP 地址范围。它必须具有 /28 前缀。在本教程中,请使用 172.16.0.32/28

    现在,您已经创建了一个专用 GKE 集群,并且该集群与您自己的项目中的 VPC 网络对等互连。

  2. 检索 GKE 集群的 VPC 网络对等互连的名称。此 VPC 网络对等互连是在创建 GKE 集群时自动创建的。

    export GKE_PEERING_NAME=$(gcloud container clusters describe PRIVATE_CLUSTER_NAME \
        --region=REGION \
        --format='value(privateClusterConfig.peeringName)')
    

    替换以下内容:

    • PRIVATE_CLUSTER_NAME:专用 GKE 集群的名称。
    • REGION:GKE 集群的区域。在本教程中,使用 us-central1 作为区域,该区域与您用于 VPC 网络的区域相同。
  3. 启用导出自定义路由,以向 GKE 集群控制层面通告专用池网络:

    gcloud compute networks peerings update $GKE_PEERING_NAME \
        --network=GKE_PEERING_VPC_NAME \
        --export-custom-routes \
        --no-export-subnet-routes-with-public-ip
    

    GKE_PEERING_VPC_NAME 替换为 VPC 网络的名称,以便与 GKE 集群控制平面建立对等互连。

    如需详细了解自定义路由,请参阅导入和导出自定义路由

创建 Cloud Build 专用池

在本部分中,您将创建 Cloud Build 专用池。

  1. 在 Cloud Shell 中,在 PRIVATE_POOL_PEERING_VPC_NAME VPC 网络中为 Cloud Build 专用池分配指定的 IP 地址范围:

    gcloud compute addresses create RESERVED_RANGE_NAME \
        --global \
        --purpose=VPC_PEERING \
        --addresses=PRIVATE_POOL_NETWORK \
        --prefix-length=PRIVATE_POOL_PREFIX \
        --network=PRIVATE_POOL_PEERING_VPC_NAME
    

    替换以下内容:

    • RESERVED_RANGE_NAME:托管 Cloud Build 专用池的专用 IP 地址范围的名称。
    • PRIVATE_POOL_NETWORKRESERVED_RANGE_NAME 的第一个 IP 地址。在本教程中,您可以使用 192.168.0.0
    • PRIVATE_POOL_PREFIXRESERVED_RANGE_NAME 的前缀。创建的每个专用池都将使用此范围内的 /24。在本教程中,您可以使用 20;这样一来,您最多可以创建 16 个池。
    • PRIVATE_POOL_PEERING_VPC_NAME:要与 Cloud Build 专用池网络建立对等互连的 VPC 网络的名称。
    • IP 地址范围是 global,因为当 --purposeVPC_PEERING 时,指定的 IP 地址范围必须是 global
  2. 在 Cloud Build 专用池所在的 VPC 网络与 PRIVATE_POOL_PEERING_VPC_NAME 之间创建专用连接:

    gcloud services vpc-peerings connect \
        --service=servicenetworking.googleapis.com \
        --ranges=RESERVED_RANGE_NAME \
        --network=PRIVATE_POOL_PEERING_VPC_NAME
    

    替换以下内容:

    • RESERVED_RANGE_NAME:托管 Cloud Build 专用池的专用 IP 地址范围的名称。
    • PRIVATE_POOL_PEERING_VPC_NAME:要与 Cloud Build 专用池网络建立对等互连的 VPC 网络的名称。
  3. 启用自定义路由导出,以将 GKE 集群控制层面网络通告到专用池:

    gcloud compute networks peerings update servicenetworking-googleapis-com \
        --network=PRIVATE_POOL_PEERING_VPC_NAME \
        --export-custom-routes \
        --no-export-subnet-routes-with-public-ip
    

    PRIVATE_POOL_PEERING_VPC_NAME 替换为要与 Cloud Build 专用池网络建立对等互连的 VPC 网络的名称。

  4. 创建与 PRIVATE_POOL_PEERING_VPC_NAME 对等互连的 Cloud Build 专用池:

    gcloud builds worker-pools create PRIVATE_POOL_NAME \
       --region=REGION \
       --peered-network=projects/$GOOGLE_CLOUD_PROJECT/global/networks/PRIVATE_POOL_PEERING_VPC_NAME
    

    替换以下内容:

    • PRIVATE_POOL_NAME:Cloud Build 专用池的名称。
    • REGION:GKE 集群的区域。在本教程中,使用 us-central1 作为区域,该区域与您用于 VPC 网络的区域相同。

现在,您已经创建了一个 Cloud Build 专用池,并将它与您自己的项目中的 VPC 网络对等互连。

在两个 VPC 网络之间创建 Cloud VPN 连接

在您自己的项目中,您现在具有一个与 Cloud Build 专用池对等互连的 VPC 网络,以及另一个与专用 GKE 集群对等互连的 VPC 网络。

在本部分中,您将在项目中的两个 VPC 网络之间创建 Cloud VPN 连接。此连接完成路由并允许 Cloud Build 专用池访问 GKE 集群。

  1. 在 Cloud Shell 中,创建两个相互连接的高可用性 VPN 网关。如需创建这些网关,请按照创建两个相互连接的完全配置的高可用性 VPN 网关中的说明操作。在您创建 BGP 会话后,设置就完成了。按照这些说明执行操作时,请使用以下值:

    • PRIVATE_POOL_PEERING_VPC_NAME 用于 NETWORK_1
    • GKE_PEERING_VPC_NAME 用于 NETWORK_2
    • REGION 用于 REGION_1REGION_2
  2. 配置您创建的四个 BGP 会话中的每个会话,以向专用池 VPC 网络和 GKE 集群控制层面 VPC 网络通告路由:

    gcloud compute routers update-bgp-peer ROUTER_NAME_1 \
        --peer-name=PEER_NAME_GW1_IF0 \
        --region=REGION \
        --advertisement-mode=CUSTOM \
        --set-advertisement-ranges=PRIVATE_POOL_NETWORK/PRIVATE_POOL_PREFIX
    
    gcloud compute routers update-bgp-peer ROUTER_NAME_1 \
        --peer-name=PEER_NAME_GW1_IF1 \
        --region=REGION \
        --advertisement-mode=CUSTOM \
        --set-advertisement-ranges=PRIVATE_POOL_NETWORK/PRIVATE_POOL_PREFIX
    
    gcloud compute routers update-bgp-peer ROUTER_NAME_2 \
        --peer-name=PEER_NAME_GW2_IF0 \
        --region=REGION \
        --advertisement-mode=CUSTOM \
        --set-advertisement-ranges=CLUSTER_CONTROL_PLANE_CIDR
    
    gcloud compute routers update-bgp-peer ROUTER_NAME_2 \
        --peer-name=PEER_NAME_GW2_IF1 \
        --region=REGION \
        --advertisement-mode=CUSTOM \
        --set-advertisement-ranges=CLUSTER_CONTROL_PLANE_CIDR
    

    其中,以下值与您在创建两个高可用性 VPN 网关时使用的名称相同:

    • ROUTER_NAME_1
    • PEER_NAME_GW1_IF0
    • PEER_NAME_GW1_IF1
    • ROUTER_NAME_2
    • PEER_NAME_GW2_IF0
    • PEER_NAME_GW2_IF1

启用 Cloud Build 对 GKE 集群控制层面的访问权限

现在,您在项目中两个 VPC 网络之间建立了 VPN 连接,接下来请启用 Cloud Build 对 GKE 集群控制层面的访问权限。

  1. 在 Cloud Shell 中,将专用池网络范围添加到 GKE 中的控制层面授权网络:

    gcloud container clusters update PRIVATE_CLUSTER_NAME \
        --enable-master-authorized-networks \
        --region=REGION \
        --master-authorized-networks=PRIVATE_POOL_NETWORK/PRIVATE_POOL_PREFIX
    

    替换以下内容:

    • PRIVATE_CLUSTER_NAME:专用 GKE 集群的名称。
    • REGION:GKE 集群的区域。在本教程中,使用 us-central1 作为区域,该区域与您用于 VPC 网络的区域相同。
    • PRIVATE_POOL_NETWORKRESERVED_RANGE_NAME 的第一个 IP 地址。在本教程中,您可以使用 192.168.0.0
    • PRIVATE_POOL_PREFIXRESERVED_RANGE_NAME 的前缀。创建的每个专用池都将使用此范围内的 /24。在本教程中,您可以使用 20;这样一来,您最多可以创建 16 个池。
  2. 允许 Cloud Build 服务账号访问 GKE 集群控制层面:

    export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format 'value(projectNumber)')
    
    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
        --member=serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com \
        --role=roles/container.developer
    

Cloud Build 专用池现在可以访问 GKE 集群控制层面。

验证解决方案

在本部分中,您将通过在专用池中运行的构建步骤中运行 kubectl get nodes 命令来验证解决方案是否正常工作。

  1. 在 Cloud Shell 中,创建一个临时文件夹,其中包含运行 kubectl get nodes 命令的 Cloud Build 配置文件:

    mkdir private-pool-test && cd private-pool-test
    
    cat > cloudbuild.yaml <<EOF
    steps:
    - name: "gcr.io/cloud-builders/kubectl"
      args: ['get', 'nodes']
      env:
      - 'CLOUDSDK_COMPUTE_REGION=REGION'
      - 'CLOUDSDK_CONTAINER_CLUSTER=PRIVATE_CLUSTER_NAME'
    options:
      workerPool:
        'projects/$GOOGLE_CLOUD_PROJECT/locations/REGION/workerPools/PRIVATE_POOL_NAME'
    EOF
    

    替换以下内容:

    • REGION:GKE 集群的区域。在本教程中,使用 us-central1 作为区域,该区域与您用于 VPC 网络的区域相同。
    • PRIVATE_CLUSTER_NAME:专用 GKE 集群的名称。
    • PRIVATE_POOL_NAME:Cloud Build 专用池的名称。
  2. 启动构建作业:

    gcloud builds submit --config=cloudbuild.yaml
    
  3. 验证输出是否为 GKE 集群中的节点列表。控制台中显示的构建日志包含类似于以下内容的表格:

    NAME                                     STATUS   ROLES    AGE   VERSION
    gke-private-default-pool-3ec34262-7lq9   Ready    <none>   9d    v1.19.9-gke.1900
    gke-private-default-pool-4c517758-zfqt   Ready    <none>   9d    v1.19.9-gke.1900
    gke-private-default-pool-d1a885ae-4s9c   Ready    <none>   9d    v1.19.9-gke.1900
    

现在,您已经验证了专用池中的工作器可以访问 GKE 集群。此访问权限允许您使用 Cloud Build 在此专用 GKE 集群上部署应用。

问题排查

如果您在使用本教程时遇到问题,请参阅以下文档:

清理

为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

删除项目

  1. 在 Google Cloud 控制台中,进入管理资源页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

逐个删除资源

  1. 在 Cloud Shell 中,删除 GKE 集群:

    gcloud container clusters delete PRIVATE_CLUSTER_NAME \
        --region=REGION \
        --async
    

    运行此命令时,VPC 网络对等互连会自动删除。

  2. 删除 Cloud Build 专用池:

    gcloud builds worker-pools delete PRIVATE_POOL_NAME \
        --region=REGION
    
  3. 删除服务提供方 VPC 网络与 PRIVATE_POOL_PEERING_VPC_NAME 之间的专用连接:

    gcloud services vpc-peerings delete \
       --network=PRIVATE_POOL_PEERING_VPC_NAME \
       --async
    
  4. 删除用于专用池的指定 IP 地址范围:

    gcloud compute addresses delete RESERVED_RANGE_NAME \
        --global
    
  5. 删除四个 VPN 隧道。使用您在创建 VPN 隧道中指定的相同名称。

    gcloud compute vpn-tunnels delete \
        TUNNEL_NAME_GW1_IF0 \
        TUNNEL_NAME_GW1_IF1 \
        TUNNEL_NAME_GW2_IF0 \
        TUNNEL_NAME_GW2_IF1 \
        --region=REGION
    
  6. 删除两个 Cloud Router 路由器。使用您在创建 Cloud Router 路由器中指定的相同名称。

    gcloud compute routers delete \
        ROUTER_NAME_1 \
        ROUTER_NAME_2 \
        --region=REGION
    
  7. 删除两个 VPN 网关。使用您在创建高可用性 VPN 网关中指定的相同名称。

    gcloud compute vpn-gateways delete \
        GW_NAME_1 \
        GW_NAME_2 \
        --region=REGION
    
  8. 删除 GKE_SUBNET_NAME(即托管 GKE 集群节点的子网):

    gcloud compute networks subnets delete GKE_SUBNET_NAME \
        --region=REGION
    
  9. 删除 PRIVATE_POOL_PEERING_VPC_NAMEGKE_PEERING_VPC_NAME 这两个 VPC 网络:

    gcloud compute networks delete \
        PRIVATE_POOL_PEERING_VPC_NAME \
        GKE_PEERING_VPC_NAME
    

后续步骤