設定輸出的網路位址轉譯 (NAT) 閘道

Google Distributed Cloud 的 egress NAT 閘道可讓您為叢集的傳出流量指派永久、確定的 SNAT IP 位址。有了可預測的來源位址,外部網路就能套用以 IP 為基礎的安全措施,例如許可清單政策。輸出 NAT 閘道是以 Dataplane V2 為基礎建構的進階網路功能。

輸出 NAT 閘道的運作方式

輸出 NAT 閘道是使用兩項自訂資源啟用。對於特定命名空間,NetworkGatewayGroup 自訂資源會指定浮動 IP 位址,這些位址可在選擇做為閘道的節點網路介面上設定。EgressNatPolicy 自訂資源可讓您指定輸出路由政策,控管輸出閘道的流量。

如果您未設定輸出 NAT 閘道,或輸出流量不符合流量選取規則,則從特定 Pod 傳送至叢集外部目的地的輸出流量,會偽裝成 Pod 執行所在節點的 IP 位址。在這種情況下,無法保證特定 Pod 的所有輸出流量都會有相同的來源 IP 位址,或會偽裝成相同的節點 IP 位址。

輸出流量選取邏輯是以命名空間選取器、Pod 選取器,以及一組以 CIDR 區塊標記法表示的目的地 IP 位址範圍為基礎。為說明輸出 NAT 閘道的運作方式,請考慮封包從 Pod 傳送至外部消費者的流程,以及對應的回應。假設節點子網路的 IP 位址位於 192.168.1.0/24 CIDR 區塊。

下圖顯示透過閘道節點傳送輸出流量的網路架構。

Google Distributed Cloud 的輸出 NAT 閘道圖

透過 egress NAT 閘道的封包流程可能如下所示:

  1. 輸出流量是由 IP 位址為 10.10.10.1 的 Pod 產生,該 Pod 位於 IP 位址為 192.168.1.1 的節點中。

    流量的目的地位址是叢集外的端點。

  2. 如果流量符合輸出規則,eBPF 程式會將輸出流量轉送至閘道節點,而非直接使用節點 IP 位址進行偽裝。

  3. 閘道節點會接收輸出流量。

  4. 閘道節點會將原始流量的來源 IP 位址 10.10.10.1 偽裝成 EgressNATPolicy 自訂資源中指定的來源輸出 IP 位址 192.168.1.100。

  5. 回傳流量會傳回閘道節點,目的地為 192.168.1.100。

  6. 閘道節點會比對回傳流量和原始 egress 流量的 conntrack,並將目的地 IP 位址重寫為 10.10.10.1。

  7. 10.10.10.1 會視為叢集內流量,轉送至原始節點,並傳回原始 Pod。

事前準備

如果節點搭載 Ubuntu 18.04,Linux 核心必須為 5.4 以上版本。詳情請參閱「設定 Ubuntu」。

為節點流量設定浮動 IP 位址

網路閘道群組自訂資源是 Google Distributed Cloud 的套裝元件。這項資源會管理一或多個浮動 IP 位址的清單,用於叢集內節點的輸出流量。參與節點由指定的命名空間決定。網路閘道群組會盡可能隨時提供浮動 IP 位址。如果使用浮動 IP 位址的節點故障,進階網路運算子會將指派的 IP 位址移至下一個可用的節點。使用該 IP 位址的所有工作負載輸出流量也會一併移動。

建立新的 1.36.200-gke.118 叢集時,請在叢集設定檔中加入網路閘道群組詳細資料 (註解和規格)。

建立 NetworkGatewayGroup 自訂資源

建立叢集時,在叢集設定檔中將 spec.clusterNetwork.advancedNetworking 欄位設為 true,即可啟用網路閘道群組,如下例所示:

apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: cluster1
  namespace: cluster-cluster1
spec:
  clusterNetwork:
    ...
    advancedNetworking: true
    ...

建立 NetworkGatewayGroup 自訂資源時,請將其命名空間設為叢集命名空間,並指定浮動 IP 位址清單,如以下範例所示:

