设置使用共享 VPC 的集群

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

概览

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

您可以将共享 VPC 与可用区级和区域级集群结合使用。使用共享 VPC 的集群不能使用旧式网络,并且必须启用别名 IP 地址

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

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

关于示例

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

本指南中的示例使用特定名称和地址范围来说明一般流程。如果您愿意,可以根据需要更改名称和地址范围。此外,练习还使用 us-central1 区域和 us-central1-a 地区。如果您愿意,可以根据需要更改区域和地区。

准备工作

在开始设置使用共享 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 工具或 Google Cloud Console 查找项目 ID 和项目编号。

控制台

  1. 访问 Google Cloud Console 中的“首页”。

    访问“首页”

  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

在项目中启用 Google Kubernetes Engine API

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

您可以使用 Google Cloud Console 或 gcloud 工具启用 Google Kubernetes Engine API。

控制台

  1. 访问 Cloud Console 中的 API 和服务信息中心。

    访问 API 信息中心

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

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

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

gcloud

为您的三个项目启用 Google Kubernetes Engine 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. 访问 Cloud Console 中的“VPC 网络”页面。

    访问“VPC 网络”页面

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

  3. 点击 创建 VPC 网络

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

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

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

  7. 对于区域,选择 us-central1

  8. 对于 IP 地址范围,输入 10.0.4.0/22

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

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

  11. 点击添加子网

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

  13. 对于区域,选择 us-central1

  14. 对于 IP 地址范围,输入 172.16.4.0/22

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

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

  17. 点击创建

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 us-central1 \
    --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 us-central1 \
    --secondary-range tier-2-services=172.16.16.0/20,tier-2-pods=172.20.0.0/14

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

您有两个服务项目,每个服务项目都有多个服务帐号。 本部分涉及您的 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. 访问 Cloud Console 中的“共享 VPC”页面。

    访问“共享 VPC”页面

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

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

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

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

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

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

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

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

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

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

  12. 在右侧窗格中,删除属于第二个服务项目的任何服务帐号。也就是说,删除包含 service-project2-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 us-central1
    

    输出包含 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 us-central1
    
  7. 获取 tier-2 子网的 IAM 政策:

    gcloud compute networks subnets get-iam-policy tier-2 \
        --project host-project-id \
        --region us-central1
    

    输出包含 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 us-central1
    

管理防火墙资源

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

  • 向服务项目的 GKE 服务帐号授予对宿主项目的 Security Admin 角色。

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

