IPv4/IPv6 双协议栈

Kubernetes 允许您配置单栈 IPv4 网络、单栈 IPv6 网络或双栈网络,同时激活两种网络族。本页对此进行了说明。
功能状态: Kubernetes v1.23 [稳定]

IPv4/IPv6 双栈网络使能够为 PodService 分配 IPv4 和 IPv6 地址。

从 1.21 版本开始,Kubernetes 集群默认启用 IPv4/IPv6 双栈网络,允许同时分配 IPv4 和 IPv6 地址。

支持的特性

Kubernetes 集群上的 IPv4/IPv6 双栈网络提供以下特性

  • 双栈 Pod 网络(每个 Pod 分配一个 IPv4 和 IPv6 地址)
  • 启用 IPv4 和 IPv6 的 Service
  • Pod 越出集群的路由(例如,互联网)通过 IPv4 和 IPv6 接口

先决条件

为了使用 IPv4/IPv6 双栈 Kubernetes 集群,需要以下先决条件

  • Kubernetes 1.20 或更高版本

    有关在早期 Kubernetes 版本中使用双栈 Service 的信息,请参阅该 Kubernetes 版本的文档。

  • 提供程序对双栈网络的支持(云提供程序或其他必须能够为 Kubernetes 节点提供可路由的 IPv4/IPv6 网络接口)

  • 支持双栈网络的 网络插件

配置 IPv4/IPv6 双栈

要配置 IPv4/IPv6 双栈,请设置双栈集群网络分配

  • kube-apiserver
    • --service-cluster-ip-range=<IPv4 CIDR>,<IPv6 CIDR>
  • kube-controller-manager
    • --cluster-cidr=<IPv4 CIDR>,<IPv6 CIDR>
    • --service-cluster-ip-range=<IPv4 CIDR>,<IPv6 CIDR>
    • --node-cidr-mask-size-ipv4|--node-cidr-mask-size-ipv6 默认为 IPv4 的 /24 和 IPv6 的 /64
  • kube-proxy
    • --cluster-cidr=<IPv4 CIDR>,<IPv6 CIDR>
  • kubelet
    • --node-ip=<IPv4 IP>,<IPv6 IP>
      • 此选项对于裸机双栈节点是必需的(不定义带有 --cloud-provider 标志的云提供程序的节点)。如果您正在使用云提供程序并选择覆盖云提供程序选择的节点 IP,请设置 --node-ip 选项。
      • (遗留内置云提供程序不支持双栈 --node-ip。)

服务

您可以创建 Service,这些 Service 可以使用 IPv4、IPv6 或两者。

Service 的地址族默认为第一个 Service 集群 IP 范围的地址族(通过 kube-apiserver 的 --service-cluster-ip-range 标志配置)。

当您定义 Service 时,您可以选择将其配置为双栈。要指定您想要的行为,您可以将 .spec.ipFamilyPolicy 字段设置为以下值之一

  • SingleStack:单栈 Service。控制平面为 Service 分配一个集群 IP,使用第一个配置的 Service 集群 IP 范围。
  • PreferDualStack:在启用双栈时,为 Service 分配 IPv4 和 IPv6 集群 IP。如果未启用或不支持双栈,则回退到单栈行为。
  • RequireDualStack:在启用双栈时,将 Service .spec.clusterIPs 从 IPv4 和 IPv6 地址范围分配。如果未启用或不支持双栈,则 Service API 对象创建将失败。
    • 根据 .spec.ipFamilies 数组中第一个元素的地址族,从 .spec.clusterIPs 列表中选择 .spec.clusterIP

如果您想定义用于单栈的 IP 族或定义双栈的 IP 族顺序,您可以选择通过设置 Service 上的可选字段 .spec.ipFamilies 来选择地址族。

您可以将 .spec.ipFamilies 设置为以下数组值之一

  • ["IPv4"]
  • ["IPv6"]
  • ["IPv4","IPv6"](双栈)
  • ["IPv6","IPv4"](双栈)

您列出的第一个族用于遗留的 .spec.clusterIP 字段。

双栈 Service 配置场景

这些示例演示了各种双栈 Service 配置场景的行为。

新 Service 上的双栈选项

  1. 此 Service 规范未显式定义 .spec.ipFamilyPolicy。当您创建此 Service 时,Kubernetes 从第一个配置的 service-cluster-ip-range 为 Service 分配一个集群 IP,并将 .spec.ipFamilyPolicy 设置为 SingleStack。(没有选择器的 Service无头 Service 带有选择器将以相同的方式运行。)

    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
      labels:
        app.kubernetes.io/name: MyApp
    spec:
      selector:
        app.kubernetes.io/name: MyApp
      ports:
        - protocol: TCP
          port: 80
    
  2. 此 Service 规范显式定义 PreferDualStack.spec.ipFamilyPolicy 中。当您在双栈集群上创建此 Service 时,Kubernetes 为该 Service 分配 IPv4 和 IPv6 地址。控制平面更新 Service 的 .spec 以记录 IP 地址分配。字段 .spec.clusterIPs 是主要字段,包含两个分配的 IP 地址;.spec.clusterIP 是一个辅助字段,其值从 .spec.clusterIPs 计算得出。

    • 对于 .spec.clusterIP 字段,控制平面记录与第一个 Service 集群 IP 范围相同的地址族的 IP 地址。
    • 在单栈集群上,.spec.clusterIPs.spec.clusterIP 字段仅列出一个地址。
    • 在启用双栈的集群上,在 .spec.ipFamilyPolicy 中指定 RequireDualStack 的行为与 PreferDualStack 相同。
    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
      labels:
        app.kubernetes.io/name: MyApp
    spec:
      ipFamilyPolicy: PreferDualStack
      selector:
        app.kubernetes.io/name: MyApp
      ports:
        - protocol: TCP
          port: 80
    
  3. 此 Service 规范显式定义 IPv6IPv4.spec.ipFamilies 中以及在 .spec.ipFamilyPolicy 中定义 PreferDualStack。当 Kubernetes 在 .spec.clusterIPs 中分配 IPv6 和 IPv4 地址时,.spec.clusterIP 设置为 IPv6 地址,因为它是 .spec.clusterIPs 数组中的第一个元素,从而覆盖默认值。

    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
      labels:
        app.kubernetes.io/name: MyApp
    spec:
      ipFamilyPolicy: PreferDualStack
      ipFamilies:
      - IPv6
      - IPv4
      selector:
        app.kubernetes.io/name: MyApp
      ports:
        - protocol: TCP
          port: 80
    