kind: NetworkGatewayGroup
apiVersion: networking.gke.io/v1
metadata:
  namespace: cluster-cluster1
  name: default
spec:
  floatingIPs:
  - 192.168.1.100
  - 192.168.1.101
  - 192.168.1.102

進階網路運算子會根據下列條件,將浮動 IP 指派給節點:

  • 節點子網路:浮動 IP 位址必須與節點的子網路相符。
  • 節點角色 (控制層、worker):指派浮動 IP 位址時,worker 節點優先於控制層節點。
  • 節點是否具有浮動 IP 位址:運算子會優先指派給尚未指派浮動 IP 的節點。

取得 NetworkGatewayGroup 物件時,您可以在 status 區段中找到位址與節點的對應關係。請注意,NetworkGatewayGroup 物件位於 kube-system 命名空間中。如果閘道節點故障,進階網路運算子會將浮動 IP 位址指派給下一個可用的節點。

驗證閘道設定

套用閘道設定變更後,您可以使用 kubectl 檢查閘道狀態,並擷取為閘道指定的浮動 IP 位址。

使用下列指令檢查 NetworkGatewayGroup 的狀態,並查看浮動 IP 位址的分配方式:

kubectl -n kube-system get networkgatewaygroups.networking.gke.io default -o yaml

如果叢集有兩個節點 (worker1 和 worker2),回應可能如下所示:

kind: NetworkGatewayGroup
apiVersion: networking.gke.io/v1
metadata:
  namespace: kube-system
  name: default
spec:
  floatingIPs:
  - 192.168.1.100
  - 192.168.1.101
  - 192.168.1.102
status:
  nodes:
    worker1: Up
    worker2: Up // Or Down
  floatingIPs:
    192.168.1.100: worker1
    192.168.1.101: worker2
    192.168.1.102: worker1

設定流量選取規則

EgressNATPolicy 自訂資源會指定流量選取規則,並為離開叢集的輸出流量指派確定性 IP 位址。指定自訂資源時,egress (至少包含一項規則)、destinationCIDRs 和 egressSourceIP 均為必要項目。

使用 kubectl apply 建立 EgressNATPolicy 自訂資源。以下各節將詳細說明如何定義規格,並提供範例。

指定輸出路由規則

EgressNatPolicy 自訂資源可讓您為輸出流量指定下列規則:

  • 您必須在 egress 區段中指定一或多個輸出流量選取規則。

    • 每項規則都包含 podSelector 和 namespaceSelector。
    • 系統會根據命名空間標籤 namespaceSelector.matchLabels.user 和 Pod 標籤 podSelector.matchLabels.role 進行選取。
    • 如果 Pod 符合任何規則 (比對時使用 OR 關係),系統就會選取該 Pod 處理輸出流量。
  • 在「destinationCIDRs」部分指定允許的目的地地址。

    • destinationCIDRs 接受 CIDR 區塊清單。
    • 如果 Pod 的傳出流量目的地 IP 位址落在任何指定 CIDR 區塊的範圍內,系統就會選取該流量做為輸出流量。

在以下範例中,如果符合下列條件,系統就會允許從 Pod 輸出的流量:

  • Pod 標有 role: frontend。
  • Pod 位於標示為 user: alice 或 user: paul 的命名空間。
  • Pod 正在與 8.8.8.0/24 CIDR 區塊中的 IP 位址通訊。
kind: EgressNATPolicy
apiVersion: networking.gke.io/v1
metadata:
  name: egress
spec:
  sources:
  - namespaceSelector:
      matchLabels:
        user: alice
    podSelector:
      matchLabels:
        role: frontend
  - namespaceSelector:
      matchLabels:
        user: paul
    podSelector:
      matchLabels:
        role: frontend
  action: SNAT
  destinations:
    - cidr: 8.8.8.0/24
  gatewayRef:
    name: default
    namespace: kube-system

如要進一步瞭解如何使用標籤,請參閱 Kubernetes 說明文件中的「標籤和選取器」。

