Kubernetes IPv4/IPv6 雙協(xié)議棧

2022-05-07 09:08 更新

IPv4/IPv6 雙協(xié)議棧

FEATURE STATE: Kubernetes v1.23 [stable]

IPv4/IPv6 雙協(xié)議棧網(wǎng)絡(luò)能夠?qū)?nbsp;IPv4 和 IPv6 地址分配給 Pod 和 Service。

從 1.21 版本開(kāi)始,Kubernetes 集群默認(rèn)啟用 IPv4/IPv6 雙協(xié)議棧網(wǎng)絡(luò), 以支持同時(shí)分配 IPv4 和 IPv6 地址。

支持的功能 

Kubernetes 集群的 IPv4/IPv6 雙協(xié)議??商峁┫旅娴墓δ埽?/p>

  • 雙協(xié)議棧 pod 網(wǎng)絡(luò) (每個(gè) pod 分配一個(gè) IPv4 和 IPv6 地址)
  • IPv4 和 IPv6 啟用的服務(wù)
  • Pod 的集群外出口通過(guò) IPv4 和 IPv6 路由

先決條件 

為了使用 IPv4/IPv6 雙棧的 Kubernetes 集群,需要滿足以下先決條件:

  • Kubernetes 1.20 版本或更高版本,有關(guān)更早 Kubernetes 版本的使用雙棧服務(wù)的信息, 請(qǐng)參考對(duì)應(yīng)版本的 Kubernetes 文檔。
  • 提供商支持雙協(xié)議棧網(wǎng)絡(luò)(云提供商或其他提供商必須能夠?yàn)?nbsp;Kubernetes 節(jié)點(diǎn)提供可路由的 IPv4/IPv6 網(wǎng)絡(luò)接口)
  • 支持雙協(xié)議棧的網(wǎng)絡(luò)插件(如 Kubenet 或 Calico)

配置 IPv4/IPv6 雙協(xié)議棧

  • 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? 對(duì)于 IPv4 默認(rèn)為 /24,對(duì)于 IPv6 默認(rèn)為 /64
  • kube-proxy:
    • ?--cluster-cidr=<IPv4 CIDR>,<IPv6 CIDR>?
  • kubelet:
    • 當(dāng)沒(méi)有 ?--cloud-provider? 時(shí),管理員可以通過(guò) ?--node-ip? 來(lái)傳遞逗號(hào)分隔的 IP 地址, 為該節(jié)點(diǎn)手動(dòng)配置雙棧 ?.status.addresses?。 如果 Pod 以 HostNetwork 模式在該節(jié)點(diǎn)上運(yùn)行,則 Pod 會(huì)用 ?.status.podIPs? 字段來(lái)報(bào)告它的 IP 地址。 一個(gè)節(jié)點(diǎn)中的所有 ?podIP ?都會(huì)匹配該節(jié)點(diǎn)的由 ?.status.addresses? 字段定義的 IP 組。
IPv4 CIDR 的一個(gè)例子:?10.244.0.0/16?(盡管你會(huì)提供你自己的地址范圍)。
IPv6 CIDR 的一個(gè)例子:?fdXY:IJKL:MNOP:15::/64? (這里演示的是格式而非有效地址 - 請(qǐng)看 RFC 4193)。

服務(wù)

你可以使用 IPv4 或 IPv6 地址來(lái)創(chuàng)建 Service。 服務(wù)的地址族默認(rèn)為第一個(gè)服務(wù)集群 IP 范圍的地址族(通過(guò) kube-apiserver 的 ?--service-cluster-ip-range? 參數(shù)配置)。 當(dāng)你定義服務(wù)時(shí),可以選擇將其配置為雙棧。若要指定所需的行為,你可以設(shè)置 ?.spec.ipFamilyPolicy? 字段為以下值之一:

  • ?SingleStack?:?jiǎn)螚7?wù)??刂泼媸褂玫谝粋€(gè)配置的服務(wù)集群 IP 范圍為服務(wù)分配集群 IP。
  • ?PreferDualStack?:
    • 為服務(wù)分配 IPv4 和 IPv6 集群 IP 地址。
  • ?RequireDualStack?:從 IPv4 和 IPv6 的地址范圍分配服務(wù)的 ?.spec.ClusterIPs ?
    • 從基于在 ?.spec.ipFamilies? 數(shù)組中第一個(gè)元素的地址族的 ?.spec.ClusterIPs? 列表中選擇 ?.spec.ClusterIP ?

如果你想要定義哪個(gè) IP 族用于單?;蚨x雙棧 IP 族的順序,可以通過(guò)設(shè)置 服務(wù)上的可選字段 .spec.ipFamilies 來(lái)選擇地址族。

