為 Pod 設定多個網路介面

本文說明如何設定 Google Distributed Cloud,為 Pod 提供多個網路介面 (多重 NIC)。Pod 的多 NIC 功能可協助區分控制層流量和資料層流量,在不同層之間建立區隔。此外,額外網路介面也能為 Pod 啟用多點播送功能。使用者叢集、混合式叢集和獨立叢集都支援 Pod 的多重 NIC。管理員類型叢集不允許使用這項功能。

本頁適用於負責安裝、設定及支援網路設備的網路專家。如要進一步瞭解我們在 Google Cloud 內容中提及的常見角色和範例工作,請參閱「常見的 GKE Enterprise 使用者角色和工作」。

對於使用網路功能虛擬化 (NFV) 的系統 (例如廣域網路 (SD-WAN) 中的軟體定義網路、雲端存取安全代理程式 (CASB) 和新一代防火牆 (NG-FW)) 而言,網路平面隔離非常重要。這類 NFV 依賴多個介面的存取權,以確保管理和資料層分離,同時以容器形式執行。

多個網路介面設定支援將網路介面與節點集區建立關聯,有助於提升效能。叢集可以包含多種節點類型。將高效能機器分組到一個節點集區後,您可以在節點集區中新增其他介面,改善流量。

設定多個網路介面

一般來說,為 Pod 設定多個網路介面需要三個步驟:

  1. 使用叢集自訂資源中的 multipleNetworkInterfaces 欄位,為叢集啟用多重 NIC

  2. 使用 NetworkAttachmentDefinition 自訂資源指定網路介面

  3. 使用 k8s.v1.cni.cncf.io/networks 註解將網路介面指派給 Pod

我們提供額外資訊,協助您以最符合網路需求的方式設定及使用多重 NIC 功能。

啟用多 NIC

如要為 Pod 啟用多重 NIC,請將 multipleNetworkInterfaces 欄位新增至叢集自訂資源的 clusterNetwork 區段,並將其設為 true

  ...
  clusterNetwork:
    multipleNetworkInterfaces: true
    pods:
      cidrBlocks:
      - 192.168.0.0/16
    services:
      cidrBlocks:
      - 10.96.0.0/20
  ...

指定網路介面

使用 NetworkAttachmentDefinition 自訂資源指定其他網路介面。NetworkAttachmentDefinition 自訂資源對應於可供 Pod 使用的網路。您可以在叢集設定中指定自訂資源,如下列範例所示,也可以直接建立 NetworkAttachmentDefinition 自訂資源。

---
apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: my-cluster
  namespace: cluster-my-cluster
spec:
    type: user
    clusterNetwork:
      multipleNetworkInterfaces: true
...
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: gke-network-1
  namespace: cluster-my-cluster
spec:
  config: '{
  "cniVersion":"0.3.0",
  "type": "ipvlan",
  "master": "enp2342",  # defines the node interface that this pod interface would
                         map to.
  "mode": "l2",
  "ipam": {
    "type": "whereabouts",
    "range": "172.120.0.0/24"
  }
}'
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: gke-network-2
  namespace: cluster-my-cluster
spec:
  config: '{
  "cniVersion":"0.3.0",
  "type": "macvlan",
  "mode": "bridge",
  "master": "vlan102",
  "ipam": {
    "type": "static",
    "addresses": [
      {
        "address": "10.10.0.1/24",
        "gateway": "10.10.0.254"
      }
    ],
    "routes": [
      { "dst": "192.168.0.0/16", "gw": "10.10.5.1" }
    ]
  }
}'

在叢集設定檔中指定 NetworkAttachmentDefinition 自訂資源時,Google Distributed Cloud 會使用這個名稱,在叢集建立後控管 NetworkAttachmentDefinition 自訂資源。Google Distributed Cloud 會將叢集命名空間內的自訂資源視為事實來源,並將其與目標叢集的 default 命名空間進行比對。

下圖說明 Google Distributed Cloud 如何將叢集專屬命名空間的 NetworkAttachmentDefinition 自訂資源,調解至 default 命名空間。

NetworkAttachmentDefinition 協調

雖然這是選用步驟,但我們建議您在建立叢集時,以這種方式指定NetworkAttachmentDefinition自訂資源。建立叢集時指定自訂資源,對使用者叢集最有益,因為這樣一來,您就能從管理員叢集控管NetworkAttachmentDefinition自訂資源。

