排查 VPC 集群中的 IP 地址管理问题


本部分介绍了如何解决 VPC 原生集群的相关问题。 您还可以查看 GKE IP 地址利用率数据分析

默认网络资源尚未就绪

表现

您会收到类似于以下内容的错误消息:

projects/[PROJECT_NAME]/regions/XXX/subnetworks/default
潜在原因

同一子网上存在并行操作。例如,正在创建其他 VPC 原生集群,或正在子网上添加或删除次要范围。

解决方法

重试此命令。

IPCidrRange 值无效

表现

您会收到类似于以下内容的错误消息:

resource.secondaryIpRanges[1].ipCidrRange': 'XXX'. Invalid IPCidrRange: XXX conflicts with existing subnetwork 'default' in region 'XXX'
潜在原因

正在同时创建其他 VPC 原生集群,且该集群正尝试在同一 VPC 网络中分配相同的范围。

正在向同一 VPC 网络中的子网添加相同的次要范围。

解决方法

如果您没有指定任何次要范围,并且在创建集群时收到该错误,请重试集群创建命令。

Pod 没有足够的可用 IP 地址空间

表现

集群在较长时间内处于预配状态。

集群创建返回托管式实例组 (MIG) 错误。

向集群添加一个或多个节点时,系统会显示以下错误:

[IP_SPACE_EXHAUSTED] Instance 'INSTANCE_NAME' creation failed: IP space of 'projects/PROJECT_ID/regions/REGION/subnetworks/SUBNET_NAME-SECONDARY_RANGE_NAME' is exhausted.
潜在原因

节点 IP 地址用尽:分配给集群的子网的主要 IP 地址范围用尽可用的 IP 地址。这通常发生在扩缩节点池或创建大型集群时。

Pod IP 地址用尽:分配给集群的 Pod CIDR 范围已满。当 Pod 数量超过 Pod CIDR 的容量时,就会发生这种情况,尤其是在每个节点的 Pod 密度较高或部署规模较大时。

特定子网命名惯例:子网在错误消息中命名的方式可以帮助您确定问题是出在节点 IP 地址范围(节点本身获取其 IP 地址的位置)还是 Pod IP 地址范围(Pod 内的容器获取其 IP 地址的位置)。

次要范围用尽 (Autopilot):在 Autopilot 集群中,由于扩缩或 Pod 密度较高,为 Pod IP 地址分配的次要范围用尽。

解决方案

收集有关集群的以下信息:名称、控制平面版本、操作模式、关联的 VPC 名称、子网名称和 CIDR。此外,请注意默认的 Pod IPv4 地址范围和任何其他集群 Pod IPv4 地址范围(包括名称和 CIDR)、是否启用了 VPC 原生流量路由,以及在集群和节点池级别(如果适用)设置的每节点 Pod 数量上限。请注意所有受影响的节点池及其特定 IPv4 Pod IP 地址范围和每个节点的最大 Pod 配置(如果与集群级设置不同)。此外,请在节点池配置中记录每个节点的 Pod 数量上限的默认配置和自定义配置(如果有)。

确认 IP 地址用尽问题

  • Network Intelligence Center:在 GKE 集群的 Network Intelligence Center 中检查 Pod IP 地址范围内的 IP 地址分配率是否较高。

    如果您发现 Network Intelligence Center 内的 Pod 范围的 IP 地址分配率较高,则表示您的 Pod IP 地址范围已用完。

    如果 Pod IP 地址范围显示正常的分配率,但您仍然遇到 IP 地址用尽的问题,则很可能是节点 IP 地址范围用尽。

  • 审核日志:检查 IP_SPACE_EXHAUSTED 条目中的 resourceName 字段,并将其与子网名称或次要 Pod IP 地址范围名称进行比较。

  • 检查用尽的 IP 地址范围是节点 IP 地址范围还是 Pod IP 地址范围。

    如需验证已用完的 IP 地址范围是节点 IP 地址范围还是 Pod IP 地址范围,请检查 IP_SPACE_EXHAUSTED 日志条目 ipSpaceExhausted 部分中的 resourceName 值是否与受影响的 GKE 集群中使用的 Pod 的子网名称或次要 IPv4 地址范围的名称相关联。

    如果 resourceName 的值采用“[Subnet_name]”格式,则表示节点 IP 地址范围已用完。如果 resourceName 的值采用“[Subnet_name]-[Name_of_Secondary_IPv4_range_for_pods]-[HASH_8BYTES]”的格式,则表示 Pod IP 地址范围已用完。