取得輸出流量的來源 IP 位址

EgressNATPolicy 自訂資源 (政策) 會使用 gatewayRef.name 和 gatewayRef.namespace 值尋找 NetworkGatewayGroup 物件 (閘道)。這項政策會使用閘道的其中一個浮動 IP 位址,做為輸出流量的來源 IP 位址。如果相符閘道中有多個浮動 IP 位址,政策會使用 floatingIPs 清單中的第一個 IP 位址,並忽略其他 IP 位址。以閘道範例來說,floatingIPs 清單中的第一個位址是 192.168.1.100。如果 gatewayRef 區段含有無效的欄位或值,系統將無法套用政策物件。

多項輸出政策和多個閘道物件

如上一節所述,每個 egressNATPolicy 物件 (政策) 都會使用閘道物件中 floatingIPs 清單內的第一個 IP 位址,該位址與 gatewayRef.name 和 gatewayRef.namespace 相符。您可以建立多個政策,如果打算使用不同的 IP 位址,則須建立多個 NetworkGatewayGroup 物件,並分別參照這些物件。

每個 NetworkGatewayGroup 資源都必須包含不重複的浮動 IP 位址。如要將多個 EgressNATPolicy 物件設為使用相同的 IP 位址,請為兩者使用相同的 gatewayRef.name 和 gatewayRef.namespace。

如要設定多項輸出政策和多個閘道物件,請按照下列步驟操作:

  1. 在 kube-system 命名空間中建立閘道物件,管理各個浮動 IP 位址。一般來說,每項輸出政策都應有對應的閘道物件,確保系統分配正確的 IP 位址。

    接著,使用 kubectl 驗證每個閘道物件,取得浮動 IP 位址的分配狀態:

    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: gateway1
    spec:
      floatingIPs:
      - 192.168.1.100
    status:
      ...
      floatingIPs:
        192.168.1.100: worker1
    ---
    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: gateway2
    spec:
      floatingIPs:
      - 192.168.1.101
    status:
      ...
      floatingIPs:
        192.168.1.101: worker2
    ---
    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: gateway3
    spec:
      floatingIPs:
      - 192.168.1.102
    status:
      ...
      floatingIPs:
        192.168.1.102: worker1
    
  2. 建立多項參照閘道物件的政策,例如在上一個步驟中建立的 gateway1:

    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egress1
    spec:
      ...
      gatewayRef:
        name: gateway1
        namespace: kube-system
    ---
    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egress2
    spec:
      ...
      gatewayRef:
        name: gateway2
        namespace: kube-system
    ---
    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egress3
    spec:
      ...
      gatewayRef:
        name: gateway3
        namespace: kube-system
    

(選用) 指定要放置浮動 IP 位址的節點

NetworkGatewayGroup 項資源支援節點選取器。如要指定託管浮動 IP 位址的節點子集,可以將節點選取器新增至 NetworkGatewayGroup 物件,如下列範例所示:

kind: NetworkGatewayGroup
apiVersion: networking.gke.io/v1
metadata:
  namespace: cluster-cluster1
  name: default
spec:
  floatingIPs:
  - 192.168.1.100
  - 192.168.1.101
  - 192.168.1.102
  nodeSelector:
    node-type: "egressNat"

節點選取器會比對具有指定標籤的節點,且只有這些節點會列入託管浮動 IP 位址的考量。如果指定多個選取器,其邏輯會累加,因此節點必須符合每個標籤,才能託管浮動 IP 位址。如果具有相符標籤的節點不多,節點選取器可能會降低浮動 IP 位址放置的高可用性 (HA) 品質。

高可用性輸出 NAT 閘道的快速容錯移轉

如果是 1.34 以上版本的叢集,您可以設定輸出 NAT 閘道,啟用快速容錯移轉功能。如果您有多個浮動 IP 位址,並設定快速容錯移轉,就能提供高可用性輸出。這項功能可更有效地分配輸出流量負載,並加快容錯移轉速度,盡可能縮短停機時間。叢集不會一次只依賴一個閘道節點 (主動-待命),而是會將傳出流量分配給多個閘道節點,以及 NetworkGatewayGroup 資源中所有已設定的浮動 IP 位址。

