本页面介绍如何在 Google Kubernetes Engine (GKE) Pod 上实现永久性 IP 地址。您可以使用自定义永久性 IP 地址映射来控制 GKE Pod 网络。如需详细了解永久性 IP 地址、其应用场景和优势,请参阅 GKE Pod 的永久性 IP 地址简介。
要求
- GKE 1.31 版或更高版本。
- 选择预留 Google 提供的 IP 地址,或是自备 IP 地址 (BYOIP)。
- 配置在 Pod 中运行的应用,以识别和使用分配的永久性 IP 地址。
- GKE Pod 的永久性 IP 地址需要启用了 GKE Dataplane V2 和 Gateway API 的集群。
限制
- 您必须将应用配置为使用分配的永久性 IP 地址。GKE 不会自动将 IP 地址配置添加到 Pod 的网络接口。
- 每个永久性 IP 地址一次可以与一个 Pod 相关联。如果您有多个 Pod 可用,GKE 通常会将流量发送到最新的匹配 Pod。但是,GKE 仅在最新 Pod 健康状况良好时才会执行此操作,这意味着 Pod 的
Ready条件状态在默认情况下为True。您可以使用GKEIPRoute上的reactionMode设置来配置此行为并进行更改。 - GKE 仅支持将 IPv4 地址用作永久性 IP 地址。
- GKE 仅支持第 3 层或设备类型多网络。
- 使用永久性 IP 地址支持高可用性 (HA) 不适合非 DPDK 应用场景。
- 您可以在单个
GKEIPRoute上指定最多 16 个 IP 地址。如需配置更多地址,您可以创建多个GKEIPRoute对象。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行
gcloud components update命令以获取最新版本。较早版本的 gcloud CLI 可能不支持运行本文档中的命令。
为 GKE Pod 实现永久性 IP 地址
GKE 中的永久性 IP 地址提供了一种为 Pod 提供稳定网络身份的方法(即使 Pod 本身进行更新或四处移动也是如此)。
本部分总结了为 GKE Pod 实现永久性 IP 地址的工作流:
- 创建集群:创建一个使用 Gateway API 和 GKE Dataplane V2 的集群。
- 预留 IP 地址:确定您需要外部(可公开访问)还是内部(仅限 Google Cloud)IP 地址并预留该地址。选择 GKE 集群所在的同一区域。
- 创建 Gateway:配置 Kubernetes Gateway 对象,该对象用于容纳预留的永久性 IP 地址,并且可让您创建有关集群中哪些 Pod 可以使用这些永久性 IP 地址的规则 (
GKEIPRoutes)。 - 创建或识别工作负载以用于永久性 IP 地址:如果您在其他网络上使用永久性 IP 地址,请通过启用多个网络接口并定义永久性 IP 地址所在的网络,使 Pod 准备好使用永久性 IP 地址。
- 为所选工作负载创建 GKEIPRoute 对象:配置
GKEIPRoute以将永久性 IP 地址分配给特定 Pod。您可以使用标签来确定正确的目标 Pod,并且可以视情况配置路由如何响应 Pod 更改。 - 配置应用感知:在 Pod 中配置应用以主动使用永久性 IP 地址。
- 监控:跟踪网关和
GKEIPRoute对象的状态,以确保一切按预期正常运行。
如需为 GKE Pod 实现永久性 IP 地址,请执行以下步骤:
第 1 步:创建启用了 Gateway API 和 GKE Dataplane V2 的 GKE 集群
如需启用在 GKE Pod 上实现永久性 IP 地址所需的高级网络路由和 IP 地址管理功能,您必须创建 GKE Dataplane V2 集群,如下所示:
gcloud container clusters create CLUSTER_NAME \
--cluster-version=CLUSTER_VERSION \
--enable-dataplane-v2 \
--enable-ip-alias \
--gateway-api=standard
替换以下内容:
CLUSTER_NAME:集群的名称。CLUSTER_VERSION:集群的版本。
第 2 步:设置永久性 IP 地址
如需为 Pod 建立可靠的网络身份并设置永久性 IP 地址,您必须先获取永久性 IP 地址。您可以选择预留 Google 提供的 IP 地址,或是使用自备 IP 地址 (BYOIP)。
第 2a 步:预留 Google 提供的 IP 地址
如需预留外部 IP 地址,请运行以下命令:
gcloud compute addresses create ADDRESS_NAME \
--region=REGION
替换以下内容:
ADDRESS_NAME:您要与此地址关联的名称。REGION:您要预留此地址的区域。此区域应为您要将 IP 地址附加到的 Pod 所在的区域。注意:您必须在预留 IP 地址时指定区域,因为处理永久性 IP 地址的流量路由的转发规则是区域级的。您的 IP 地址和 GKE 集群必须位于同一区域,才能使路由正常运行。
如需预留内部 IP 地址,请运行以下命令:
gcloud compute addresses create ADDRESS_NAME \
--region REGION
--subnet SUBNETWORK \
--addresses IP_ADDRESS
替换以下内容:
ADDRESS_NAME:您要预留的一个或多个地址的名称。对于多个地址,请将所有地址指定为列表(以空格分隔)。例如:example-address-1 example-address-2 example-address-3REGION:此请求对应的区域。SUBNETWORK:此内部 IPv4 地址所属的子网。
为了确保在专用网络中正确路由流量,内部 IP 地址必须属于集群的默认子网或其他网络子网。
如需详细了解外部和内部 IP 地址,或了解如何使用控制台预留地址,请参阅预留静态外部 IP 地址和预留静态内部 IP 地址。
第 2b 步:自备 IP 地址 (BYOIP)
您可以自备 IP 地址 (BYOIP),而不是依赖于 Google 提供的 IP 地址。如果您需要将特定 IP 地址用于应用或将现有系统迁移到 Google Cloud,则 BYOIP 非常有用。如需使用 BYOIP,Google 会验证您是否拥有该 IP 地址范围,在这些 IP 地址导入 Google Cloud后,您可以将其分配为 GKE Pod 的永久性 IP 地址。如需了解详情,请参阅使用自备 IP 地址。
第 3 步:创建网关对象
网关对象用于保存 IP 地址,并定义哪些 Pod 有资格使用它们。如需控制将永久性 IP 地址分配给 GKE Pod 的方式,您会使用网关对象。
- 创建适当类的 Kubernetes 网关对象:
gke-persistent-regional-external-managed,用于外部(公共)IP 地址。gke-persistent-regional-internal-managed,用于内部(仅限Google Cloud)IP 地址。
- 在网关的地址部分中,列出此网关管理的永久性 IP 地址(Google 提供的 IP 地址或 BYOIP)。
使用
Listeners部分确定哪些 Pod(及其关联的GKEIPRoute对象)可能会使用网关的 IP 地址。Listeners基于GKEIPRoute对象所在的 GKEIPRoute 命名空间充当过滤条件。您可以从以下 Kubernetes 命名空间选择选项中进行选择:
- 所有命名空间:集群中的任何
GKEIPRoute。 - 选择器:GKEIPRoute 命名空间中与特定标签匹配的
GKEIPRoute。 - 相同命名空间:仅限位于网关所在的 GKEIPRoute 命名空间中的
GKEIPRoutes。
- 所有命名空间:集群中的任何
以下示例提供对外部永久性 IP 地址的集群范围访问权限,允许任何 Pod 使用它们。
将以下示例清单保存为 allowed-pod-ips.yaml:
kind: Gateway
apiVersion: gateway.networking.k8s.io/v1
metadata:
namespace: default
name: allowed-pod-ips
spec:
gatewayClassName: gke-persistent-regional-external-managed
listeners:
- name: default
port: 443
protocol: none
allowedRoutes:
namespaces:
from: All
addresses:
- value: "34.123.10.1/32"
type: "gke.networking.io/cidr"
- value: "34.123.10.2/32"
type: "gke.networking.io/cidr"
其中:
- addresses:列出其权限由特定网关管理的所有 IP 地址。
- listeners:用于标识
GKEIPRoute对象可以从中引用此 Gateway 的命名空间。
将清单应用于集群:
kubectl apply -f allowed-pod-ips.yaml
第 4 步:(可选)使用其他网络创建或识别工作负载以用于永久性 IP 地址
如果您打算将永久性 IP 地址用于需要连接到多个网络的 Pod,可以设置多网络 Pod 并创建网络对象以表示永久性 IP 地址所属的网络。
第 5 步:为所选工作负载创建 GKEIPRoute 对象
如需为所选 Pod 分配永久性 IP 地址,请创建 GKEIPRoute 对象。
将以下示例清单保存为 my-ip-route.yaml:
kind: GKEIPRoute
apiVersion: networking.gke.io/v1
metadata:
namespace: default
name: my-ip-route
spec:
parentRefs:
- name: allowed-pod-ips
namespace: default
addresses:
- value: "34.123.10.1/32"
type: "gke.networking.io/cidr"
network: default
reactionMode: ReadyCondition
podSelector: # Only one pod is selected.
matchLabels:
component: proxy
其中:
- parentRefs:指向从中使用永久性 IP 地址的网关。该字段不可更改。
- addresses:列出路由到使用
podSelector标识的 Pod 的所有永久性 IP 地址。此字段可更改。 对于 IPv4,仅支持 /32 地址。 - podSelector:指定用于标识永久性 IP 地址路由到的 Pod 的标签。此字段可更改,应用于放置
GKEIPRoute的同一命名空间。如果您选择多个 Pod,需考虑另外两个因素:Pod 创建时间(GKE 会选择最新 Pod)和reactionMode字段的设置。 - reactionMode:指定在创建或删除特定 Pod(通过
podSelector选择)时,此功能的行为方式。此字段是可选字段,默认值为ReadyCondition。ReadyCondition字段不可更改。您可以设置reactionMode以控制在创建、删除或更新 Pod 时此功能的行为方式。 - network:指向永久性 IP 地址路由到的 Pod 上的网络接口。此字段是可选字段,默认值为
default。请注意,如果您使用默认网络,则必须将network设置为default。如果您使用其他网络,请将网络设置为您之前创建的网络对象的名称。该字段不可更改。
将清单应用于集群:
kubectl apply -f my-ip-route.yaml
为 StatefulSet Pod 分配永久性 IP 地址
如需为 StatefulSet 中的特定多网络 Pod 分配永久性 IP 地址,请使用 Pod 的可预测主机名和 Kubernetes 的自动添加标签功能,如以下示例所示:
将以下示例清单保存为 my-pod-ips.yaml:
kind: GKEIPRoute
apiVersion: networking.gke.io/v1
metadata:
namespace: proxy-ss-ns
name: my-pod-ips
spec:
parentRefs:
- name: allowed-pod-ips
namespace: default
addresses:
- value: "34.123.10.1/32"
type: "gke.networking.io/cidr"
- value: "34.123.10.2/32"
type: "gke.networking.io/cidr"
network: blue-network
reactionMode: ReadyCondition
podSelector:
matchLabels:
statefulset.kubernetes.io/pod-name: proxy-ss-1
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
namespace: proxy-ss-ns
name: proxy-ss
spec:
selector:
matchLabels:
component: proxy
serviceName: "proxy"
replicas: 3
template:
metadata:
annotations:
networking.gke.io/default-interface: 'eth0'
networking.gke.io/interfaces: '[{"interfaceName":"eth0","network":"default"}, {"interfaceName":"eth1","network":"blue-network"}]'
labels:
component: proxy
spec:
containers:
- name: hello-app
image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
将清单应用于集群(确保您有一个名为“blue-network”的网络):
kubectl apply -f my-pod-ips.yaml
将永久性 IP 地址分配给 Deployment Pod
如需为 Deployment 中的最新 Pod 分配永久性 IP 地址,请应用具有以下配置的 GKEIPRoute:
将以下示例清单保存为 my-pod-ips.yaml:
kind: GKEIPRoute
apiVersion: networking.gke.io/v1
metadata:
namespace: proxy-deploy-ns
name: my-pod-ips
spec:
parentRefs:
- name: allowed-pod-ips
namespace: default
addresses:
- value: "34.123.10.1/32"
type: "gke.networking.io/cidr"
- value: "34.123.10.2/32"
type: "gke.networking.io/cidr"
network: blue-network # point to the right network if you intend to use persistent-ip on additional networks
reactionMode: ReadyCondition
podSelector:
matchLabels:
component: proxy
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: proxy-deploy-ns
name: proxy-deploy
spec:
selector:
matchLabels:
component: proxy
replicas: 4 # Latest Pod is used
template:
metadata:
# annotations: <- Remove these lines if the pods are not multi-nic pods
# networking.gke.io/default-interface: 'eth0'
# networking.gke.io/interfaces: '[{"interfaceName":"eth0","network":"default"}, {"interfaceName":"eth1","network":"blue-network"}]'
labels:
component: proxy
spec:
containers:
- name: hello-app
image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
将清单应用于集群:
kubectl apply -f my-ip-route.yaml
如果您使用其他网络,请确保您有一个名为“blue-network”的网络。
第 6 步:使用 Pod 中的永久性 IP 地址
使用 GKEIPRoute 向 GKE Pod 分配永久性 IP 地址并不会自动使这些 IP 地址可供应用使用。永久性 IP 地址在网络路由级别进行处理,但 Pod 的默认配置不清楚这一点。您必须配置应用的配置,以识别和使用 Pod 中的地址。为此,您的 Pod 需要特权权限。
如需配置应用,请考虑以下选项:
- net.ipv4.ip_nonlocal_bind:修改系统设置,以允许应用使用未直接分配给其接口的 IP 地址。
- ip address add:在应用的逻辑中使用此命令,将永久性 IP 地址手动添加到接口。
- 原始套接字:为了实现更多控制,您的应用可以直接与网络栈进行交互(高级)。
- 用户空间 IP 地址栈:在专门的场景中,一个单独的应用可能会在 Pod 中运行来管理 IP 地址(非常高级)。
第 7 步:为永久性 IP 地址启用 ARP(仅限默认网络)
如需生成有效的地址解析协议 (ARP) 请求和响应,并使用默认网络上的永久性 IP 地址与 Pod 建立新连接,您必须配置 arp_announce 变量。
如需设置 arp_announce 变量,请在 Pod 上运行以下命令:
echo "2" > /proc/sys/net/ipv4/conf/eth0/arp_announce
其中,arp_announce 变量用于控制 ARP 通知的处理方式。将其设置为“2”可确保为永久性 IP 地址发出 ARP 通知,从而使网络上的其他设备了解新的关联。
自定义 Pod 更改期间的永久性 IP 地址行为
本部分介绍在创建或删除目标 Pod 时,GKE Pod 的永久性 IP 地址的行为方式。GKE 控制器会监控您的 Pod 和 GKEIPRoute 配置。当检测到发生更新时,它会根据您选择的 reactionMode 自动将永久性 IP 地址重新分配给合适的 Pod。
了解永久性 IP 地址功能如何自动处理 Pod 更改以及您可以使用的配置选项:
- 确定
GKEIPRoute配置的 reactionMode 字段中是 ReadyCondition 还是 Exists。请考虑应用在分配 IP 地址的速度与严格就绪性要求方面的需求。 - 如果您使用
ReadyCondition来确保就绪性,请确保您的 Pod 已正确实现 Kubernetes 就绪性探测。否则,永久性 IP 地址可能无法按预期运行。 - 我们建议您监控 Pod 的状态和
GKEIPRoute对象的Conditions字段,以确保系统正常运行。Ready条件的true状态表示系统正常运行。
排查与 Pod 的永久性 IP 地址进行通信方面的问题
本部分介绍如何解决与 Pod 的永久性 IP 地址相关的问题。
NoPodsFound(如果找不到匹配的 Pod)
症状
GKEIPRoute 对象指定 podSelector(一组标签),以标识哪些 Pod 与永久性 IP 地址相关联。NoPodsFound 状态表示目标 GKEIPRoute's 命名空间中没有具有匹配标签的 Pod。
潜在原因
- 标签不正确:您打算对其使用永久性 IP 地址的 Pod 可能具有错误的标签,或者根本没有标签。
- Pod 不存在:如果
reactionMode == Exists,请通过检查pod.Spec.nodeName字段来检查 Pod 是否已分配给节点。GKEIPRoute's命名空间中可能没有任何与选择器匹配的 Pod 运行。 - Pod 未就绪:如果
reactionMode == ReadyCondition,请检查 Pod 状态是否为READY。即使存在匹配的 Pod,但如果其未处于Ready状态,它也无法处理流量,因此不会被选择。
解决方法
- 检查您的标签:核查
GKEIPRoute'spodSelector中的标签是否与您应用于预期 Pod 的标签相匹配。 - 验证 Pod 是否存在:确保具有正确标签的 Pod 实际存在于网关
Listeners所指定的GKEIPRoute's命名空间中。如果reactionMode == Exists,请通过检查pod.Spec.nodeName字段来检查 Pod 是否已分配给节点 确认 Pod 就绪性:如果
reactionMode == ReadyCondition,请检查 Pod 状态是否为READY。可使用以下命令确保 Pod 处于Ready状态:kubectl get pods -n <namespace>不会选择处于其他状态(例如“Pending”或“Error”)的 Pod。
配置 Pod,以响应分配的永久性 IP 地址。
Mutated(如果找到匹配的 Pod 并且永久性 IP 地址编程正在进行)
症状
GKEIPRoute 状态显示“Mutated”,表示匹配 Pod 的永久性 IP 地址配置正在进行中。
可能原因:
在配置期间,当系统为永久性 IP 地址设置 GKE 数据路径和 Google Cloud 资源时,预计会出现“Mutated”状态。
解决方法:
- 等待并重试:在大多数情况下,配置过程会在短时间内自动完成。等待后检查状态。成功后,状态会更改为
Ready。 - 进一步调查(如有必要):如果“Mutated”状态长时间持续存在,则可能表示存在配置错误。检查
GKEIPRoute上的其他状态条件:- Accepted:指示您的
GKEIPRoute设置是否有效。 - DPV2Ready:指示节点上的数据路径是否已正确编程。
- GCPReady:指示 Google Cloud 资源是否按预期设置。
- Accepted:指示您的
在这些条件下查找错误消息,以帮助排查问题。