如果多个服务项目中包含集群,则必须选择一项策略,并为每个服务项目的 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 访问权限的情况下附加了服务项目(假设宿主项目和服务项目中均已启用 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-project-num 是您的服务项目的编号:

service-service-project-num@container-engine-robot.iam.gserviceaccount.com

此绑定允许服务项目的 GKE 服务帐号在宿主项目中执行网络管理操作,就像它是宿主项目的 GKE 服务帐号一样。例如,控制层面使用宿主项目的 GKE 服务帐号来创建防火墙规则。此角色只能授予服务项目的 GKE 服务帐号。

控制台

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

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 地址范围可能无法使用。无论您是使用 Cloud Console 还是 gcloud 命令行工具来创建集群,都应指定可用的 IP 地址范围。

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

您可以使用 gcloud 命令行工具列出项目的可用子网和次要 IP 范围。

gcloud

gcloud container subnets list-usable \
    --project service-project-id \
    --network-project host-project-id

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

该命令的输出如下所示:

PROJECT   REGION       NETWORK      SUBNET          RANGE
xpn-host  us-central1  empty-vpc    empty-subnet    10.0.0.0/21
xpn-host  us-east1     some-vpc     some-subnet     10.0.0.0/19
    ┌──────────────────────┬───────────────┬─────────────────────────────┐
    │ SECONDARY_RANGE_NAME │ IP_CIDR_RANGE │            STATUS           │
    ├──────────────────────┼───────────────┼─────────────────────────────┤
    │ pods-range           │ 10.2.0.0/21   │ usable for pods or services │
    │ svc-range            │ 10.1.0.0/21   │ usable for pods or services │
    └──────────────────────┴───────────────┴─────────────────────────────┘
xpn-host  us-central1  shared-net   tier-2          172.16.4.0/22
    ┌──────────────────────┬────────────────┬─────────────────────────────┐
    │ SECONDARY_RANGE_NAME │ IP_CIDR_RANGE  │            STATUS           │
    ├──────────────────────┼────────────────┼─────────────────────────────┤
    │ tier-2-services      │ 172.16.16.0/20 │ usable for pods or services │
    │ tier-2-pods          │ 172.20.0.0/14  │ usable for pods or services │
    └──────────────────────┴────────────────┴─────────────────────────────┘
xpn-host  us-central1  shared-net   tier-1          10.0.4.0/22
    ┌──────────────────────┬───────────────┬─────────────────────────────┐
    │ SECONDARY_RANGE_NAME │ IP_CIDR_RANGE │            STATUS           │
    ├──────────────────────┼───────────────┼─────────────────────────────┤
    │ tier-1-services      │ 10.0.32.0/20  │ unusable                    │
    │ tier-1-pods          │ 10.4.0.0/14   │ usable for pods             │
    │ tier-1-extra         │ 10.8.0.0/14   │ usable for pods or services │
    └──────────────────────┴───────────────┴─────────────────────────────┘

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

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

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

有关次要范围的注意事项

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

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

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

控制台

  1. 访问 Cloud Console 中的 Google Kubernetes Engine 菜单。

    访问 Google Kubernetes Engine 菜单

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

  3. 点击 创建

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

  5. 对于位置类型,选择地区

  6. 地区下拉列表中,选择 us-central1-a

  7. 在导航窗格的集群下,点击网络

  8. 选择启用 VPC 原生流量路由(使用别名 IP)复选框。

  9. 清除自动创建次要范围复选框。

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

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

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

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

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

  15. 点击创建

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

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

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

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

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

gcloud

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

gcloud container clusters create tier-1-cluster \
    --project service-project-1-id \
    --zone=us-central1-a \
    --enable-ip-alias \
    --network projects/host-project-id/global/networks/shared-net \
    --subnetwork projects/host-project-id/regions/us-central1/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-...  us-central1-a  ... 10.0.4.2
gke-tier-1-cluster-...  us-central1-a  ... 10.0.4.3
gke-tier-1-cluster-...  us-central1-a  ... 10.0.4.4

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

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

控制台

  1. 访问 Cloud Console 中的 Google Kubernetes Engine 菜单。

    访问 Google Kubernetes Engine 菜单

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

  3. 点击 创建

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

  5. 对于位置类型,选择地区

  6. 地区下拉列表中,选择 us-central1-a

  7. 在导航窗格的集群下,点击网络

  8. 选择启用 VPC 原生流量路由(使用别名 IP)复选框。

  9. 清除自动创建次要范围复选框。

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

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

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

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

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

  15. 点击创建

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

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

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

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

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

gcloud

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

gcloud container clusters create tier-2-cluster \
    --project service-project-2-id \
    --zone=us-central1-a \
    --enable-ip-alias \
    --network projects/host-project-id/global/networks/shared-net \
    --subnetwork projects/host-project-id/regions/us-central1/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-...  us-central1-a  ... 172.16.4.2
gke-tier-2-cluster-...  us-central1-a  ... 172.16.4.3
gke-tier-2-cluster-...  us-central1-a  ... 172.16.4.4

创建防火墙规则

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

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

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

控制台

  1. 访问 Cloud Console 中的“防火墙”页面。

    访问“防火墙规则”页面

  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. 访问 Cloud Console 中的 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 us-central1-a \

其中 node-name 是您的其中一个节点的名称。

更新防火墙规则以在节点之间执行 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 与专用集群结合使用。无需特殊设置,但是,您必须确保控制层面(主服务器)CIDR 范围不与共享网络中的其他预留范围重叠。

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

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

控制台

  1. 转到 Cloud Console 中的 Google Kubernetes Engine 页面:

    转到 Google Kubernetes Engine

  2. 点击 创建

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

  4. 在导航窗格的集群下,点击网络

  5. 选择专用集群

  6. 确保选中使用控制平面的外部 IP 地址对其进行访问复选框。

  7. 控制平面 IP 地址范围设置为 172.16.0.16/28

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

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

  10. 确保选中启用 VPC 原生流量路由(使用别名 IP)复选框。

  11. 根据需要配置集群。

  12. 点击创建

gcloud

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

gcloud container clusters create private-cluster-vpc \
    --project project-id \
    --enable-ip-alias \
    --network projects/host-project/global/networks/shared-net \
    --subnetwork shared-subnetwork \
    --cluster-secondary-range-name c0-pods \
    --services-secondary-range-name c0-services \
    --enable-private-nodes \
    --master-ipv4-cidr 172.16.0.0/28

预留 IP 地址

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

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

您可以在 gcloud 命令行工具中使用以下命令来预留内部 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. 访问 Cloud Console 中的 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 us-central1-a

gcloud container clusters delete tier-2-cluster \
    --project service-project-2-id \
    --zone us-central1-a

停用共享 VPC

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

控制台

  1. 访问 Cloud Console 中的“共享 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. 访问 Cloud Console 中的“防火墙”页面。

    访问“防火墙规则”页面

  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. 访问 Cloud Console 中的“VPC 网络”页面。

    访问“VPC 网络”页面

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

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

  4. 点击删除 VPC 网络

gcloud

gcloud compute networks subnets delete tier-1 \
    --project host-project-id \
    --region us-central1

gcloud compute networks subnets delete tier-2 \
    --project host-project-id \
    --region us-central1

gcloud compute networks delete shared-net --project host-project-id

移除 Host Service Agent User 角色

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

控制台

  1. 访问 Cloud Console 中的 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
    

问题排查

权限遭拒

症状

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 服务帐号不存在。例如,它可能已被删除。

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

  • 服务项目的 Google Kubernetes Engine 服务帐号不具有宿主项目的 Host Service Agent User 角色。

解决方法:确定宿主项目的 Google Kubernetes Engine 服务帐号是否存在。 如果不存在,请执行以下操作:

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

  • 如果在宿主项目中启用了 Kubernetes Engine API,这意味着宿主项目的 Google Kubernetes Engine 服务帐号已被删除,或者它没有宿主项目的 Kubernetes Engine Service Agent (container.serviceAgent) 角色。如需恢复 Google Kubernetes Engine 服务帐号或角色绑定,您必须先停用 Kubernetes Engine API,然后再重新启用。如需了解详情,请参阅 Google Kubernetes Engine 问题排查

后续步骤