控制与 GKE Pod 上的永久性 IP 地址进行的通信


本页面介绍如何在 Google Kubernetes Engine (GKE) Pod 上实现永久性 IP 地址。您可以使用自定义永久性 IP 地址映射来控制 GKE Pod 网络。如需详细了解永久性 IP 地址、其应用场景和优势,请参阅 GKE Pod 的永久性 IP 地址简介

要求

  • GKE 1.29 版或更高版本。
  • 选择预留 Google 提供的 IP 地址(Google 提供的 IP 地址)或自备 IP 地址 (BYOIP)。
  • 配置在 Pod 中运行的应用,以识别和使用分配的永久性 IP 地址。
  • GKE Pod 的永久性 IP 地址需要启用了 GKE Dataplane V2 和多网络的集群。

限制

  • 默认网络不支持永久性 IP 地址。您必须在创建集群期间启用多网络。
  • 将应用配置为使用分配的永久性 IP 地址。GKE 不会自动将 IP 地址配置添加到 Pod 的网络接口。
  • 每个永久性 IP 地址一次可以与一个 Pod 相关联。如果您有多个 Pod 可用,GKE 通常会将流量发送到最新 Pod。但是,GKE 仅在最新 Pod 健康状况良好时才会执行此操作,这意味着 Pod 的 Ready 条件状态在默认情况下为 True。您可以使用 GKEIPRoute 上的 reactionMode 设置来配置此行为并进行更改。
  • GKE 仅支持将 IPv4 地址用作永久性 IP 地址。
  • GKE 仅支持将第 3 层或设备类型多网络用于永久性 IP 地址。

准备工作

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行 gcloud components update 以获取最新版本。

价格

只有启用了 GKE Enterprise 的项目中的集群支持以下 Network Function Optimizer (NFO) 功能:

如需了解启用 Google Kubernetes Engine (GKE) Enterprise 版本的相关费用,请参阅 GKE Enterprise 价格

为 GKE Pod 实现永久性 IP 地址

GKE 中的永久性 IP 地址提供了一种为 Pod 提供稳定网络身份的方法(即使 Pod 本身进行更新或四处移动也是如此)。

本部分总结了为 GKE Pod 实现永久性 IP 地址的工作流:

  1. 创建集群:创建启用了 Gateway API、GKE Dataplane V2 和多网络的集群。
  2. 预留 IP 地址:确定您需要外部(可公开访问)还是内部(仅限 Google Cloud)IP 地址并预留该地址。选择 GKE 集群所在的同一区域。
  3. 创建网关:配置 Kubernetes 网关对象,该对象用于保存预留的永久性 IP 地址,并使您可以创建有关集群中哪些 Pod 可以使用这些永久性 IP 地址的规则 (GKEIPRoutes)。
  4. 使用其他网络创建或标识工作负载以用于永久性 IP 地址:通过启用多个网络接口并定义永久性 IP 地址所在的网络,使 Pod 准备好使用永久性 IP 地址。
  5. 为所选工作负载创建 GKEIPRoute 对象:配置 GKEIPRoute 以将永久性 IP 地址分配给特定 Pod。您可以使用标签来确定正确的目标 Pod,并且可以选择性地配置路由如何响应 Pod 更改。
  6. 配置应用感知:在 Pod 中配置应用以主动使用永久性 IP 地址。
  7. 监控:跟踪网关和 GKEIPRoute 对象的状态,以确保一切按预期正常运行。

如需为 GKE Pod 实现永久性 IP 地址,请执行以下步骤:

第 1 步:创建启用了 GKE Dataplane V2 和多网络的 GKE 集群

如需启用在 GKE Pod 上实现永久性 IP 地址所需的高级网络路由和 IP 地址管理功能,您必须create启用了 GKE Dataplane V2 和多网络的集群。

第 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-3
  • REGION:此请求对应的区域。
  • 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 的方式,您会使用网关对象。

  1. 创建适当类的 Kubernetes 网关对象:
    • gke-persistent-regional-external-managed,用于外部(公共)IP 地址。
    • gke-persistent-regional-internal-managed,用于内部(仅限 Google Cloud)IP 地址。
  2. 在网关的地址部分中,列出此网关管理的永久性 IP 地址(Google 提供的 IP 地址或 BYOIP)。
  3. 使用 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/v1beta1
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 地址

设置多网络 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: blue-network
  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 选择)时,此功能的行为方式。此字段是可选字段,默认值为 ReadyConditionReadyCondition 字段不可更改。您可以设置 reactionMode 以控制在创建、删除或更新 Pod 时此功能的行为方式。
  • network:指向永久性 IP 地址路由到的 Pod 上的网络接口。该字段不可更改。

将清单应用于集群:

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
  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:
        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-ip-route.yaml

第 6 步:使用 Pod 中的永久性 IP 地址

使用 GKEIPRoute 向 GKE Pod 分配永久性 IP 地址并不会自动使这些 IP 地址可供应用使用。永久性 IP 地址在网络路由级别进行处理,但 Pod 的默认配置不清楚这一点。您必须配置应用的配置,以识别和使用 Pod 中的地址。为此,您的 Pod 需要特权权限。

如需配置应用,请考虑以下选项:

  1. net.ipv4.ip_nonlocal_bind:修改系统设置,以允许应用使用未直接分配给其接口的 IP 地址。
  2. ip address add:在应用的逻辑中使用此命令,将永久性 IP 地址手动添加到接口。
  3. 原始套接字:为了实现更多控制,您的应用可以直接与网络栈进行交互(高级)。
  4. 用户空间 IP 地址堆栈:在专门的场景中,一个单独的应用可能会在 Pod 中运行来管理 IP 地址(非常高级)。

自定义 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 状态,它也无法处理流量,因此不会被选择。

解决方法

  1. 检查您的标签:核查 GKEIPRoute's podSelector 中的标签是否与您应用于预期 Pod 的标签相匹配。
  2. 验证 Pod 是否存在:确保具有正确标签的 Pod 实际存在于网关 Listeners 所指定的 GKEIPRoute's 命名空间中。如果 reactionMode == Exists,请通过检查 pod.Spec.nodeName 字段来检查 Pod 是否已分配给节点
  3. 确认 Pod 就绪性:如果 reactionMode == ReadyCondition,请检查 Pod 状态是否为 READY。可使用以下命令确保 Pod 处于 Ready 状态:

    kubectl get pods -n <namespace>
    

    不会选择处于其他状态(例如“Pending”或“Error”)的 Pod。

  4. 配置 Pod,以响应分配的永久性 IP 地址。

Mutated(如果找到匹配的 Pod 并且永久性 IP 地址编程正在进行)

症状

GKEIPRoute 状态显示“Mutated”,表示匹配 Pod 的永久性 IP 地址配置正在进行中。

可能原因

在配置期间,当系统为永久性 IP 地址设置 GKE 数据路径和 Google Cloud 资源时,预计会出现“Mutated”状态。

解决方法

  1. 等待并重试:在大多数情况下,配置过程会在短时间内自动完成。等待后检查状态。成功后,状态会更改为 Ready
  2. 进一步调查(如有必要):如果“Mutated”状态长时间持续存在,则可能表示存在配置错误。检查 GKEIPRoute 上的其他状态条件:
    • Accepted:指示您的 GKEIPRoute 设置是否有效。
    • DPV2Ready:指示节点上的数据路径是否已正确编程。
    • GCPReady:指示 Google Cloud 资源是否按预期设置。

在这些条件下查找错误消息,以帮助排查问题。

后续步骤