Pod の複数のネットワーク インターフェースを構成する

10

このドキュメントでは、Pod に複数のネットワーク インターフェース(マルチ NIC)を提供するように VMware(GKE On-Prem)で Anthos クラスタを構成する方法について説明します。Pod 用のマルチ NIC 機能は、コントロール プレーン トラフィックをデータプレーン トラフィックから分離して、プレーン間で分離するのに役立ちます。また、追加のネットワーク インターフェースによって、Pod のマルチキャスト機能を有効にできます。Pod のマルチ NIC はユーザー クラスタではサポートされており、管理クラスタでは許可されません。

ネットワーク プレーンの分離は、広域ネットワーク(SD-WAN)のソフトウェア定義ネットワーキング、クラウド アクセス セキュリティ ブローカー(CASB)、次世代ファイアウォール(NG-FW)などのネットワーク機能仮想化(NFV)を使用するシステムにとって重要です。これらのタイプの NFV は、コントロール プレーンとデータプレーンを分離するために、複数のインターフェースを利用します。

複数ネットワーク インターフェースの構成では、ネットワーク インターフェースとノードプールの関連付けがサポートされ、パフォーマンスの向上が実現できます。たとえば、1 つのクラスタには、混在するノードタイプを含めることができます。高パフォーマンスのマシンを 1 つのノードプールにグループ化する場合は、ノードプールに別のインターフェースを作成してトラフィック フローを改善できます。

複数のネットワーク インターフェースを設定する

通常、次の 3 ステップで、Pod に複数のネットワーク インターフェースを設定します。

  1. クラスタ構成ファイルで multipleNetworkInterfaces フィールドと enableDataplaneV2 フィールドを使用して、ユーザー クラスタのマルチ NIC を有効にする

  2. クラスタ構成ファイルの additionalNodeInterfaces セクションでネットワーク インターフェースを指定し、1 つ以上の NetworkAttachmentDefinition カスタム リソースを作成する。

  3. k8s.v1.cni.cncf.io/networks アノテーションを使用して、Pod にネットワーク インターフェースを割り当てる

マルチ NIC を有効にする

Pod のマルチ NIC は、ユーザー クラスタ構成ファイルの multipleNetworkInterfaces フィールドと enableDataplaneV2 フィールドを true に設定して有効にします。

apiVersion: v1
multipleNetworkInterfaces: true
enableDataplaneV2: true
  ...

ネットワーク インターフェースを指定する

クラスタの構成ファイルの additionalNodeInterfaces セクションで、追加のノード ネットワーク インターフェースを指定します。

たとえば、次のユーザー クラスタ構成ファイルの一部は、追加のノード ネットワーク インターフェースを示しています。

apiVersion: v1
multipleNetworkInterfaces: true
enableDataplaneV2: true
network:
  serviceCIDR: "10.96.0.0/20"
  podCIDR: "192.168.0.0/16"
  vCenter:
    networkName: network-private310
  ...
  # New multiple network configs
  additionalNodeInterfaces:
  - networkName: "gke-network-1"
    ipBlockFilePath: "my-block-yaml"
    type: static

前述の構成でクラスタを作成したら、追加のネットワーク インターフェースを指定するユーザー クラスタに、1 つ以上の NetworkAttachmentDefinition(NAD)カスタム リソースを作成する必要があります。NetworkAttachmentDefinitions は、Pod で使用できるネットワークに対応しています。次の例は、NetworkAttachmentDefinition のマニフェストを示しています。

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: gke-network-1
  namespace: default
spec:
  config: '{
  "cniVersion":"0.3.0",
  "type": "ipvlan",
  "master": "ens224", # defines the node interface that this Pod interface would map to
  "mode": "l2",
  "ipam": {
    "type": "whereabouts",
    "range": "172.16.0.0/24"
   }
}'

マニフェストを YAML ファイル(my-nad.yaml など)として保存し、NetworkAttachmentDefinition を作成します。

kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] apply -f my-nad.yaml

Pod にネットワーク インターフェースを割り当てる

k8s.v1.cni.cncf.io/networks アノテーションを使用して、1 つ以上のネットワーク インターフェースを Pod に割り当てます。各ネットワーク インターフェースは、NetworkAttachmentDefinition とスラッシュ(/)で区切られた名前空間で指定します。複数のネットワーク インターフェースを指定する場合は、カンマ区切りのリストを使用します。

次の例では、2 つのネットワーク インターフェースが samplepod Pod に割り当てられます。ネットワーク インターフェースは、default 名前空間に作成された 2 つの NetworkAttachmentDefinitionsgke-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:
  ...

ネットワーク インターフェースを一連のノードに制限する

NetworkAttachmentDefinition をクラスタ全体に適用できるようにしない場合は、その機能を一連のノードに制限できます。

