设置使用共享 VPC 的集群


本指南介绍如何在单独的项目中创建两个使用共享 VPC 的 Google Kubernetes Engine (GKE) 集群。如需了解 GKE 网络的一般信息,请参阅网络概览

概览

使用共享 VPC 时,您可以将一个项目指定为宿主项目,并将其他项目(称为服务项目)关联到该宿主项目。您可以在宿主项目中创建网络、子网、次要地址范围、防火墙规则以及其他网络资源。然后,您可以与服务项目共享所选子网,包括次要范围。 在某个服务项目中运行的组件可以使用共享 VPC 与在其他服务项目中运行的组件通信。

您可以将共享 VPC 与 Autopilot 集群以及可用区级区域级 Standard 集群结合使用。

使用共享 VPC 的 Standard 集群不能使用旧式网络,并且必须启用VPC 原生流量路由。Autopilot 集群始终启用 VPC 原生流量路由。

您可以在创建新集群时配置共享 VPC。 GKE 不支持将现有集群转换为共享的 VPC 模型。

使用共享 VPC 时,需遵循某些配额和限制。例如,项目中的网络数量有一个配额,并且可以关联到每个宿主项目的服务项目数量有限制。如需了解详情,请参阅配额和限制

关于示例

本指南中的示例为双层 Web 应用设置基础架构,如共享 VPC 概览中所述。

准备工作

在开始设置使用共享 VPC 的集群之前,请先完成以下准备工作:

在执行本指南中的练习之前,请先执行以下操作:

  • 选择一个项目作为宿主项目。
  • 选择两个项目作为服务项目。

每个项目都有一个名称、一个 ID 和一个编号。在某些情况下,名称和 ID 是相同的。本指南使用以下易记名称和占位符来引用您的项目:

易记名称 项目 ID
占位符
项目编号
占位符
您的宿主项目 HOST_PROJECT_ID HOST_PROJECT_NUM
您的第一个服务项目 SERVICE_PROJECT_1_ID SERVICE_PROJECT_1_NUM
您的第二个服务项目 SERVICE_PROJECT_2_ID SERVICE_PROJECT_2_NUM

查找您的项目 ID 和编号

您可以使用 gcloud CLI 或 Google Cloud 控制台查找项目 ID 和项目编号。

控制台

  1. 进入 Google Cloud 控制台中的首页

    进入首页

  2. 在项目选择器中,选择您的宿主项目。

  3. 项目信息下,您可以看到项目名称、项目 ID 和项目编号。记下 ID 和编号以备后续使用。

  4. 对您选择的每个服务项目执行相同的操作。

gcloud

使用以下命令列出您的项目:

gcloud projects list

输出会显示项目名称、ID 和编号。记下 ID 和编号以备后续使用:

PROJECT_ID        NAME        PROJECT_NUMBER
host-123          host        1027xxxxxxxx
srv-1-456         srv-1       4964xxxxxxxx
srv-2-789         srv-2       4559xxxxxxxx

在项目中启用 GKE API

在继续本指南中的练习之前,请确保在所有三个项目中都启用了 GKE API。在项目中启用 API 会为该项目创建 GKE 服务账号。为了执行本指南中的其余任务,您的所有项目都必须具有一个 GKE 服务账号。

您可以使用 Google Cloud 控制台或 Google Cloud CLI 启用 GKE API。

控制台

  1. 转到 Google Cloud 控制台中的 API 和服务页面。

    转到“API 和服务”

  2. 在项目选择器中,选择您的宿主项目。

  3. 如果 Kubernetes Engine API 位于 API 列表中,表示它已启用,您无需执行任何操作。如果它不在列表中,请点击启用 API 和服务。搜索 Kubernetes Engine API。点击 Kubernetes Engine API 卡片,然后点击启用

  4. 对您选择的每个服务项目重复执行上述步骤。每项操作可能需要一些时间才能完成。

gcloud

为您的三个项目启用 GKE API。每项操作可能需要一些时间才能完成:

gcloud services enable container.googleapis.com --project HOST_PROJECT_ID
gcloud services enable container.googleapis.com --project SERVICE_PROJECT_1_ID
gcloud services enable container.googleapis.com --project SERVICE_PROJECT_2_ID

创建一个网络和两个子网

在本部分中,您将执行以下任务:

  1. 在您的宿主项目中,创建一个名为 shared-net 的网络。
  2. 创建两个名为 tier-1tier-2 的子网。
  3. 对于每个子网,创建两个次要地址范围:一个用于 Service,另一个用于 Pod。

控制台

  1. 转到 Google Cloud 控制台中的 VPC 网络页面。

    转到 VPC 网络

  2. 在项目选择器中,选择您的宿主项目。

  3. 点击 创建 VPC 网络

  4. 对于名称,输入 shared-net

  5. 子网创建模式下,选择自定义

  6. 新子网框的名称部分中,输入 tier-1

  7. 区域部分中,选择一个区域。

  8. IP 栈类型下,选择 IPv4(单栈)

  9. 对于 IPv4 范围,输入 10.0.4.0/22

  10. 点击创建次要 IPv4 地址范围。在子网范围名称部分,输入 tier-1-services;在次要 IPv4 范围部分,输入 10.0.32.0/20

  11. 点击添加 IP 范围。在子网范围名称部分,输入 tier-1-pods;在次要 IPv4 范围部分,输入 10.4.0.0/14

  12. 点击添加子网

  13. 对于名称,输入 tier-2

  14. 区域部分中,选择您为之前的子网选择的同一区域。

  15. 对于 IPv4 范围,输入 172.16.4.0/22

  16. 点击创建次要 IPv4 地址范围。在子网范围名称部分,输入 tier-2-services;在次要 IPv4 范围部分,输入 172.16.16.0/20

  17. 点击添加 IP 范围。在子网范围名称部分,输入 tier-2-pods;在次要 IPv4 范围部分,输入 172.20.0.0/14

  18. 点击创建