解决 Pod IP 地址用尽问题:

  • 调整现有 Pod CIDR 的大小:增加当前 Pod IP 地址范围的大小。您可以使用连续的多 Pod CIDR 向集群添加 Pod IP 地址范围。
  • 创建其他子网:向集群添加具有专用 Pod CIDR 的子网。

减少每个节点的 Pod 数量以释放 IP 地址:

解决节点 IP 地址用尽的问题:

  • 查看 IP 地址规划:确保节点 IP 地址范围符合您的扩缩要求。
  • 创建新集群(如有必要):如果节点 IP 地址范围受到严重限制,请创建具有适当 IP 地址范围大小的替换集群。请参阅 VCP 原生集群的 IP 范围IP 范围规划

使用 gcpdiag 调试 IP 地址用尽问题

gcpdiag 是一种开源工具,不是由官方提供支持的 Google Cloud 产品。您可以使用 gcpdiag 工具来帮助识别和修复 Google Cloud 项目问题。如需了解详情,请参阅 GitHub 上的 gcpdiag 项目

如需检查 Autopilot 和标准 GKE 集群的 IP 地址耗尽原因,请考虑以下因素:
  • 集群状态:在报告 IP 地址用尽时检查集群状态。
  • 网络分析器:查询 Stackdriver 日志以获取网络分析器日志,以确认是否存在 Pod 或节点 IP 地址耗尽的情况。
  • 集群类型:检查集群类型,并根据集群类型提供相关建议。

Google Cloud 控制台

  1. 完成然后复制以下命令。
  2. gcpdiag runbook gke/ip-exhaustion --project=PROJECT_ID \
        --parameter name=CLUSTER_NAME \
        --parameter location=ZONE|REGION \
        --parameter start_time=yyyy-mm-ddThh:mm:ssZ \
        --parameter end_time=yyyy-mm-ddThh:mm:ssZ \
  3. 打开 Google Cloud 控制台并激活 Cloud Shell。
  4. 打开 Cloud 控制台
  5. 粘贴复制的命令。
  6. 运行 gcpdiag 命令以下载 gcpdiag Docker 映像,然后执行诊断检查。如果适用,请按照输出说明修复失败的检查。

Docker

您可以使用封装容器运行 gcpdiag,以在 Docker 容器中启动 gcpdiag。必须安装 Docker 或 Podman

  1. 在本地工作站上复制并运行以下命令。
    curl https://gcpdiag.dev/gcpdiag.sh >gcpdiag && chmod +x gcpdiag
  2. 执行 gcpdiag 命令:
    ./gcpdiag runbook gke/ip-exhaustion --project=PROJECT_ID \
        --parameter name=CLUSTER_NAME \
        --parameter location=ZONE|REGION \
        --parameter start_time=yyyy-mm-ddThh:mm:ssZ \
        --parameter end_time=yyyy-mm-ddThh:mm:ssZ \

查看此 Runbook 的可用参数

替换以下内容:

  • PROJECT_ID:资源所在项目的 ID
  • CLUSTER_NAME:项目中目标 GKE 集群的名称。
  • LOCATION:集群所在的可用区或区域。
  • start_time:问题开始的时间。
  • end_time:问题结束的时间。如果问题仍然存在,请设置当前时间。

实用标志:

  • --projectPROJECT_ID
  • --universe-domain:如果适用,则为托管资源的可信合作伙伴主权云网域
  • --parameter-p:Runbook 参数

如需查看所有 gcpdiag 工具标志的列表和说明,请参阅 gcpdiag 使用说明

确认是否已停用默认 SNAT

使用以下命令检查默认 SNAT 的状态:

gcloud container clusters describe CLUSTER_NAME

CLUSTER_NAME 替换为您的集群名称。

输出内容类似如下:

networkConfig:
  disableDefaultSnat: true
  network: ...

无法在没有 --enable-ip-alias 的情况下使用 --disable-default-snat

此错误消息和“must disable default sNAT (--disable-default-snat) before using public IP address privately in the cluster”表示您应在创建集群时明确设置 --disable-default-snat 标志,因为您是在专用集群中使用公共 IP 地址。

