本教程介绍如何将以非公开方式使用的公共 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
以获取最新版本。
仅使用 VPC 原生集群。
为 VPC 对等互连设置所需的 IPAM 规范。
设置网络和集群
创建 VPC 网络:
创建以下两个 VPC 网络,并将 RFC-1918 用作节点的主要范围和 Pod 的 PUPI 范围。将 RFC 1918 专用地址空间中的主要 IP 地址范围(例如
10.x.x.x
、172.16.x.x
或192.168.x.x
)分配给这两个 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 \ --enable-ip-alias \ --network=NETWORK_NAME \ --subnetwork=SUBNETWORK_NAME \ --cluster-secondary-range-name=PRODUCER_PODS \ --services-secondary-range-name=PRODUCER_SERVICES \ --num-nodes=1 \ --zone=PRODUCER_ZONE_NAME \ --project=PRODUCER_PROJECT_NAME
替换以下内容:
PRODUCER_CLUSTER_NAME
:GKE 提供方集群的名称。COMPUTE_LOCATION
:集群的 Compute Engine 位置。PRODUCER_SUBNET_NAME
:现有子网的名称。 子网的主要 IP 地址范围用于节点。子网必须位于集群所使用的区域中。如果省略此项,GKE 会尝试使用集群所在区域的default
VPC 网络中的子网。- 如果次要范围分配方法由 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 地址范围的名称。
使用使用方网络和子网创建
consumer
集群,如下所示:gcloud container clusters create CONSUMER_CLUSTER_NAME \ --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 \ --zone=CONSUMER_ZONE \ --project=CONSUMER_PROJECT
替换以下内容:
CONSUMER_CLUSTER_NAME
:GKE 使用方集群的名称。COMPUTE_LOCATION
:集群的 Compute Engine 位置。CONSUMER_SUBNET_NAME
:现有子网的名称。 子网的主要 IP 地址范围用于节点。子网必须位于集群所使用的区域中。如果省略此项,GKE 会尝试使用集群所在区域的default
VPC 网络中的子网。- 如果次要范围分配方法由 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-vpc 网络和 producer-vpc 网络之间建立 VPC 对等互连关系,如下所示:
如需将
consumer
网络连接到提供方,请运行以下命令:gcloud compute networks peerings create PEERING_NAME \ --project=consumer_project \ --network=consumer \ --peer-network=producer
如需将
producer
网络连接到使用方,请运行以下命令:gcloud compute networks peerings create PEERING_NAME \ --project=producer_project \ --network=producer \ --peer-network=consumer \ --no-export-subnet-routes-with-public-ip \ --import-subnet-routes-with-public-ip
替换以下内容:
PEERING_NAME
:GKE 提供方集群的名称。CONSUMER_CLUSTER_NAME
:GKE 使用方集群的名称。
默认情况下,使用方 VPC 会导出 PUPI 地址。创建提供方 VPC 时,请使用以下参数将 VPC 配置为导入 PUPI 地址,但不导出它们:
--no-export-subnet-routes-with-public-ip --import-subnet-routes-with-public-ip
验证网络和子网
验证提供方网络:
gcloud compute networks describe producer \ --project=producer_project
输出类似于以下内容:
... 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-subnet \ --project=producer_project\ --region=producer_region
输出类似于以下内容:
... 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 subnets describe consumer-subnet \ --project=consumer_project \ --region=consumer_region
输出类似于以下内容:
... 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 describe consumer \ --project=consumer_project
输出类似于以下内容:
... 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 \ --project=consumer_project \ --zone=consumer_zone
输出类似于以下内容:
... 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
验证
helloweb
Deployment。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-peer-producer \ --direction=OUTGOING \ --network=consumer \ --region=<consumer_region>
输出类似于以下内容,其中显示了全部三个使用方 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-peer-consumer \ --direction=INCOMING \ --network=producer \ --region=<producer_region>
输出类似于以下内容,其中显示了全部三个使用方 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 架构中心。