gcloud

在您的宿主项目中,创建一个名为 shared-net 的网络:

gcloud compute networks create shared-net \
    --subnet-mode custom \
    --project HOST_PROJECT_ID

在新网络中,创建一个名为 tier-1 的子网:

gcloud compute networks subnets create tier-1 \
    --project HOST_PROJECT_ID \
    --network shared-net \
    --range 10.0.4.0/22 \
    --region COMPUTE_REGION \
    --secondary-range tier-1-services=10.0.32.0/20,tier-1-pods=10.4.0.0/14

创建另一个名为 tier-2 的子网:

gcloud compute networks subnets create tier-2 \
    --project HOST_PROJECT_ID \
    --network shared-net \
    --range 172.16.4.0/22 \
    --region COMPUTE_REGION \
    --secondary-range tier-2-services=172.16.16.0/20,tier-2-pods=172.20.0.0/14

COMPUTE_REGION 替换为 Compute Engine 区域

确定服务项目中服务账号的名称

您有两个服务项目,每个服务项目都有多个服务账号。 本部分涉及您的 GKE 服务账号和您的 Google API 服务账号。 在下一个部分中,您需要用到这些服务账号的名称。

下表列出了两个服务项目中 GKE 和 Google API 服务账号的名称:

服务账号类型 服务账号名称
GKE service-SERVICE_PROJECT_1_NUM@container-engine-robot.iam.gserviceaccount.com
service-SERVICE_PROJECT_2_NUM@container-engine-robot.iam.gserviceaccount.com
Google API SERVICE_PROJECT_1_NUM@cloudservices.gserviceaccount.com
SERVICE_PROJECT_2_NUM@cloudservices.gserviceaccount.com

启用共享 VPC 并授予角色

如需执行本部分中的任务,请确保您的组织已定义 Shared VPC Admin 角色。

在本部分中,您将执行以下任务:

  1. 在您的宿主项目中,启用共享 VPC。
  2. 将两个服务项目关联到宿主项目。
  3. 向属于您的服务项目的服务账号授予适当的 IAM 角色:
    • 在第一个服务项目中,向两个服务账号授予宿主项目的 tier-1 子网的 Compute Network User 角色。
    • 在第二个服务项目中,向两个服务账号授予宿主项目的 tier-2 子网的 Compute Network User 角色。

控制台

执行以下步骤以启用共享 VPC、关联服务项目并授予角色:

  1. 转到 Google Cloud 控制台中的“共享 VPC”页面

    转到共享 VPC

  2. 在项目选择器中,选择您的宿主项目。

  3. 点击设置共享 VPC。此时将显示启用宿主项目屏幕。

  4. 点击保存并继续。此时将显示选择子网页面。

  5. 共享模式下,选择个别子网

  6. 要共享的子网下,选中 tier-1tier-2。清除所有其他复选框。

  7. 点击继续。此时会显示授予权限页面。

  8. 关联服务项目下,选中您的第一个服务项目和第二个服务项目。清除关联服务项目下的所有其他复选框。

  9. Kubernetes Engine 访问权限下,选中已启用

  10. 点击保存。系统随即会显示一个新页面。

  11. 个别子网权限下,选中 tier-1

  12. 在右侧窗格中,删除属于第二个服务项目的任何服务账号。也就是说,删除包含 SERVICE_PROJECT_2_NUM 的任何服务账号。

  13. 在右侧窗格中,查找属于第一个服务项目的 Kubernetes Engine 和 Google API 服务账号的名称。您希望在列表中看到这两个服务账号名称。如果其中任何一个不在列表中,请在添加成员下方输入服务账号名称,然后点击添加

  14. 在中央窗格中的个别子网权限下,选中 tier-2,并取消选中 tier-1

  15. 在右侧窗格中,删除属于第一个服务项目的任何服务账号。也就是说,删除包含 SERVICE_PROJECT_1_NUM 的任何服务账号。

  16. 在右侧窗格中,查找属于第二个服务项目的 Kubernetes Engine 和 Google API 服务账号的名称。您希望在列表中看到这两个服务账号名称。如果其中任何一个不在列表中,请在添加成员下方输入服务账号名称,然后点击添加