如果您看到类似“cannot disable default sNAT ...”的错误消息,则表示无法在集群中停用默认 SNAT。如需解决此问题,请检查您的集群配置。

在停用默认 SNAT 的情况下调试 Cloud NAT

如果您使用 --disable-default-snat 标志创建了一个专用集群,并且为 Cloud NAT 设置了互联网访问,但没有看到来自 Pod 的互联网绑定流量,请确保 Pod 范围包含在 Cloud NAT 配置中。

如果 Pod 到 Pod 的通信存在问题,请检查节点的 iptables 规则以验证 Pod 范围是否未被 iptables 规则伪装。

如需了解详情,请参阅 GKE IP 伪装文档

如果您尚未为集群配置 IP 伪装代理,GKE 会自动确保 Pod 到 Pod 的通信未被伪装。但是,如果配置了 IP 伪装代理,则该代理将替换默认的 IP 伪装规则。验证是否在 IP 伪装代理中配置了其他规则,以忽略对 Pod 范围的伪装。

双栈集群网络通信未按预期工作

潜在原因
GKE 集群创建的防火墙规则不包含分配的 IPv6 地址。
解决方法
您可以按照以下步骤验证防火墙规则
  1. 验证防火墙规则内容:

    gcloud compute firewall-rules describe FIREWALL_RULE_NAME
    

    请将 FIREWALL_RULE_NAME 替换为防火墙规则的名称。

    每个双栈集群都会创建一条防火墙规则,以允许节点和 Pod 互相通信。防火墙规则内容如下所示:

    allowed:
    - IPProtocol: esp
    - IPProtocol: ah
    - IPProtocol: sctp
    - IPProtocol: tcp
    - IPProtocol: udp
    - IPProtocol: '58'
    creationTimestamp: '2021-08-16T22:20:14.747-07:00'
    description: ''
    direction: INGRESS
    disabled: false
    enableLogging: false
    id: '7326842601032055265'
    kind: compute#firewall
    logConfig:
      enable: false
    name: gke-ipv6-4-3d8e9c78-ipv6-all
    network: https://www.googleapis.com/compute/alpha/projects/my-project/global/networks/alphanet
    priority: 1000
    selfLink: https://www.googleapis.com/compute/alpha/projects/my-project/global/firewalls/gke-ipv6-4-3d8e9c78-ipv6-all
    selfLinkWithId: https://www.googleapis.com/compute/alpha/projects/my-project/global/firewalls/7326842601032055265
    sourceRanges:
    - 2600:1900:4120:fabf::/64
    targetTags:
    - gke-ipv6-4-3d8e9c78-node
    

    sourceRanges 值必须与 subnetIpv6CidrBlock 相同。targetTags 值必须与 GKE 节点上的标记相同。如需解决此问题,请使用集群 ipAllocationPolicy信息更新防火墙规则

Private Service Connect 端点可能会在删除集群期间泄露

表现

您无法在基于 Private Service Connect 的集群中看到 Private Service Connect 下的已连接端点。

您无法删除 Private Service Connect 分配的端点所在的子网或 VPC 网络。系统会显示类似以下内容的错误消息:

projects/<PROJECT_ID>/regions/<REGION>/subnetworks/<SUBNET_NAME> is already being used by projects/<PROJECT_ID>/regions/<REGION>/addresses/gk3-<ID>
潜在原因

在使用 Private Service Connect 的 GKE 集群上,GKE 会通过转发规则部署 Private Service Connect 端点,该转发规则会分配一个内部 IP 地址,以便在控制平面的网络中访问集群的控制平面。为了通过使用 Private Service Connect 保护控制平面与节点之间的通信,GKE 会使端点不可见,您无法在 Google Cloud 控制台或 gcloud CLI 中看到该端点。

解决方法

为防止在集群删除之前泄露 Private Service Connect 端点,请完成以下步骤:

  1. Kubernetes Engine Service Agent role 分配给 GKE 服务账号。
  2. 确保 compute.forwardingRules.*compute.addresses.* 权限未被 GKE 服务账号明确拒绝。

如果您发现 Private Service Connect 端点泄露,请与支持团队联系

后续步骤

  • 如需了解诊断 Kubernetes DNS 问题的一般信息,请参阅调试 DNS 解析