IPv4/IPv6 雙堆疊

Kubernetes 允許您設定單堆疊 IPv4 網路、單堆疊 IPv6 網路,或是同時啟用兩種網路家族的雙堆疊網路。本頁面說明其作法。
功能狀態: Kubernetes v1.23 [穩定]

IPv4/IPv6 雙堆疊網路功能允許將 IPv4 和 IPv6 位址分配給 PodService

從 1.21 版本開始,您的 Kubernetes 叢集預設啟用 IPv4/IPv6 雙堆疊網路,允許同時分配 IPv4 和 IPv6 位址。

支援的特性

Kubernetes 叢集上的 IPv4/IPv6 雙堆疊提供以下功能:

  • 雙堆疊 Pod 網路(每個 Pod 分配一個 IPv4 和一個 IPv6 位址)
  • 支援 IPv4 和 IPv6 的 Service
  • 透過 IPv4 和 IPv6 介面進行 Pod 叢集外流出路由(例如存取網際網路)

先決條件

使用 IPv4/IPv6 雙堆疊 Kubernetes 叢集需要滿足以下先決條件:

  • Kubernetes 1.20 或更高版本

    有關在較早的 Kubernetes 版本中使用雙堆疊服務的資訊,請參閱該版本的 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。)

注意

IPv4 CIDR 範例:10.244.0.0/16(您應使用自己的位址範圍)

IPv6 CIDR 範例:fdXY:IJKL:MNOP:15::/64(此處僅顯示格式,並非有效位址 - 請參閱 RFC 4193

服務

您可以建立可使用 IPv4、IPv6 或兩者皆使用的Service

Service 的位址家族預設為第一個服務叢集 IP 範圍的位址家族(透過 kube-apiserver 的 --service-cluster-ip-range 旗標進行設定)。

定義 Service 時,您可以選擇將其設定為雙堆疊。若要指定所需的行為,請將 .spec.ipFamilyPolicy 欄位設為下列其中一個值:

  • SingleStack:單堆疊服務。控制平面會使用第一個設定的服務叢集 IP 範圍為該 Service 分配一個叢集 IP。
  • PreferDualStack:當啟用雙堆疊時,為該 Service 分配 IPv4 和 IPv6 叢集 IP。如果未啟用或不支援雙堆疊,則回退到單堆疊行為。
  • RequireDualStack:當啟用雙堆疊時,從 IPv4 和 IPv6 位址範圍中分配 Service 的 .spec.clusterIPs。如果未啟用或不支援雙堆疊,則 Service API 物件建立會失敗。
    • 根據 .spec.ipFamilies 陣列中第一個元素的位址家族,從 .spec.clusterIPs 列表中選取 .spec.clusterIP

如果您想定義單堆疊使用的 IP 家族,或是定義雙堆疊的 IP 家族順序,可以透過設定 Service 上的選用欄位 .spec.ipFamilies 來選擇位址家族。

注意

.spec.ipFamilies 欄位是有條件可變更的:您可以新增或移除次要 IP 位址家族,但不能變更現有 Service 的主要 IP 位址家族。

您可以將 .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 和具有選取器的 headless 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 規格明確在 .spec.ipFamilyPolicy 中定義了 PreferDualStack。當您在雙堆疊叢集上建立此 Service 時,Kubernetes 會為該服務指派 IPv4 和 IPv6 位址。控制平面會更新 Service 的 .spec 以記錄 IP 位址分配。.spec.clusterIPs 欄位是主要欄位,包含兩個分配的 IP 位址;.spec.clusterIP 是次要欄位,其值由 .spec.clusterIPs 計算得出。

    • 對於 .spec.clusterIP 欄位,控制平面會記錄與第一個服務叢集 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 規格在 .spec.ipFamilies 中明確定義了 IPv6IPv4,並在 .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 檢查現有的服務來驗證此行為。

    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. 當叢集啟用雙堆疊時,即使 .spec.clusterIP 設定為 None,具有選取器的現有 headless Service 也會被控制平面配置為將 .spec.ipFamilyPolicy 設定為 SingleStack,並將 .spec.ipFamilies 設定為第一個服務叢集 IP 範圍的位址家族(透過 kube-apiserver 的 --service-cluster-ip-range 旗標進行設定)。

    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 檢查具有選取器的現有 headless 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 的位址家族。

無選取器 (Selector) 的 Headless Service

對於無選取器的 Headless Service 且未明確設定 .spec.ipFamilyPolicy 的情況,.spec.ipFamilyPolicy 欄位預設為 RequireDualStack

LoadBalancer 類型的 Service

若要為您的 Service 配置雙堆疊負載平衡器:

  • .spec.type 欄位設為 LoadBalancer
  • .spec.ipFamilyPolicy 欄位設為 PreferDualStackRequireDualStack

注意

若要使用雙堆疊 LoadBalancer 類型的 Service,您的雲端供應商必須支援 IPv4 和 IPv6 負載平衡器。

流出 (Egress) 流量

如果您想啟用流出流量,以便從使用非公開可路由 IPv6 位址的 Pod 到達叢集外目的地(例如公用網際網路),您需要透過透明代理 (transparent proxying) 或 IP 偽裝 (IP masquerading) 等機制,讓 Pod 能夠使用公開路由的 IPv6 位址。ip-masq-agent 專案支援在雙堆疊叢集上進行 IP 偽裝。

注意

確保您的 CNI 供應商支援 IPv6。

Windows 支援

Windows 上的 Kubernetes 不支援單堆疊「僅 IPv6」網路。但是,支援用於 Pod 和節點的雙堆疊 IPv4/IPv6 網路,但服務仍採用單一家族。

您可以在 l2bridge 網路中使用 IPv4/IPv6 雙堆疊網路。

注意

Windows 上的覆蓋 (Overlay, VXLAN) 網路支援雙堆疊網路。

您可以在Windows 網路主題中閱讀更多關於 Windows 不同網路模式的資訊。

接下來


最後修改於 2024 年 6 月 12 日上午 10:06 (PST):修正 IPv4/IPv6 雙堆疊中的參考 (5ead326713)