gcloud

  1. 在您的宿主项目中启用共享 VPC。您使用的命令取决于您拥有的所需的管理角色

    如您有文件夹级别的 Shared VPC Admin 角色,请运行以下命令:

    gcloud compute shared-vpc enable HOST_PROJECT_ID
    

    如您有文件夹级别的 Shared VPC Admin 角色,请运行以下命令:

    gcloud beta compute shared-vpc enable HOST_PROJECT_ID
    
  2. 将您的第一个服务项目关联到宿主项目:

    gcloud compute shared-vpc associated-projects add SERVICE_PROJECT_1_ID \
        --host-project HOST_PROJECT_ID
    
  3. 将您的第二个服务项目关联到宿主项目:

    gcloud compute shared-vpc associated-projects add SERVICE_PROJECT_2_ID \
        --host-project HOST_PROJECT_ID
    
  4. 获取 tier-1 子网的 IAM 政策:

    gcloud compute networks subnets get-iam-policy tier-1 \
       --project HOST_PROJECT_ID \
       --region COMPUTE_REGION
    

    输出包含 etag 字段。记下 etag 值。

  5. 创建一个名为 tier-1-policy.yaml 且包含以下内容的文件:

    bindings:
    - members:
      - serviceAccount:SERVICE_PROJECT_1_NUM@cloudservices.gserviceaccount.com
      - serviceAccount:service-SERVICE_PROJECT_1_NUM@container-engine-robot.iam.gserviceaccount.com
      role: roles/compute.networkUser
    etag: ETAG_STRING
    

    ETAG_STRING 替换为您之前记下的 etag 值。

  6. 设置 tier-1 子网的 IAM 政策:

    gcloud compute networks subnets set-iam-policy tier-1 \
        tier-1-policy.yaml \
        --project HOST_PROJECT_ID \
        --region COMPUTE_REGION
    
  7. 获取 tier-2 子网的 IAM 政策:

    gcloud compute networks subnets get-iam-policy tier-2 \
        --project HOST_PROJECT_ID \
        --region COMPUTE_REGION
    

    输出包含 etag 字段。记下 etag 值。

  8. 创建一个名为 tier-2-policy.yaml 且包含以下内容的文件:

    bindings:
    - members:
      - serviceAccount:SERVICE_PROJECT_2_NUM@cloudservices.gserviceaccount.com
      - serviceAccount:service-SERVICE_PROJECT_2_NUM@container-engine-robot.iam.gserviceaccount.com
      role: roles/compute.networkUser
    etag: ETAG_STRING
    

    ETAG_STRING 替换为您之前记下的 etag 值。

  9. 设置 tier-2 子网的 IAM 政策:

    gcloud compute networks subnets set-iam-policy tier-2 \
        tier-2-policy.yaml \
        --project HOST_PROJECT_ID \
        --region COMPUTE_REGION
    

管理防火墙资源

如果您希望服务项目中的 GKE 集群在宿主项目中创建和管理防火墙资源,则必须使用以下策略之一向服务项目的 GKE 服务账号授予适当的 IAM 权限:

控制台

  1. 在 Google Cloud 控制台中,前往 IAM 页面。

    转到 IAM

  2. 选择宿主项目。

  3. 点击 授予访问权限,然后输入服务项目的 GKE 服务账号主账号 service-SERVICE_PROJECT_NUM@container-engine-robot.iam.gserviceaccount.com

  4. 从下拉列表中选择 Compute Security Admin 角色。

  5. 点击保存

gcloud

向服务项目的 GKE 服务账号授予对宿主项目的 Compute Security Admin 角色:

gcloud projects add-iam-policy-binding HOST_PROJECT_ID \
    --member=serviceAccount:service-SERVICE_PROJECT_NUM@container-engine-robot.iam.gserviceaccount.com \
    --role=roles/compute.securityAdmin

替换以下内容:

  • HOST_PROJECT_ID:共享 VPC 宿主项目 ID
  • SERVICE_PROJECT_NUM:包含 GKE 服务账号的服务项目的 ID
  • 如需更精细的方法,请创建一个仅包含以下权限的自定义 IAM 角色compute.networks.updatePolicycompute.firewalls.listcompute.firewalls.getcompute.firewalls.createcompute.firewalls.updatecompute.firewalls.delete。向服务项目的 GKE 服务账号授予对宿主项目的自定义角色。

控制台

在包含上述 IAM 权限的宿主项目中创建一个自定义角色:

  1. 在 Google Cloud 控制台中,转到角色页面。

    转到“角色”页面

  2. 使用页面顶部的下拉列表选择宿主项目。

  3. 点击创建角色

  4. 输入角色的称谓说明ID角色发布阶段。角色创建后,角色名称便无法更改。

  5. 点击添加权限

  6. 过滤 compute.networks 并选择之前提到的 IAM 权限。

  7. 选择所有需要的权限后,点击添加

  8. 点击创建

向服务项目的 GKE 服务账号授予宿主项目中新创建的自定义角色:

  1. 在 Google Cloud 控制台中,前往 IAM 页面。

    转到 IAM

  2. 选择宿主项目。

  3. 点击 授予访问权限,然后输入服务项目的 GKE 服务账号主账号 service-SERVICE_PROJECT_NUM@container-engine-robot.iam.gserviceaccount.com

  4. 过滤新创建的自定义角色的称谓并将其选中。

  5. 点击保存