现有 Service 上的双栈默认值

这些示例演示了在新集群上启用双栈时现有 Service 的默认行为。(将现有集群升级到 1.21 或更高版本将启用双栈。)

  1. 当双栈在集群上启用时,现有的 Service(无论是 IPv4 还是 IPv6)都由控制平面配置为将 .spec.ipFamilyPolicy 设置为 SingleStack 并将 .spec.ipFamilies 设置为现有 Service 的地址族。现有的 Service 集群 IP 将存储在 .spec.clusterIPs 中。

    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
      labels:
        app.kubernetes.io/name: MyApp
    spec:
      selector:
        app.kubernetes.io/name: MyApp
      ports:
        - protocol: TCP
          port: 80
    

    您可以使用 kubectl 检查现有 Service 来验证此行为。

    kubectl get svc my-service -o yaml
    
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app.kubernetes.io/name: MyApp
      name: my-service
    spec:
      clusterIP: 10.0.197.123
      clusterIPs:
      - 10.0.197.123
      ipFamilies:
      - IPv4
      ipFamilyPolicy: SingleStack
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        app.kubernetes.io/name: MyApp
      type: ClusterIP
    status:
      loadBalancer: {}
    
  2. 当双栈在集群上启用时,现有的 无头 Service 带有选择器由控制平面配置为将 .spec.ipFamilyPolicy 设置为 SingleStack 并将 .spec.ipFamilies 设置为第一个 Service 集群 IP 范围的地址族(通过 kube-apiserver 的 --service-cluster-ip-range 标志配置),即使 .spec.clusterIP 设置为 None

    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
      labels:
        app.kubernetes.io/name: MyApp
    spec:
      selector:
        app.kubernetes.io/name: MyApp
      ports:
        - protocol: TCP
          port: 80
    

    您可以使用 kubectl 检查现有的带有选择器的无头 Service 来验证此行为。

    kubectl get svc my-service -o yaml
    
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app.kubernetes.io/name: MyApp
      name: my-service
    spec:
      clusterIP: None
      clusterIPs:
      - None
      ipFamilies:
      - IPv4
      ipFamilyPolicy: SingleStack
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        app.kubernetes.io/name: MyApp
    

在单栈和双栈 Service 之间切换

Service 可以在单栈和双栈之间更改。

  1. 要将 Service 从单栈更改为双栈,请将 .spec.ipFamilyPolicySingleStack 更改为 PreferDualStackRequireDualStack,如您所愿。当您将此 Service 从单栈更改为双栈时,Kubernetes 分配缺少的地址族,以便该 Service 现在具有 IPv4 和 IPv6 地址。

    编辑 Service 规范,将 .spec.ipFamilyPolicySingleStack 更新为 PreferDualStack

    之前

    spec:
      ipFamilyPolicy: SingleStack
    

    之后

    spec:
      ipFamilyPolicy: PreferDualStack
    
  2. 要将 Service 从双栈更改为单栈,请将 .spec.ipFamilyPolicyPreferDualStackRequireDualStack 更改为 SingleStack。当您将此 Service 从双栈更改为单栈时,Kubernetes 将仅保留 .spec.clusterIPs 数组中的第一个元素,并将 .spec.clusterIP 设置为该 IP 地址,并将 .spec.ipFamilies 设置为 .spec.clusterIPs 的地址族。

无选择器的 Headless Services

对于 无选择器的 Headless Services 且未显式设置 .spec.ipFamilyPolicy 时,.spec.ipFamilyPolicy 字段默认为 RequireDualStack

Service 类型 LoadBalancer

为您的 Service 配置双栈负载均衡器

  • .spec.type 字段设置为 LoadBalancer
  • .spec.ipFamilyPolicy 字段设置为 PreferDualStackRequireDualStack

出口流量

如果您希望启用出口流量,以便从使用非公共可路由 IPv6 地址的 Pod 访问集群外部的目标地址(例如,公共互联网),您需要启用 Pod 使用通过透明代理或 IP 伪装等机制的公共路由 IPv6 地址。 ip-masq-agent 项目支持双栈集群上的 IP 伪装。

Windows 支持

Windows 上的 Kubernetes 不支持单栈“仅 IPv6”网络。但是,支持具有单族服务的 Pod 和节点的双栈 IPv4/IPv6 网络。

您可以使用 IPv4/IPv6 双栈网络与 l2bridge 网络。

您可以在 Windows 上的网络 主题中了解有关 Windows 不同网络模式的更多信息。

接下来

最后修改时间 2024 年 6 月 12 日上午 10:06 PST:修复 IPv4/IPv6 双栈中的引用 (5ead326713)