?.spec.ipFamilies? 字段是不可變的,因?yàn)橄到y(tǒng)無(wú)法為已經(jīng)存在的服務(wù)重新分配 ?.spec.ClusterIP?。如果你想改變 ?.spec.ipFamilies?,則需要?jiǎng)h除并重新創(chuàng)建服務(wù)。

你可以設(shè)置 ?.spec.ipFamily? 為以下任何數(shù)組值:

  • ?["IPv4"] ?
  • ?["IPv6"] ?
  • ?["IPv4","IPv6"] ?(雙棧)
  • ?["IPv6","IPv4"] ?(雙棧)

你所列出的第一個(gè)地址族用于原來(lái)的 ?.spec.ClusterIP? 字段。

雙棧服務(wù)配置場(chǎng)景

以下示例演示多種雙棧服務(wù)配置場(chǎng)景下的行為。

新服務(wù)的雙棧選項(xiàng)

  1. 此服務(wù)規(guī)約中沒(méi)有顯式設(shè)定 ?.spec.ipFamilyPolicy?。當(dāng)你創(chuàng)建此服務(wù)時(shí),Kubernetes 從所配置的第一個(gè) ?service-cluster-ip-range? 種為服務(wù)分配一個(gè)集群IP,并設(shè)置 ?.spec.ipFamilyPolicy? 為 ?SingleStack?。 (無(wú)選擇算符的服務(wù) 和無(wú)頭服務(wù)的行為方式 與此相同。)
  2. apiVersion: v1
    kind: Service
    metadata:
      name: my-service
      labels:
        app: MyApp
    spec:
      selector:
        app: MyApp
      ports:
        - protocol: TCP
          port: 80
    
            
  3. 此服務(wù)規(guī)約顯式地將 ?.spec.ipFamilyPolicy? 設(shè)置為 ?PreferDualStack?。 當(dāng)你在雙棧集群上創(chuàng)建此服務(wù)時(shí),Kubernetes 會(huì)為該服務(wù)分配 IPv4 和 IPv6 地址。 控制平面更新服務(wù)的 ?.spec? 以記錄 IP 地址分配。 字段 ?.spec.ClusterIPs? 是主要字段,包含兩個(gè)分配的 IP 地址;?.spec.ClusterIP? 是次要字段, 其取值從 ?.spec.ClusterIPs? 計(jì)算而來(lái)。
    • 對(duì)于 .spec.ClusterIP 字段,控制面記錄來(lái)自第一個(gè)服務(wù)集群 IP 范圍 對(duì)應(yīng)的地址族的 IP 地址。
    • 對(duì)于單協(xié)議棧的集群,.spec.ClusterIPs 和 .spec.ClusterIP 字段都 僅僅列出一個(gè)地址。
    • 對(duì)于啟用了雙協(xié)議棧的集群,將 .spec.ipFamilyPolicy 設(shè)置為 RequireDualStack 時(shí),其行為與 PreferDualStack 相同。
    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
      labels:
        app: MyApp
    spec:
      ipFamilyPolicy: PreferDualStack
      selector:
        app: MyApp
      ports:
        - protocol: TCP
          port: 80
    
  4. 下面的服務(wù)規(guī)約顯式地在 ?.spec.ipFamilies? 中指定 ?IPv6 ?和 ?IPv4?,并 將 ?.spec.ipFamilyPolicy? 設(shè)定為 ?PreferDualStack?。 當(dāng) Kubernetes 為 ?.spec.ClusterIPs? 分配一個(gè) IPv6 和一個(gè) IPv4 地址時(shí), ?.spec.ClusterIP? 被設(shè)置成 IPv6 地址,因?yàn)樗?nbsp;?.spec.ClusterIPs? 數(shù)組中的第一個(gè)元素, 覆蓋其默認(rèn)值。
  5. apiVersion: v1
    kind: Service
    metadata:
      name: my-service
      labels:
        app: MyApp
    spec:
      ipFamilyPolicy: PreferDualStack
      ipFamilies:
      - IPv6
      - IPv4
      selector:
        app: MyApp
      ports:
        - protocol: TCP
          port: 80
    
    
                    

現(xiàn)有服務(wù)的雙棧默認(rèn)值