gcloud

  1. 在包含上述 IAM 权限的宿主项目中创建一个自定义角色:

    gcloud iam roles create ROLE_ID \
        --title="ROLE_TITLE" \
        --description="ROLE_DESCRIPTION" \
        --stage=LAUNCH_STAGE \
        --permissions=compute.networks.updatePolicy,compute.firewalls.list,compute.firewalls.get,compute.firewalls.create,compute.firewalls.update,compute.firewalls.delete \
        --project=HOST_PROJECT_ID
    
  2. 向服务项目的 GKE 服务账号授予宿主项目中新创建的自定义角色:

    gcloud projects add-iam-policy-binding HOST_PROJECT_ID \
        --member=serviceAccount:service-SERVICE_PROJECT_NUM@container-engine-robot.iam.gserviceaccount.com \
        --role=projects/HOST_PROJECT_ID/roles/ROLE_ID
    

    替换以下内容:

    • ROLE_ID:角色的名称,例如 gkeFirewallAdmin
    • ROLE_TITLE:角色的易记称谓,例如 GKE Firewall Admin
    • ROLE_DESCRIPTION:角色的简短说明,例如 GKE service account FW permissions
    • LAUNCH_STAGE:角色在其生命周期中的发布阶段,例如 ALPHABETAGA
    • HOST_PROJECT_ID:共享 VPC 宿主项目 ID
    • SERVICE_PROJECT_NUM:包含 GKE 服务账号的服务项目的 ID

如果多个服务项目中包含集群,则必须选择一项策略,并为每个服务项目的 GKE 服务账号重复执行此策略。

针对子网授予的角色摘要

下面简要介绍了针对子网授予的角色:

服务账号 角色 子网
service-SERVICE_PROJECT_1_NUM@container-engine-robot.iam.gserviceaccount.com Compute Network User tier-1
SERVICE_PROJECT_1_NUM@cloudservices.gserviceaccount.com Compute Network User tier-1
service-SERVICE_PROJECT_2_NUM@container-engine-robot.iam.gserviceaccount.com Compute Network User tier-2
SERVICE_PROJECT_2_NUM@cloudservices.gserviceaccount.com Compute Network User tier-2

Kubernetes Engine 访问权限

附加服务项目时,如果启用 Kubernetes Engine 访问权限,则系统会向服务项目的 GKE 服务账号授予在宿主项目中执行网络管理操作的权限。

启用 Kubernetes Engine 访问权限时,GKE 会在宿主项目中自动分配以下角色:

成员 角色 资源
service-SERVICE_PROJECT_NUM@container-engine-robot.iam.gserviceaccount.com Host Service Agent User 宿主项目中的 GKE 服务账号

但是,您必须向服务项目的 GKE 服务账号手动添加 Compute Network User IAM 权限,才能访问宿主网络。

成员 角色 资源
service-SERVICE_PROJECT_NUM@container-engine-robot.iam.gserviceaccount.com Compute Network User 特定子网或整个宿主项目

如果在未启用 Kubernetes Engine 访问权限的情况下附加了服务项目(假设宿主项目和服务项目中均已启用 Kubernetes Engine API),则您可以通过在宿主项目中添加以下 IAM 角色绑定,手动将权限分配给服务项目的 GKE 服务账号:

成员 角色 资源
service-SERVICE_PROJECT_NUM@container-engine-robot.iam.gserviceaccount.com Compute Network User 特定子网或整个宿主项目
service-SERVICE_PROJECT_NUM@container-engine-robot.iam.gserviceaccount.com Host Service Agent User 宿主项目中的 GKE 服务账号

授予 Host Service Agent User 角色

每个服务项目的 GKE 服务账号必须具有针对宿主项目的 Host Service Agent User 角色绑定。GKE 服务账号采用以下形式:

service-SERVICE_PROJECT_NUM@container-engine-robot.iam.gserviceaccount.com

其中,SERVICE_PROJECT_NUM 是您的服务项目的编号。

此绑定允许服务项目的 GKE 服务账号在宿主项目中执行网络管理操作,就像它是宿主项目的 GKE 服务账号一样。此角色只能授予服务项目的 GKE 服务账号。

控制台

如果您一直在使用 Google Cloud 控制台,则不必明确授予 Host Service Agent User 角色。在您使用 Google Cloud 控制台将服务项目附加到宿主项目时,系统已自动执行该操作。

gcloud

  1. 对于您的第一个项目,请向该项目的 GKE 服务账号授予 Host Service Agent User 角色。在您的宿主项目上授予此角色:

    gcloud projects add-iam-policy-binding HOST_PROJECT_ID \
        --member serviceAccount:service-SERVICE_PROJECT_1_NUM@container-engine-robot.iam.gserviceaccount.com \
        --role roles/container.hostServiceAgentUser
    
  2. 对于您的第二个项目,向该项目的 GKE 服务账号授予 Host Service Agent User 角色。在您的宿主项目上授予此角色:

    gcloud projects add-iam-policy-binding HOST_PROJECT_ID \
        --member serviceAccount:service-SERVICE_PROJECT_2_NUM@container-engine-robot.iam.gserviceaccount.com \
        --role roles/container.hostServiceAgentUser
    

验证可用的子网和次要 IP 地址范围

创建集群时,您必须指定要用于集群 Pod 和 Service 的子网和次要 IP 地址范围。由于多种原因,IP 地址范围可能无法使用。无论您是使用 Google Cloud 控制台还是 gcloud CLI 来创建集群,都应指定可用的 IP 地址范围。

如果某个 IP 地址范围尚未使用,则该范围可用于新集群的 Service。您为新集群的 Pod 指定的 IP 地址范围可以是未使用的范围,也可以是与其他集群中的 Pod 共用的范围。集群无法使用由 GKE 创建和管理的 IP 地址范围。

您可以使用 gcloud CLI 列出项目的可用子网和次要 IP 地址范围。

gcloud

gcloud container subnets list-usable \
    --project SERVICE_PROJECT_ID \
    --network-project HOST_PROJECT_ID

SERVICE_PROJECT_ID 替换为服务项目的项目 ID。