如果您選擇在建立叢集時不指定NetworkAttachmentDefinition自訂資源,可以直接將NetworkAttachmentDefinition自訂資源新增至現有的目標叢集。Google Distributed Cloud 會調解叢集命名空間中定義的NetworkAttachmentDefinition自訂資源。刪除時也會進行對帳。從叢集命名空間移除NetworkAttachmentDefinition自訂資源時,Google Distributed Cloud 會從目標叢集移除該自訂資源。

將網路介面指派給 Pod

使用 k8s.v1.cni.cncf.io/networks 註解,將一或多個網路介面指派給 Pod。每個網路介面都會以命名空間和自訂資源的名稱指定,並以斜線 (/) 分隔。NetworkAttachmentDefinition

---
apiVersion: v1
kind: Pod
metadata:
  name: samplepod
  annotations:
    k8s.v1.cni.cncf.io/networks: NAMESPACE/NAD_NAME
spec:
  containers:
  ...

更改下列內容:

  • NAMESPACE:命名空間。使用 default 做為預設命名空間 (這是標準做法)。如需例外狀況,請參閱「安全疑慮」。
  • NAD_NAMENetworkAttachmentDefinition自訂資源的名稱。

使用以半形逗號分隔的清單,指定多個網路介面。

在下列範例中,系統會將兩個網路介面指派給 samplepod Pod。網路介面是由目標叢集預設命名空間中的兩個 NetworkAttachmentDefinition 自訂資源名稱 (gke-network-1gke-network-2) 指定。

---
apiVersion: v1
kind: Pod
metadata:
  name: samplepod
  annotations:
    k8s.v1.cni.cncf.io/networks: default/gke-network-1,default/gke-network-2
spec:
  containers:
  ...

將網路介面限制為 NodePool

使用 k8s.v1.cni.cncf.io/nodeSelector 註解指定 NetworkAttachmentDefinition 自訂資源有效的節點集區。Google Distributed Cloud 會強制將參照這個自訂資源的任何 Pod 部署到這些特定節點。在下列範例中,Google Distributed Cloud 會強制將指派 gke-network-1 網路介面的所有 Pod 部署至 multinicNP NodePool。Google Distributed Cloud 會相應地為 NodePool 加上 baremetal.cluster.gke.io/node-pool 標籤。

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  annotations:
    k8s.v1.cni.cncf.io/nodeSelector: baremetal.cluster.gke.io/node-pool=multinicNP
  name: gke-network-1
spec:
...

您不一定要使用標準標籤,您可以為叢集節點套用自訂標籤,從這些節點建立自訂集區。使用 kubectl label nodes 指令套用自訂標籤:

kubectl label nodes NODE_NAME LABEL_KEY=LABEL_VALUE

更改下列內容:

  • NODE_NAME:要加入標籤的節點名稱。
  • LABEL_KEY:標籤使用的鍵。
  • LABEL_VALUE:標籤名稱。

標記節點後,請在該節點上套用 baremetal.cluster.gke.io/label-taint-no-sync 註解,防止 Google Distributed Cloud 協調標籤。使用 kubectl get nodes --show-labels 指令驗證節點是否已加上標籤。

安全疑慮

NetworkAttachmentDefinition自訂資源可提供網路的完整存取權,因此叢集管理員必須謹慎授權其他使用者建立、更新或刪除資源。如果需要隔離特定NetworkAttachmentDefinition自訂資源,可以將其放在非預設命名空間中,只有該命名空間中的 Pod 才能存取。如要調解叢集設定檔中指定的 NetworkAttachmentDefinition 自訂資源,這些資源一律會放在預設命名空間中。

在下圖中,default 命名空間中的 Pod 無法存取 privileged 命名空間中的網路介面。

使用命名空間隔離網路流量

支援的 CNI 外掛程式

本節列出 Google Distributed Cloud 多重 NIC 功能支援的 CNI 外掛程式。指定 NetworkAttachmentDefinition 自訂資源時,請只使用下列外掛程式。

建立介面:

  • ipvlan
  • macvlan
  • bridge
  • sriov

Meta 外掛程式:

  • portmap
  • sbr
  • tuning

IPAM 外掛程式:

  • host-local
  • static
  • whereabouts

路徑設定

具有一或多個指派的 NetworkAttachmentDefinition 自訂資源 資源的 Pod 具有多個網路介面。根據預設,在這種情況下,只有來自指派的NetworkAttachmentDefinition自訂資源的本機可用額外介面,會擴充路由表。預設閘道仍設定為使用 Pod 的主要/預設介面 eth0

您可以使用下列 CNI 外掛程式修改這項行為:

  • sbr
  • static
  • whereabouts