下面示例演示了在服務(wù)已經(jīng)存在的集群上新啟用雙棧時(shí)的默認(rèn)行為。 (將現(xiàn)有集群升級(jí)到 1.21 或者更高版本會(huì)啟用雙協(xié)議棧支持。)

  1. 在集群上啟用雙棧時(shí),控制面會(huì)將現(xiàn)有服務(wù)(無(wú)論是 ?IPv4 ?還是 ?IPv6?)配置 ?.spec.ipFamilyPolicy? 為 ?SingleStack ?并設(shè)置? .spec.ipFamilies? 為服務(wù)的當(dāng)前地址族。
  2. apiVersion: v1
    kind: Service
    metadata:
      name: my-service
      labels:
        app: MyApp
    spec:
      selector:
        app: MyApp
      ports:
        - protocol: TCP
          port: 80
    

    你可以通過(guò)使用 kubectl 檢查現(xiàn)有服務(wù)來(lái)驗(yàn)證此行為。

    kubectl get svc my-service -o yaml
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: 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: MyApp
      type: ClusterIP
    status:
      loadBalancer: {}
    
  3. 在集群上啟用雙棧時(shí),帶有選擇算符的現(xiàn)有 無(wú)頭服務(wù) 由控制面設(shè)置 ?.spec.ipFamilyPolicy? 為 ?SingleStack ?并設(shè)置 ?.spec.ipFamilies? 為第一個(gè)服務(wù)集群 IP 范圍的地址族(通過(guò)配置 kube-apiserver 的 ?--service-cluster-ip-range? 參數(shù)),即使 ?.spec.ClusterIP? 的設(shè)置值為 ?None ?也如此。
  4. apiVersion: v1
    kind: Service
    metadata:
      name: my-service
      labels:
        app: MyApp
    spec:
      selector:
        app: MyApp
      ports:
        - protocol: TCP
          port: 80
    
    
            

    你可以通過(guò)使用 kubectl 檢查帶有選擇算符的現(xiàn)有無(wú)頭服務(wù)來(lái)驗(yàn)證此行為。

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

在單棧和雙棧之間切換服務(wù)

服務(wù)可以從單棧更改為雙棧,也可以從雙棧更改為單棧。

  1. 要將服務(wù)從單棧更改為雙棧,根據(jù)需要將 ?.spec.ipFamilyPolicy? 從 ?SingleStack ?改為 ?PreferDualStack ?或 ?RequireDualStack?。 當(dāng)你將此服務(wù)從單棧更改為雙棧時(shí),Kubernetes 將分配缺失的地址族,以便現(xiàn)在 該服務(wù)具有 IPv4 和 IPv6 地址。 編輯服務(wù)規(guī)約將 ?.spec.ipFamilyPolicy? 從 ?SingleStack ?改為 ?PreferDualStack?。
  2. 之前:

    spec:
      ipFamilyPolicy: SingleStack

    之后:

    spec:
      ipFamilyPolicy: PreferDualStack
  3. 要將服務(wù)從雙棧更改為單棧,請(qǐng)將 ?.spec.ipFamilyPolicy? 從 ?PreferDualStack ?或 ?RequireDualStack ?改為 ?SingleStack?。 當(dāng)你將此服務(wù)從雙棧更改為單棧時(shí),Kubernetes 只保留 ?.spec.ClusterIPs? 數(shù)組中的第一個(gè)元素,并設(shè)置 ?.spec.ClusterIP? 為那個(gè) IP 地址, 并設(shè)置 ?.spec.ipFamilies? 為 ?.spec.ClusterIPs? 地址族。

無(wú)選擇算符的無(wú)頭服務(wù)

對(duì)于不帶選擇算符的無(wú)頭服務(wù), 若沒(méi)有顯式設(shè)置 ?.spec.ipFamilyPolicy?,則 ?.spec.ipFamilyPolicy? 字段默認(rèn)設(shè)置為 ?RequireDualStack?。

LoadBalancer 類型服務(wù)

要為你的服務(wù)提供雙棧負(fù)載均衡器:

  • 將 ?.spec.type? 字段設(shè)置為 ?LoadBalancer ?
  • 將 ?.spec.ipFamilyPolicy? 字段設(shè)置為 ?PreferDualStack ?或者 ?RequireDualStack?

為了使用雙棧的負(fù)載均衡器類型服務(wù),你的云驅(qū)動(dòng)必須支持 IPv4 和 IPv6 的負(fù)載均衡器。

出站流量

如果你要啟用出站流量,以便使用非公開(kāi)路由 IPv6 地址的 Pod 到達(dá)集群外地址 (例如公網(wǎng)),則需要通過(guò)透明代理或 IP 偽裝等機(jī)制使 Pod 使用公共路由的 IPv6 地址。 ip-masq-agent項(xiàng)目 支持在雙棧集群上進(jìn)行 IP 偽裝。

確認(rèn)你的 CNI 驅(qū)動(dòng)支持 IPv6。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)