如果省略 --project--network-project 选项,则 gcloud CLI 命令会使用活跃配置中的默认项目。由于宿主项目和网络项目不同,因此您必须指定 --project 和/或 --network-project

输出类似于以下内容:

PROJECT: xpn-host
REGION: REGION_NAME
NETWORK: shared-net
SUBNET: tier-2
RANGE: 172.16.4.0/22

SECONDARY_RANGE_NAME: tier-2-services
IP_CIDR_RANGE: 172.20.0.0/14
STATUS: usable for pods or services

SECONDARY_RANGE_NAME: tier-2-pods
IP_CIDR_RANGE: 172.16.16.0/20
STATUS: usable for pods or services

PROJECT: xpn-host
REGION: REGION_NAME
NETWORK: shared-net
SUBNET: tier-1
RANGE: 10.0.4.0/22

SECONDARY_RANGE_NAME: tier-1-services
IP_CIDR_RANGE: 10.0.32.0/20
STATUS: usable for pods or services

SECONDARY_RANGE_NAME: tier-1-pods
IP_CIDR_RANGE: 10.4.0.0/14
STATUS: usable for pods or services

list-usable 命令会在以下情况下返回空列表:

  • 服务项目的 Kubernetes Engine 服务账号没有宿主项目的 Host Service Agent User 角色。
  • 宿主项目中的 Kubernetes Engine 服务账号不存在(例如,您意外删除了该账号)。
  • 宿主项目中未启用 Kubernetes Engine API(这意味着宿主项目中缺少 Kubernetes Engine 服务账号)。

如需了解详情,请参阅问题排查部分。

有关次要范围的注意事项

您可以在给定子网中创建 30 个次要范围。对于每个集群,您需要两个次要范围:一个用于 Pod,另一个用于 Service。

在第一个服务项目中创建集群

如需在第一个服务项目中创建集群,请使用 gcloud CLI 或 Google Cloud 控制台执行以下步骤。

控制台

  1. 转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。

    前往 Google Kubernetes Engine

  2. 在项目选择器中,选择您的第一个服务项目。

  3. 点击 创建

  4. 在 Autopilot 或 Standard 部分中,点击配置

  5. 对于名称,输入 tier-1-cluster

  6. 区域下拉列表中,选择您用于子网的同一区域。

  7. 在导航窗格中,点击网络

  8. 选择与我共享的网络(通过宿主项目)

  9. 对于网络,选择 shared-net

  10. 对于节点子网,选择 tier-1

  11. 对于 Pod 次要 CIDR 范围,选择 tier-1-pods

  12. 对于 Service 次要 CIDR 范围,选择 tier-1-services

  13. 点击创建

  14. 创建完成后,在集群列表中点击 tier-1-cluster

  15. 集群详情页面上,点击节点标签页

  16. 节点池下,点击要检查的节点池的名称。

  17. 实例组下,点击您要检查的实例组的名称。例如 gke-tier-1-cluster-default-pool-5c5add1f-grp。

  18. 在实例列表中,验证节点的内部 IP 地址是否位于 tier-1 子网的主要范围 (10.0.4.0/22) 内。

gcloud

在第一个服务项目中创建一个名为 tier-1-cluster 的集群:

gcloud container clusters create-auto tier-1-cluster \
    --project=SERVICE_PROJECT_1_ID \
    --location=COMPUTE_REGION \
    --network=projects/HOST_PROJECT_ID/global/networks/shared-net \
    --subnetwork=projects/HOST_PROJECT_ID/regions/COMPUTE_REGION/subnetworks/tier-1 \
    --cluster-secondary-range-name=tier-1-pods \
    --services-secondary-range-name=tier-1-services

创建完成后,请验证您的集群节点是否位于 tier-1 子网的主要范围 10.0.4.0/22 内。

gcloud compute instances list --project SERVICE_PROJECT_1_ID

输出会显示节点的内部 IP 地址:

NAME                    ZONE           ... INTERNAL_IP
gke-tier-1-cluster-...  ZONE_NAME      ... 10.0.4.2
gke-tier-1-cluster-...  ZONE_NAME      ... 10.0.4.3
gke-tier-1-cluster-...  ZONE_NAME      ... 10.0.4.4

在第二个服务项目中创建集群

如需在第二个服务项目中创建集群,请使用 gcloud CLI 或 Google Cloud 控制台执行以下步骤。

控制台

  1. 转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。

    转到 Google Kubernetes Engine

  2. 在项目选择器中,选择您的第二个服务项目。

  3. 点击 创建

  4. 在 Standard 或 Autopilot 部分中,点击配置

  5. 对于名称,输入 tier-2-cluster

  6. 区域下拉列表中,选择您用于子网的同一区域。

  7. 在导航窗格中,点击网络

  8. 对于网络,选择 shared-net

  9. 对于节点子网,选择 tier-2

  10. 对于 Pod 次要 CIDR 范围,选择 tier-2-pods

  11. 对于 Service 次要 CIDR 范围,选择 tier-2-services

  12. 点击创建

  13. 创建完成后,在集群列表中点击 tier-2-cluster

  14. 集群详情页面上,点击节点标签页

  15. 节点池下,点击要检查的节点池的名称。

  16. 实例组下,点击您要检查的实例组的名称。例如 gke-tier-2-cluster-default-pool-5c5add1f-grp

  17. 在实例列表中,验证节点的内部 IP 地址是否位于 tier-2 子网的主要范围 (172.16.4.0/22) 内。

