本页面介绍如何将以非公开方式使用的公共 IP (PUPI) 地址应用于 Google Kubernetes Engine (GKE) Pod 地址块。
以非公开方式使用的公共 IP (PUPI) 地址是指您可以在 Google Cloud Virtual Private Cloud (VPC) 网络中以非公开方式使用的地址。这些 IP 地址不归 Google 所有。您无需拥有这些公共 IP 地址即可以非公开方式使用。
概览
GKE 集群要求为节点、Pod 和 Service 使用专用 IP 地址范围。随着基础设施的发展,您可能会面临标准内部 IP 地址空间 (RFC 1918) 耗尽问题。缓解专用 RFC 1918 地址耗尽问题的一种方法是使用 GKE Pod CIDR 地址块的以非公开方式使用的公共 IP (PUPI) 地址。PUPI 为 GKE Pod 网络提供了一种替代方案,可为其他集群组件预留专用 IP 地址。
单个集群:如果您只创建一个 GKE 集群,则可以通过启用以非公开方式使用的外部 IP 地址范围来启用 PUPI。
多个集群:如果您要使用通过 VPC 对等互连连接的多个 GKE 集群(这对于服务提供商而言是常见场景),则需要更复杂的配置。下图举例说明了公司(提供方)如何使用 PUPI 为托管式服务提供与客户(使用方)的 VPC 对等互连。