クラスタノードは、ノードに割り当てられた標準ラベルか、独自のカスタムラベルを使用してグループ化できます。次にノードラベルを、k8s.v1.cni.cncf.io/nodeSelector アノテーションを使用し、NetworkAttachmentDefinition マニフェストで指定できます。Anthos clusters on VMware は、このカスタム リソースを参照するすべての Pod を、このラベルがあるノードに強制的にデプロイします。

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  annotations:
    k8s.v1.cni.cncf.io/nodeSelector: LABEL_KEY=LABEL_VALUE
  name: gke-network-1
spec:
...

次の例は NetworkAttachmentDefinition で指定された my-label=multinicNP ラベルを示しており、gke-network-1 ネットワークに割り当てられたすべての Pod を、このラベルを持つノードに強制的にデプロイしています。

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  annotations:
    k8s.v1.cni.cncf.io/nodeSelector: my-label=multinicNP
  name: gke-network-1
spec:
...

ノードにカスタムラベルを適用するには、kubectl label nodes コマンドを使用します。

kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] label nodes NODE_NAME LABEL_KEY=LABEL_VALUE 

次のように置き換えます。

  • NODE_NAME: ラベルを付ける Node の名前。
  • LABEL_KEY: ラベルに使用するキー。
  • LABEL_VALUE: ラベルの値。

次の例では、ノード my-nodeenvironment=production ラベルが付与されます。

kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] label nodes my-node environment=production

セキュリティに関する懸念

NetworkAttachmentDefinition はネットワークへの完全アクセス権を提供するため、クラスタ管理者は他のユーザーへの作成、更新、削除のアクセス権の付与は注意して行う必要があります。特定の NetworkAttachmentDefinition を分離する必要がある場合は、作成する際にデフォルト以外の名前空間を指定して、その名前空間の Pod のみがアクセスできるようにします。

次の図では、default 名前空間の Pod は、privileged 名前空間のネットワーク インターフェースにアクセスできません。

Namespace を使用してネットワーク トラフィックを分離する

サポートされている CNI プラグイン

このセクションでは、Anthos clusters on VMware のマルチ NIC 機能でサポートされている CNI プラグインを一覧表示します。NetworkAttachmentDefinition を指定する場合は、次のプラグインのみを使用します。

インターフェースの作成:

  • ipvlan
  • macvlan
  • bridge

メタプラグイン:

  • portmap
  • sbr
  • tuning

IPAM プラグイン:

  • host-local
  • static
  • whereabouts

ルートの構成

NetworkAttachmentDefinitions が 1 つ以上割り当てられている Pod には、複数のネットワーク インターフェースがあります。デフォルトでは、この状況の Pod のルーティング テーブルは、割り当てられた NetworkAttachmentDefinitions からローカルで使用できる追加のインターフェースのみで拡張されます。デフォルト ゲートウェイにバインドされたパケットは、Pod のデフォルト インターフェース eth0 を使用するように引き続き構成されます。この動作は、次の CNI プラグインを使用することにより変更できます。

  • sbr
  • static
  • whereabouts

たとえば、ほとんどのトラフィックがデフォルト ゲートウェイを経由するようにする場合、これは、トラフィックがデフォルトのネットワーク インターフェースを経由することを意味します。ただし、特定のトラフィックがデフォルト以外のインターフェースのいずれかを通過するように設定します。両方のインターフェース タイプで同じエンドポイントを使用できるため、宛先 IP(通常のルーティング)に基づいてトラフィックの曖昧さを取り除くことは難しい場合があります。このような場合は、ソースベースのルーティング(SBR)が役立ちます。

SBR プラグイン

sbr プラグインを使用すると、アプリケーションでルーティングの決定を制御できるようになります。アプリケーションは、確立する接続の送信元 IP アドレスとして使用するものを制御します。アプリケーションが送信元 IP として NetworkAttachmentDefinition の IP アドレスの使用を選択すると、パケットは追加のルーティング テーブル sbr に設定されます。sbr ルーティング テーブルは、独自のデフォルト ゲートウェイ経由でトラフィックを送信します。このデフォルト ゲートウェイは NetworkAttachmentDefinition のインターフェースを通じて送信されます。テーブル内のデフォルト ゲートウェイ IP は、whereabouts または static プラグイン内の gateway フィールドで制御されます。sbr プラグインはチェーン プラグインとして実行されます。使用状況の情報など、sbr プラグインの詳細については、ソースベースのルーティング プラグインをご覧ください。

次の例は、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

static プラグインと whereabouts プラグイン

whereabouts プラグインは基本的に static プラグインの拡張であり、これら 2 つはルーティング構成を共有します。構成例については、静的 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 インターフェースの確認

Pod インターフェースを確認するには kubectl exec コマンドを使用します。NetworkAttachmentDefinitions が正常に適用されると、Pod インターフェースは次のような出力になります。

user@node1:~$ 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 のステータスの取得

特定の Pod のネットワーク ステータスを取得するには kubectl get を使用します。

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