gcloud

在第二个服务项目中创建一个名为 tier-2-cluster 的集群:

gcloud container clusters create-auto tier-2-cluster \
    --project=SERVICE_PROJECT_2_ID \
    --location=COMPUTE_REGION \
    --network=projects/HOST_PROJECT_ID/global/networks/shared-net \
    --subnetwork=projects/HOST_PROJECT_ID/regions/COMPUTE_REGION/subnetworks/tier-2 \
    --cluster-secondary-range-name=tier-2-pods \
    --services-secondary-range-name=tier-2-services

创建完成后,请验证您的集群节点是否位于 tier-2 子网的主要范围 172.16.4.0/22 内。

gcloud compute instances list --project SERVICE_PROJECT_2_ID

输出会显示节点的内部 IP 地址:

NAME                    ZONE           ... INTERNAL_IP
gke-tier-2-cluster-...  ZONE_NAME      ... 172.16.4.2
gke-tier-2-cluster-...  ZONE_NAME      ... 172.16.4.3
gke-tier-2-cluster-...  ZONE_NAME      ... 172.16.4.4

创建防火墙规则

如需允许流量进入网络以及在网络中的各集群之间传输,您需要创建防火墙。以下部分演示了如何创建和更新防火墙规则:

创建防火墙规则以允许通过 SSH 连接到节点

在宿主项目中,为 shared-net 网络创建防火墙规则。 允许流量进入 TCP 端口 22,这使得您可以使用 SSH 连接到集群节点。

控制台

  1. 转到 Google Cloud 控制台中的防火墙页面。

    转到“防火墙”

  2. 在项目选择器中,选择您的宿主项目。

  3. VPC 网络菜单中,点击创建防火墙规则

  4. 对于名称,请输入 my-shared-net-rule

  5. 对于网络,选择 shared-net

  6. 对于流量方向,选择入站

  7. 对于对匹配项执行的操作,选择允许

  8. 对于目标,选择网络中的所有实例

  9. 对于来源过滤条件,选择 IP 地址范围

  10. 对于来源 IP 地址范围,请输入 0.0.0.0/0

  11. 对于协议和端口,选择指定的协议和端口。 在框中输入 tcp:22

  12. 点击创建

gcloud

为您的共享网络创建防火墙规则:

gcloud compute firewall-rules create my-shared-net-rule \
    --project HOST_PROJECT_ID \
    --network shared-net \
    --direction INGRESS \
    --allow tcp:22

使用 SSH 连接到节点

创建允许 TCP 端口 22 上的入站流量的防火墙后,您可以使用 SSH 连接到该节点。

控制台

  1. 转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。

    前往 Google Kubernetes Engine

  2. 在项目选择器中,选择您的第一个服务项目。

  3. 点击 tier-1-cluster

  4. 集群详情页面上,点击节点标签页。

  5. 节点池下,点击节点池的名称。

  6. 实例组下,点击实例组的名称。例如 gke-tier-1-cluster-default-pool-faf87d48-grp。

  7. 在实例列表中,记下节点的内部 IP 地址。这些地址位于 10.0.4.0/22 范围内。

  8. 对于其中一个节点,点击 SSH。连接会成功,因为 SSH 使用 TCP 端口 22,防火墙规则允许流量进入该端口。

gcloud

列出第一个服务项目中的节点:

gcloud compute instances list --project SERVICE_PROJECT_1_ID

输出包含集群中节点的名称:

NAME                                           ...
gke-tier-1-cluster-default-pool-faf87d48-3mf8  ...
gke-tier-1-cluster-default-pool-faf87d48-q17k  ...
gke-tier-1-cluster-default-pool-faf87d48-x9rk  ...

使用 SSH 连接到其中一个节点:

gcloud compute ssh NODE_NAME \
    --project SERVICE_PROJECT_1_ID \
    --zone COMPUTE_ZONE

替换以下内容:

更新防火墙规则以在节点之间执行 ping 操作

  1. 在 SSH 命令行窗口中,启动 CoreOS 工具箱

    /usr/bin/toolbox
    
  2. 在工具箱 shell 中,对同一集群中的其他某一节点进行 ping 操作。例如:

    ping 10.0.4.4
    

    ping 命令会成功,因为您的节点和另一个节点都位于 10.0.4.0/22 范围内。

  3. 现在尝试对其他服务项目中集群的其中一个节点进行 ping 操作。例如:

    ping 172.16.4.3
    

    这次 ping 命令会失败,因为您的防火墙规则不允许互联网控制消息协议 (ICMP) 流量。

  4. 在普通命令提示符下(而不是在您的工具箱 shell 中),更新您的防火墙规则以允许 ICMP:

    gcloud compute firewall-rules update my-shared-net-rule \
        --project HOST_PROJECT_ID \
        --allow tcp:22,icmp
    
  5. 在工具箱 shell 中,再次 ping 该节点。例如:

    ping 172.16.4.3
    

    这次 ping 命令会成功。

创建其他防火墙规则

您可以创建其他防火墙规则,以允许在集群中的节点、Pod 和 Service 之间进行通信。

例如,以下规则允许来自 tier-1-cluster 中任何节点、Pod 或 Service 的流量进入任何 TCP 或 UDP 端口:

gcloud compute firewall-rules create my-shared-net-rule-2 \
    --project HOST_PROJECT_ID \
    --network shared-net \
    --allow tcp,udp \
    --direction INGRESS \
    --source-ranges 10.0.4.0/22,10.4.0.0/14,10.0.32.0/20

以下规则允许来自 tier-2-cluster 中任何节点、Pod 或 Service 的流量进入任何 TCP 或 UDP 端口:

gcloud compute firewall-rules create my-shared-net-rule-3 \
    --project HOST_PROJECT_ID \
    --network shared-net \
    --allow tcp,udp \
    --direction INGRESS \
    --source-ranges 172.16.4.0/22,172.20.0.0/14,172.16.16.0/20

Kubernetes 还将尝试在必要时创建和管理防火墙资源,例如,当您创建负载平衡器服务时。如果 Kubernetes 由于权限问题而无法更改防火墙规则,系统将触发 Kubernetes 事件来引导您进行更改。

如果要授予 Kubernetes 更改防火墙规则的权限,请参阅管理防火墙资源

对于 Ingress 负载平衡器,如果 Kubernetes 由于权限不足而无法更改防火墙规则,则会每隔几分钟发出一次 firewallXPNError 事件。在 GLBC 1.4 及更高版本中,您可以通过将 networking.gke.io/suppress-firewall-xpn-error: "true" 注释添加到 Ingress 资源,忽略 firewallXPNError 事件。您可以随时移除此注释以取消忽略。

在共享 VPC 中创建专用集群

您可以将共享 VPC 与专用集群结合使用。

这要求您在宿主项目上向用户账号或用于创建集群的服务账号授予以下权限:

  • compute.networks.get

  • compute.networks.updatePeering

您还必须确保控制层面 IP 地址范围不与共享网络中的其他预留范围重叠。

对于您在 2020 年 1 月 15 日之前创建的专用集群,每个 VPC 网络可以拥有的专用 GKE 集群数量上限为单个 VPC 网络中的对等互连连接数量。新的专用集群会重用 VPC 网络对等互连连接,从而不受此限制的约束。如需在旧的专用集群上启用 VPC 网络对等互连重复使用功能,您可以删除集群并重新创建。升级集群不会导致其重复使用现有的 VPC 网络对等互连连接。

在本部分中,您将在预定义的共享 VPC 网络中创建一个名为 private-cluster-vpc 的 VPC 原生集群。

控制台

  1. 转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。

    转到 Google Kubernetes Engine

  2. 点击 创建

  3. 在 Autopilot 或 Standard 部分中,点击配置

  4. 对于名称,输入 private-cluster-vpc

  5. 在导航窗格中,点击网络

  6. 选择专用集群

  7. (对于 Autopilot 而言为可选):将控制层面 IP 地址范围设置为 172.16.0.16/28

  8. 网络下拉列表中,选择您之前创建的 VPC 网络。

  9. 节点子网下拉列表中,选择您之前创建的共享子网。

  10. 根据需要配置集群。

  11. 点击创建

gcloud

运行以下命令,以在预定义的共享 VPC 中创建一个名为 private-cluster-vpc 的集群:

gcloud container clusters create-auto private-cluster-vpc \
    --project=PROJECT_ID \
    --location=COMPUTE_REGION \
    --network=projects/HOST_PROJECT/global/networks/shared-net \
    --subnetwork=SHARED_SUBNETWORK \
    --cluster-secondary-range-name=tier-1-pods \
    --services-secondary-range-name=tier-1-services \
    --enable-private-nodes \
    --master-ipv4-cidr=172.16.0.0/28

预留 IP 地址

您可以为共享 VPC 集群预留内部 IP 地址外部 IP 地址。确保在服务项目中保留 IP 地址。

对于内部 IP 地址,您必须提供 IP 地址所属的子网。如需跨项目预留 IP 地址,请使用完整资源网址来标识子网。

您可以在 Google Cloud CLI 中使用以下命令来预留内部 IP 地址:

gcloud compute addresses create RESERVED_IP_NAME \
    --region=COMPUTE_REGION \
    --subnet=projects/HOST_PROJECT_ID/regions/COMPUTE_REGION/subnetworks/SUBNETWORK_NAME \
    --addresses=IP_ADDRESS \
    --project=SERVICE_PROJECT_ID

如需调用此命令,您必须已添加子网的 compute.subnetworks.use 权限。您可以为调用者授予子网的 compute.networkUser 角色,也可以为调用者授予一个自定义角色(其在项目级层具有 compute.subnetworks.use 权限)。

清理

完成本指南中的练习后,请执行以下任务来移除资源,以免您的账号产生不必要的费用:

删除集群

删除您创建的两个集群。

控制台

  1. 转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。

    前往 Google Kubernetes Engine

  2. 在项目选择器中,选择您的第一个服务项目。

  3. 选择 tier-1-cluster,然后点击删除

  4. 在项目选择器中,选择您的第二个服务项目。

  5. 选择 tier-2-cluster,然后点击删除

gcloud

gcloud container clusters delete tier-1-cluster \
    --project SERVICE_PROJECT_1_ID \
    --zone COMPUTE_ZONE

gcloud container clusters delete tier-2-cluster \
    --project SERVICE_PROJECT_2_ID \
    --zone COMPUTE_ZONE

停用共享 VPC

在宿主项目中停用共享 VPC。