上图涉及以下注意事项:
- 主要 CIDR 地址块:用于节点和内部负载均衡器 (ILB) 且不能跨 VPC 重叠的非 PUPI CIDR 地址块。
- 提供方次要 CIDR 地址块:用于 Pod 的 PUPI CIDR 地址块(例如
45.45.0.0/16)。 - 使用方次要 CIDR 地址块:客户端的任何其他 PUPI CIDR 地址块(例如
5.5.0.0/16)。
如何在服务提供商方案中使用 PUPI
服务提供商(提供方)在其 VPC (vpc-producer) 内的 GKE 集群 (gke-2) 上运行其托管式服务。此集群使用 PUPI 范围 45.0.0.0/8 作为其 Pod IP 地址。
客户(使用方)也在自己的 VPC (vpc-consumer) 中有一个 GKE 集群 (gke-1),该集群使用另一 PUPI 范围 5.0.0.0/8 作为其 Pod IP 地址。
这两个 VPC 使用 VPC 对等互连进行连接,但每个 VPC 都继续为节点、服务和内部负载均衡器使用标准专用 IP 地址 (RFC 1918)。
确保 VPC 之间的通信
- 使用方到提供方:默认情况下,使用方的 VPC 会自动与提供方共享其 RFC 1918 路由(但不共享 PUPI)。这样,使用方 VPC 中的资源便可访问提供方 VPC 中的服务(通常通过内部负载均衡器)。
- 提供方到使用方:为了让提供方的 Pod 访问使用方 VPC 中的资源,需要进行明确配置。
- 不重叠:提供方和使用方必须确保使用方的 PUPI 范围不与提供方 VPC 中使用的任何 IP 地址冲突。
- 导出/导入:提供方必须启用导出 PUPI 路由的功能,并且使用方必须启用通过对等互连连接导入这些路由的功能。
在 PUPI 范围重叠时实现通信
如果使用方的 VPC 已使用与提供方相同的 PUPI 范围,则无法实现来自提供方 Pod 的直接通信。但是,提供方可以启用 IP 地址伪装,以便将 Pod IP 地址隐藏在提供方的节点 IP 地址后面。
下表展示了每个 VPC 的默认导入和导出设置。您可以使用 gcloud compute networks peerings update 命令修改默认 VPC 对等互连设置。
| VPC 网络 | 导入设置 | 导出设置 | 备注 |
|---|---|---|---|
| 提供方 | 默认行为(已关闭):不导入具有公共 IP 地址的子网路由 |
默认行为(已开启):导出具有公共 IP 地址的子网路由 |
通过服务网络控制标志。 |
| 使用方 | 已关闭(默认) | 已开启(默认) | 通常由客户管理,不需要通过服务网络进行修改 |
这些设置会产生以下结果:
- 提供方 VPC 看到所有客户路由。
- 使用方 VPC 未看到提供方 VPC 的 Pod 子网上配置的 PUPI 路由。
- 从提供方 Pod 到
vpc-consumer网络的流量必须在提供方集群中的节点地址后面进行转换。
前提条件
如需在 VPC Pod 与另一个 VPC 之间成功建立通信,请确保满足以下前提条件和配置:
- GKE 集群必须满足以下最低版本要求:
- Autopilot 集群:GKE 1.22 版或更高版本
- Standard 集群:GKE 1.14 版或更高版本
- 选择无法公开路由或不归 Google 所有的 PUPI 范围。
- 确保两个 VPC 的节点 IP 地址和主要 IP 地址范围不重叠。
- 如果您需要在客户 VPC 与托管式服务之间实现直接 Pod 到 Pod 通信,请按照以下步骤操作:
- Autopilot 集群:为 PUPI 配置 SNAT,以确保 Pod 到 Pod 的通信。您无需进行其他配置。
- Standard 集群:使用 SNAT 将 Pod IP 地址转换为相应的节点 IP 地址。为 PUPI 流量启用 SNAT。如需了解详情,请参阅启用以非公开方式使用的外部 IP 地址范围。
为 GKE 集群配置以非公开方式使用的公共 IP 地址
如需为 GKE 集群配置 PUPI 地址,请执行以下操作:
- 配置两个 Virtual Private Cloud 网络。
- 在每个 Virtual Private Cloud 网络内配置一个子网。
- 在每个子网的次要地址范围内配置 PUPI 地址范围。
- 使用正确的导入和导出设置在两个 Virtual Private Cloud 网络之间建立 Virtual Private Cloud 对等互连关系。
- 检查每个 Virtual Private Cloud 内的路由。
费用
在本文档中,您将使用 Google Cloud的以下收费组件:
您可使用价格计算器根据您的预计使用量来估算费用。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请通过运行
gcloud components update命令来获取最新版本。较早版本的 gcloud CLI 可能不支持运行本文档中的命令。
仅使用 VPC 原生集群。
为 VPC 对等互连设置所需的 IPAM 规范。
设置网络和集群
创建 VPC 网络:
创建以下两个 VPC 网络,并将 RFC-1918 用作节点的主要范围和 Pod 的 PUPI 范围。将 RFC 1918 专用地址空间(例如
10.x.x.x、172.16.x.x或192.168.x.x)中的主要 IP 地址范围分配给这两个 VPC。这些范围通常用于 GKE 集群中的工作器节点。除了内部 IP 地址范围之外,请为每个 VPC 指定单独的以非公开方式使用的公共 IP 地址 (PUPI) 范围。这些 PUPI 范围专门用于相应 GKE 集群中的 Pod IP 地址。使用方 VPC 网络:此 VPC 托管在其中运行使用方应用或工作负载的 GKE 集群。您可以使用如下所示的配置:
Network: consumer Subnetwork: consumer-subnet Primary range: 10.129.0.0/24 Service range name and cidr: consumer-services, 172.16.5.0/24 Pod range name and cidr: consumer-pods, 5.5.5.0/24 Cluster name: consumer-cluster提供方 VPC 网络:此 VPC 托管负责提供使用方使用的服务的 GKE 集群。您可以使用如下所示的配置:
Network: producer Subnetwork: producer-subnet Primary range: 10.128.0.0/24 Service range name and cidr: producer-services, 172.16.45.0/24 Pod range name and cidr: producer-pods, 45.45.45.0/24 Cluster name: producer-cluster
如需详细了解如何创建 VPC 网络,请参阅创建 VPC 网络。
借助在上一步中使用 PUPI 范围创建的 VPC 网络和子网,您可以创建两个 GKE 集群(
producer和consumer)。使用提供方网络和子网创建
producer集群,如下所示:gcloud container clusters create PRODUCER_CLUSTER_NAME \ --location=PRODUCER_CONTROL_PLANE_LOCATION \ --enable-ip-alias \ --network=PRODUCER_NETWORK_NAME \ --subnetwork=PRODUCER_SUBNETWORK_NAME \ --cluster-secondary-range-name=PRODUCER_PODS \ --services-secondary-range-name=PRODUCER_SERVICES \ --num-nodes=1 \ --project=PRODUCER_PROJECT_ID替换以下内容:
PRODUCER_CLUSTER_NAME:GKE 提供方集群的名称。PRODUCER_CONTROL_PLANE_LOCATION:提供方集群控制平面的 Compute Engine 位置。为区域级集群提供区域,或为可用区级集群提供可用区。PRODUCER_NETWORK_NAME:现有提供方 VPC 网络的名称。PRODUCER_SUBNETWORK_NAME:现有子网的名称。 子网的主要 IP 地址范围用于节点。子网必须位于集群所使用的区域中。如果省略此项,GKE 会尝试使用集群所在区域的defaultVPC 网络中的子网。- 如果次要范围分配方法由 GKE 管理:
POD_IP_RANGE:以 CIDR 表示法表示的 IP 地址范围(例如10.0.0.0/14),或 CIDR 地址块的子网掩码大小(例如/14)。此项用于为 Pod 创建子网次要 IP 地址范围。如果您省略--cluster-ipv4-cidr选项,GKE 会自动选择/14范围(218 个地址)。系统会从10.0.0.0/8(范围为 224 个地址)随机选择自动选择的范围。SERVICES_IP_RANGE:以 CIDR 表示法表示的 IP 地址范围(例如10.4.0.0/19)或 CIDR 地址块的子网掩码大小(例如/19)。此项用于为 Service 创建子网次要 IP 地址范围。
- 如果次要范围分配方法由用户管理:
SECONDARY_RANGE_PODS:指定的SUBNET_NAME中现有次要 IP 地址范围的名称。GKE 将整个子网次要 IP 地址范围用于集群的 Pod。SECONDARY_RANGE_SERVICES:指定项中现有次要 IP 地址范围的名称。
PRODUCER_PROJECT_ID:提供方项目的 ID。
使用使用方网络和子网创建
consumer集群,如下所示:gcloud container clusters create CONSUMER_CLUSTER_NAME \ --location=CONSUMER_CONTROL_PLANE_LOCATION \ --enable-ip-alias \ --network=CONSUMER_NETWORK_NAME \ --subnetwork=CONSUMER_SUBNETWORK_NAME \ --cluster-secondary-range-name=CONSUMER_PODS \ --services-secondary-range-name=CONSUMER_SERVICES \ --num-nodes=1 \ --project=CONSUMER_PROJECT_ID替换以下内容:
CONSUMER_CLUSTER_NAME:GKE 使用方集群的名称。CONSUMER_CONTROL_PLANE_LOCATION:使用方集群控制平面的 Compute Engine 位置。为区域级集群提供区域,或为可用区级集群提供可用区。PRODUCER_NETWORK_NAME:现有使用方 VPC 网络的名称。CONSUMER_SUBNETWORK_NAME:现有子网的名称。 子网的主要 IP 地址范围用于节点。子网必须位于集群所使用的区域中。如果省略此项,GKE 会尝试使用集群所在区域的defaultVPC 网络中的子网。- 如果次要范围分配方法由 GKE 管理:
POD_IP_RANGE:以 CIDR 表示法表示的 IP 地址范围(例如10.0.0.0/14),或 CIDR 地址块的子网掩码大小(例如/14)。此项用于为 Pod 创建子网次要 IP 地址范围。如果您省略--cluster-ipv4-cidr选项,GKE 会自动选择/14范围(218 个地址)。系统会从10.0.0.0/8(范围为 224 个地址)随机选择自动选择的范围,且该范围不会包括分配给虚拟机和现有路由的 IP 地址范围,也不会包括分配给其他集群的范围。自动选择的范围可能与预留的 IP 地址、动态路由或与此集群建立对等互连的 VPC 内的路由相冲突。如果您使用其中任一项,则应指定--cluster-ipv4-cidr以防止发生冲突。SERVICES_IP_RANGE:以 CIDR 表示法表示的 IP 地址范围(例如10.4.0.0/19)或 CIDR 地址块的子网掩码大小(例如/19)。此项用于为 Service 创建子网次要 IP 地址范围。
- 如果次要范围分配方法由用户管理:
SECONDARY_RANGE_PODS:指定的SUBNET_NAME中现有次要 IP 地址范围的名称。GKE 将整个子网次要 IP 地址范围用于集群的 Pod。SECONDARY_RANGE_SERVICES:指定项中现有次要 IP 地址范围的名称。
CONSUMER_PROJECT_ID:使用方项目的 ID。
如需详细了解如何创建集群,请参阅创建集群。
在 consumer-vpc 网络和 producer-vpc 网络之间建立 VPC 对等互连关系,如下所示:
如需将
consumer网络连接到提供方,请运行以下命令:gcloud compute networks peerings create CONSUMER_PEERING_NAME \ --project=CONSUMER_PROJECT_ID \ --network=CONSUMER_NETWORK_NAME \ --peer-network=PRODUCER_NETWORK_NAME将
CONSUMER_PEERING_NAME替换为要添加到使用方网络的对等互连的名称。如需将
producer网络连接到使用方,请运行以下命令:gcloud compute networks peerings create PRODUCER_PEERING_NAME \ --project=PRODUCER_PROJECT_ID \ --network=PRODUCER_NETWORK_NAME \ --peer-network=CONSUMER_NETWORK_NAME \ --no-export-subnet-routes-with-public-ip \ --import-subnet-routes-with-public-ip将
PRODUCER_PEERING_NAME替换为要添加到提供方网络的对等互连的名称。
默认情况下,使用方 VPC 会导出 PUPI 地址。创建提供方 VPC 时,请使用以下参数将 VPC 配置为导入 PUPI 地址,但不导出它们:
--no-export-subnet-routes-with-public-ip --import-subnet-routes-with-public-ip
验证网络和子网
验证提供方网络:
gcloud compute networks describe PRODUCER_NETWORK_NAME \ --project=PRODUCER_PROJECT_ID输出类似于以下内容:
... kind: compute#network name: producer peerings: - autoCreateRoutes: true exchangeSubnetRoutes: true exportCustomRoutes: false exportSubnetRoutesWithPublicIp: false importCustomRoutes: false importSubnetRoutesWithPublicIp: true name: producer-peer-consumer …验证提供方子网:
gcloud compute networks subnets describe PRODUCER_SUBNETWORK_NAME \ --project=PRODUCER_PROJECT_ID\ --region=PRODUCER_CONTROL_PLANE_LOCATION输出类似于以下内容:
... ipCidrRange: 10.128.0.0/24 kind: compute#subnetwork name: producer-subnet … secondaryIpRanges: - ipCidrRange: 172.16.45.0/24 rangeName: producer-services - ipCidrRange: 45.45.45.0/24 rangeName: producer-pods …验证使用方网络:
gcloud compute networks describe CONSUMER_NETWORK_NAME \ --project=CONSUMER_PROJECT_ID输出类似于以下内容:
... kind: compute#network name: consumer peerings: - autoCreateRoutes: true exchangeSubnetRoutes: true exportCustomRoutes: false exportSubnetRoutesWithPublicIp: true importCustomRoutes: false importSubnetRoutesWithPublicIp: false name: consumer-peer-producer ...验证使用方子网:
gcloud compute networks subnets describe CONSUMER_SUBNETWORK_NAME \ --project=CONSUMER_PROJECT_ID\ --region=CONSUMER_CONTROL_PLANE_LOCATION输出类似于以下内容:
... ipCidrRange: 10.129.0.0/24 kind: compute#subnetwork name: consumer-subnet ... secondaryIpRanges: - ipCidrRange: 172.16.5.0/24 rangeName: consumer-services - ipCidrRange: 5.5.5.0/24 rangeName: consumer-pods ...
验证 GKE 集群及其资源
获取使用方集群凭据:
gcloud container clusters get-credentials CONSUMER_CLUSTER_NAME \ --project=CONSUMER_PROJECT_ID \ --location=CONSUMER_CONTROL_PLANE_LOCATION输出类似于以下内容:
... Fetching cluster endpoint and auth data. kubeconfig entry generated for consumer-cluster. ...-
或者,您也可以将以下清单保存为
deployment.yaml:kubectl apply -f - <<'EOF' apiVersion: apps/v1 kind: Deployment metadata: name: helloweb labels: app: hello spec: selector: matchLabels: app: hello tier: web template: metadata: labels: app: hello tier: web spec: containers: - name: hello-app image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0 ports: - containerPort: 8080 resources: requests: cpu: 200m EOF 应用 deployment.yaml:
kubectl apply -f验证
hellowebDeployment。kubectl get deployment helloweb输出类似于以下内容:
... NAME READY UP-TO-DATE AVAILABLE AGE helloweb 1/1 1 1 10s ...
验证解决方案
验证是否已成功创建 VPC 对等互连:
gcloud compute networks peerings list输出类似于以下内容,其中显示了名为使用方和提供方的对等互连:
NAME NETWORK PEER_PROJECT PEER_NETWORK STACK_TYPE PEER_MTU IMPORT_CUSTOM_ROUTES EXPORT_CUSTOM_ROUTES STATE STATE_DETAILS consumer-peer-producer consumer <project_name> producer IPV4_ONLY 1460 False False ACTIVE [2023-08-07T13:14:57.178-07:00]: Connected. producer-peer-consumer producer <project_name> consumer IPV4_ONLY 1460 False False ACTIVE [2023-08-07T13:14:57.178-07:00]: Connected.验证使用方 VPC 是否导出 PUPI 路由:
gcloud compute networks peerings list-routes CONSUMER_PEERING_NAME \ --direction=OUTGOING \ --network=CONSUMER_NETWORK_NAME \ --region=CONSUMER_CONTROL_PLANE_LOCATION输出类似于以下内容,其中显示了全部三个使用方 CIDR 地址块:
DEST_RANGE TYPE NEXT_HOP_REGION PRIORITY STATUS 10.129.0.0/24 SUBNET_PEERING_ROUTE us-central1 0 accepted by peer 172.16.5.0/24 SUBNET_PEERING_ROUTE us-central1 0 accepted by peer 5.5.5.0/24 SUBNET_PEERING_ROUTE us-central1 0 accepted by peer验证提供方 VCP 导入的 PUPI 路由:
gcloud compute networks peerings list-routes PRODUCER_PEERING_NAME \ --direction=INCOMING \ --network=PRODUCER_NETWORK_NAME \ --region=PRODUCER_CONTROL_PLANE_LOCATION输出类似于以下内容,其中显示了全部三个使用方 CIDR 地址块:
DEST_RANGE TYPE NEXT_HOP_REGION PRIORITY STATUS 10.129.0.0/24 SUBNET_PEERING_ROUTE us-central1 0 accepted 172.16.5.0/24 SUBNET_PEERING_ROUTE us-central1 0 accepted 5.5.5.0/24 SUBNET_PEERING_ROUTE us-central1 0 accepted验证 GKE Pod 是否拥有 PUPI 地址:
kubectl get pod -o wide输出类似于以下内容,其中显示 Pod 的 IP 地址在 5.5.5/24 范围内。
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES helloweb-575d78464d-xfklj 1/1 Running 0 28m 5.5.5.16 gke-consumer-cluster-default-pool-e62b6542-dp5f <none> <none>
后续步骤
- 阅读配置专用服务访问通道指南。
- 阅读 Service Networking API 使用入门指南。
- 探索有关Google Cloud的参考架构、图表和最佳实践。查看我们的 Cloud 架构中心。