這種主動-主動模式有以下主要優點:

  • 負載分配:來自不同來源端點 (例如 Pod) 的輸出流量會分散到所有可用的閘道節點,降低任何單一節點的負載,並增加可用的輸出頻寬總量。

  • 快速容錯移轉:如果輸出閘道節點故障,流量會自動重新導向至其餘健康狀態良好的節點。目標是讓流量快速容錯移轉。雖然故障節點上的現有連線會中斷,但新連線會立即透過其他閘道建立,盡可能縮短停機時間。

主要差異

為快速容錯移轉設定輸出 NAT 閘道,會變更輸出 NAT 閘道的運作方式:

功能 運作中對待命 (預設) 主動-主動 (快速容錯移轉)
浮動 IP 使用情形 EgressNATPolicy 只會使用 NetworkGatewayGroup 中的第一個浮動 IP 位址。 NetworkGatewayGroup 中列出的所有浮動 IP 位址都會主動分配 egress 流量。
容錯移轉 如果閘道節點故障,相同的浮動 IP 位址會移至其他節點,這可能會導致流量中斷。 如果閘道節點故障,流量會重新導向至其他節點上不同的健康 IP 位址。新的連線會立即透過健康狀態良好的閘道路由,而故障節點上現有的有狀態連線則會終止。
流量 指定政策的所有流量都會通過單一閘道節點。 流量會根據來源端點 (例如 Pod) 的一致性雜湊,分配到多個閘道節點。

設定快速容錯移轉

設定這項功能主要有兩個步驟:

  1. 指定多個浮動 IP 位址。

    請為 NetworkGatewayGroup 設定至少兩個浮動 IP 位址的集區,以實現高可用性和負載分配的優勢。使用更多浮動 IP 位址可提高輸出可靠性和處理量。

    以下是設定範例:

    apiVersion: networking.gke.io/v1
    kind: NetworkGatewayGroup
    metadata:
      name: egress-gateways
      namespace: cluster-admin
    spec:
      nodeSelector:
        # Selects nodes that are designated as egress gateways
        node-role.kubernetes.io/egress: ""
      floatingIPs:
      - "192.168.1.100"
      - "192.168.1.101"
      - "192.168.1.102"
    
  2. 如要啟用快速容錯移轉功能,請將 networking.gke.io/egressnat-ha: "enable" 註解新增至 EgressNATPolicy 自訂資源:

    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egress
      annotations:
        networking.gke.io/egressnat-ha: "enable"
    spec:
      ...
    

輸出流量選取規則和網路政策

輸出 NAT 閘道與網路政策 API 相容。系統會先評估網路政策,其優先順序高於 egress NAT 閘道的流量選取規則。舉例來說,如果輸出流量觸發網路政策,導致封包遭到捨棄,輸出閘道規則就不會檢查封包。只有在網路政策允許封包輸出時,系統才會評估輸出流量選取規則,決定流量的處理方式,包括使用輸出 NAT 閘道,或直接以 Pod 執行所在節點的 IP 位址偽裝。

限制

輸出 NAT 閘道目前的限制包括:

  • 輸出 NAT 閘道僅適用於 IPv4 模式。

  • 輸出 IP 位址必須與節點 IP 位址位於相同的第 2 層網域。

  • 如果您同時設定標準 BGP 負載平衡和輸出 NAT,並使用 GKE On-Prem API 管理叢集 (透過 Terraform、 Google Cloud 控制台或 gcloud CLI),則不支援 BGP 對等互連選取器。這項限制可能導致 BGP 工作階段隨機使用不正確的本機 IP 進行對等互連,進而造成 BGP 對等互連失敗。如需解決方法,請參閱「使用 BGP 設定負載平衡器套裝組合:BGP 選取器限制」。