控制台

  1. 转到 Google Cloud 控制台中的共享 VPC 页面。

    转到共享 VPC

  2. 在项目选择器中,选择您的宿主项目。

  3. 点击停用共享 VPC

  4. 在相应字段中输入 HOST_PROJECT_ID,然后点击停用

gcloud

gcloud compute shared-vpc associated-projects remove SERVICE_PROJECT_1_ID \
    --host-project HOST_PROJECT_ID

gcloud compute shared-vpc associated-projects remove SERVICE_PROJECT_2_ID \
    --host-project HOST_PROJECT_ID

gcloud compute shared-vpc disable HOST_PROJECT_ID

删除防火墙规则

移除您创建的防火墙规则。

控制台

  1. 转到 Google Cloud 控制台中的防火墙页面。

    转到“防火墙”

  2. 在项目选择器中,选择您的宿主项目。

  3. 在规则列表中,选择 my-shared-net-rulemy-shared-net-rule-2my-shared-net-rule -3

  4. 点击删除

gcloud

删除您的防火墙规则:

gcloud compute firewall-rules delete \
    my-shared-net-rule \
    my-shared-net-rule-2 \
    my-shared-net-rule-3 \
    --project HOST_PROJECT_ID

删除共享网络

删除您创建的共享网络。

控制台

  1. 转到 Google Cloud 控制台中的 VPC 网络页面。

    转到 VPC 网络

  2. 在项目选择器中,选择您的宿主项目。

  3. 在网络列表中,选择 shared-net

  4. 点击删除 VPC 网络

gcloud

gcloud compute networks subnets delete tier-1 \
    --project HOST_PROJECT_ID \
    --region COMPUTE_REGION

gcloud compute networks subnets delete tier-2 \
    --project HOST_PROJECT_ID \
    --region COMPUTE_REGION

gcloud compute networks delete shared-net --project HOST_PROJECT_ID

移除 Host Service Agent User 角色

从两个服务项目中移除 Host Service Agent User 角色。

控制台

  1. 转到 Google Cloud 控制台中的 IAM 页面。

    转到 IAM

  2. 在项目选择器中,选择您的宿主项目。

  3. 在成员列表中,选中显示 service-SERVICE_PROJECT_1_NUM@container-engine-robot.iam.gserviceaccount.com 被授予 Kubernetes Engine Host Service Agent User 角色的行。

  4. 选择显示 service-SERVICE_PROJECT_2_NUM@container-engine-robot.iam.gserviceaccount.com 被授予 Kubernetes Engine Host Service Agent User 角色的行。

  5. 点击移除访问权限

gcloud

  1. 从第一个服务项目的 GKE 服务账号中移除 Host Service Agent User 角色:

    gcloud projects remove-iam-policy-binding HOST_PROJECT_ID \
        --member serviceAccount:service-SERVICE_PROJECT_1_NUM@container-engine-robot.iam.gserviceaccount.com \
        --role roles/container.hostServiceAgentUser
    
  2. 从第二个服务项目的 GKE 服务账号中移除 Host Service Agent User 角色:

    gcloud projects remove-iam-policy-binding HOST_PROJECT_ID \
        --member serviceAccount:service-SERVICE_PROJECT_2_NUM@container-engine-robot.iam.gserviceaccount.com \
        --role roles/container.hostServiceAgentUser
    

问题排查

以下部分将帮助您解决共享 VPC 集群的常见问题。

错误:无法从网络项目获取元数据

使用共享 VPC 集群时,以下消息是一种常见错误:

Failed to get metadata from network project. GCE_PERMISSION_DENIED: Google
Compute Engine: Required 'compute.projects.get' permission for
'projects/HOST_PROJECT_ID

出现此错误的原因如下:

  • 尚未在宿主项目中启用 Kubernetes Engine API。

  • 宿主项目的 GKE 服务账号不存在。例如,它可能已被删除。

  • 宿主项目的 GKE 服务账号没有宿主项目的 Kubernetes Engine Service Agent (container.serviceAgent) 角色。绑定可能已被意外移除。

  • 服务项目的 GKE 服务账号没有宿主项目的 Host Service Agent User 角色。

如需解决此问题,请确定宿主项目的 GKE 服务账号是否存在。

如果服务账号不存在,请执行以下操作:

  • 如果未在宿主项目中启用 Kubernetes Engine API,请将其启用。 此操作会创建宿主项目的 GKE 服务账号,并向宿主项目的 GKE 服务账号授予 Kubernetes Engine Service Agent (container.serviceAgent) 角色。

  • 如果在宿主项目中启用了 Kubernetes Engine API,这意味着宿主项目的 GKE 服务账号已被删除,或者它没有宿主项目的 Kubernetes Engine Service Agent (container.serviceAgent) 角色。如需恢复 GKE 服务账号或角色绑定,您必须先停用 Kubernetes Engine API,然后再重新启用。如需了解详情,请参阅错误 400/403:缺少账号的修改权限

问题:网络连接

如果您遇到位于同一 Virtual Private Cloud (VPC) 网络中或与 VPC 网络对等互连连接的两个 VPC 网络中的 Compute Engine 虚拟机之间的连接问题,请参阅 Virtual Private Cloud (VPC) 文档中的排查具有内部 IP 地址的虚拟机 (VM) 实例之间的连接问题

问题:丢包

如果您在使用 Cloud NATVPC 原生集群IP 伪装代理将流量从集群发送到外部 IP 地址时遇到丢包问题,请参阅排查集群中的 Cloud NAT 丢包问题

后续步骤