舉例來說,您可能希望所有流量都通過預設閘道 (預設介面)。不過,部分特定流量會透過其中一個非預設介面傳輸。根據目的地 IP (一般轉送) 區分流量可能會有困難,因為這兩種介面類型都提供相同的端點。在這種情況下,來源式路由 (SBR) 就能派上用場。

SBR 外掛程式

應用程式可透過 sbr 外掛程式控制路徑決策。應用程式會控管連線建立時使用的來源 IP 位址。當應用程式選擇使用NetworkAttachmentDefinition自訂資源的 IP 位址做為來源 IP 時,封包會落在 sbr 設定的額外路由表。sbr 路由表會將NetworkAttachmentDefinition自訂資源的介面設為預設閘道。該表格中的預設閘道 IP 是由 whereaboutsstatic 外掛程式中的 gateway 欄位控制。以鏈結外掛程式的形式提供 sbr 外掛程式。如要進一步瞭解 sbr 外掛程式,包括使用資訊,請參閱「Source-based routing plugin」。

以下範例顯示在 whereabouts 中設定的 "gateway":"21.0.111.254",以及在 ipvlan 後設定為鏈結外掛程式的 sbr

# ip route
default via 192.168.0.64 dev eth0  mtu 1500
192.168.0.64 dev eth0 scope link
# ip route list table 100
default via 21.0.111.254 dev net1
21.0.104.0/21 dev net1 proto kernel scope link src 21.0.111.1

靜態和所在位置外掛程式

whereabouts 外掛程式基本上是 static 外掛程式的擴充功能,這兩者共用轉送設定。如需設定範例,請參閱靜態 IP 位址管理外掛程式。您可以定義要新增至 Pod 路由表的閘道和路徑。但您無法以這種方式修改 Pod 的預設閘道。

以下範例顯示在 NetworkAttachmentDefinition 自訂資源中新增 "routes": [{ "dst": "172.31.0.0/16" }]

# ip route
default via 192.168.0.64 dev eth0  mtu 1500
172.31.0.0/16 via 21.0.111.254 dev net1
21.0.104.0/21 dev net1 proto kernel scope link src 21.0.111.1
192.168.0.64 dev eth0 scope link

設定範例

本節說明多重 NIC 功能支援的常見網路設定。

多個 Pod 使用單一網路附件

多個 Pod 使用單一網路附件

單一 Pod 使用多個網路附件

單一 Pod 使用多個網路附件

多個網路附件指向單一 Pod 使用的相同介面

多個網路附件指向單一 Pod 使用的相同介面

單一 Pod 多次使用相同的網路附件

單一 Pod 多次使用相同的網路附件

疑難排解

如果額外網路介面設定錯誤,系統就不會啟動指派這些介面的 Pod。本節重點說明如何尋找資訊,以排解多重 NIC 功能的問題。

檢查 Pod 事件

Multus 會透過 Kubernetes pod 事件回報失敗情形。使用下列 kubectl describe 指令,查看特定 Pod 的事件:

kubectl describe pod POD_NAME

檢查記錄

您可以在下列位置找到每個節點的 Whereabouts 和 Multus 記錄:

  • /var/log/whereabouts.log
  • /var/log/multus.log

查看 Pod 介面

使用 kubectl exec 指令檢查 Pod 介面。成功套用 NetworkAttachmentDefinition 自訂資源後,Pod 介面會顯示如下輸出內容:

$ kubectl exec samplepod-5c6df74f66-5jgxs -- ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: net1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
    link/ether 00:50:56:82:3e:f0 brd ff:ff:ff:ff:ff:ff
    inet 21.0.103.112/21 scope global net1
       valid_lft forever preferred_lft forever
38: eth0@if39: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 36:23:79:a9:26:b3 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.2.191/32 scope global eth0
       valid_lft forever preferred_lft forever

取得 Pod 狀態

使用 kubectl get 擷取特定 Pod 的網路狀態:

kubectl get pods POD_NAME -oyaml

以下是範例輸出內容,顯示具有多個網路的 Pod 狀態:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    k8s.v1.cni.cncf.io/network-status: |-
      [{
          "name": "",
          "interface": "eth0",
          "ips": [
              "192.168.1.88"
          ],
          "mac": "36:0e:29:e7:42:ad",
          "default": true,
          "dns": {}
      },{
          "name": "default/gke-network-1",
          "interface": "net1",
          "ips": [
              "21.0.111.1"
          ],
          "mac": "00:50:56:82:a7:ab",
          "dns": {}
      }]
    k8s.v1.cni.cncf.io/networks: gke-network-1