SR-IOV ネットワーキングを設定する

このドキュメントでは、ベアメタル版 Anthos クラスタにシングルルート入力 / 出力仮想化(SR-IOV)ネットワーキングを設定する方法について説明します。SR-IOV は、Linux カーネルでネットワーク デバイスとして使用できるネットワーク インターフェース カード(NIC)を作成するための I/O 仮想化を提供します。これにより、ネットワーク接続の管理と、Pod への割り当てが可能になります。NIC と Pod の間でパケットが直接移動するため、パフォーマンスが向上します。

Pod ワークロードへの高速ネットワーキングが必要な場合は、この機能を使用してください。ベアメタル版 Anthos クラスタの SR-IOV を使用すると、クラスタノードのサポート対象デバイスで仮想関数(VF)を構成できます。特定のカーネル モジュールを指定して、VF にバインドすることもできます。

この機能は、ハイブリッドスタンドアロンユーザー クラスタなどのワークロードを実行するクラスタで使用できます。

設定プロセスは、次のおおまかな手順で構成されています。

  1. SR-IOV ネットワーキングを有効にするようにクラスタを構成する。
  2. SR-IOV 演算子(SriovOperatorConfig カスタム リソース)を構成する。
  3. SR-IOV ポリシーを設定し、VF を構成する。
  4. VF を参照する NetworkAttachmentDefinition カスタム リソースを作成する。

要件

SR-IOV ネットワーキング機能を使用するには、ネットワーク アダプタ用の公式ドライバがクラスタノードに存在する必要があります。SR-IOV 演算子を使用する前に、ドライバをインストールします。また、VF に vfio-pci モジュールを使用するには、そのモジュールが使用されるノードでモジュールが使用可能であることを確認してください。

クラスタの SR-IOV ネットワークを有効にする

SR-IOV ネットワーキングを有効にするには、クラスタのカスタム リソースに baremetal.cluster.gke.io/enable-sriov-networking アノテーションを追加します。また、クラスタ カスタム リソースの clusterNetwork セクションにある multipleNetworkInterfaces フィールドを true に設定します。

apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: cluster1
  annotations:
    baremetal.cluster.gke.io/enable-sriov-networking: "true"
spec:
  clusterNetwork:
    multipleNetworkInterfaces: true
    pods:
      cidrBlocks:
      - 192.168.0.0/16
    services:
      cidrBlocks:
      - 10.96.0.0/12

SR-IOV オペレーターを構成する

SriovOperatorConfig カスタム リソースは、SR-IOV ネットワーキング機能のグローバル構成を提供します。このバンドル カスタム リソースの名前は default で、gke-operators 名前空間にあります。SriovOperatorConfig カスタム リソースは、この名前と名前空間に対してのみ尊重されます。

このオブジェクトは、次のコマンドで編集できます。

kubectl -n gke-operators edit sriovoperatorconfigs.sriovnetwork.k8s.cni.cncf.io default

SriovOperatorConfig カスタム リソース構成の例を次に示します。

apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovOperatorConfig
metadata:
  name: default
  namespace: gke-operators
spec:
  configDaemonNodeSelector:
    nodePool: "withSriov"
  disableDrain: false
  logLevel: 2

configDaemonNodeSelector セクションでは、SR-IOV 演算子が処理できるノードを制限できます。前の例では、演算子は nodePool: withSriov ラベルを持つノードのみに制限されています。configDaemonNodeSelector フィールドが指定されていない場合、次のデフォルト ラベルが適用されます。

beta.kubernetes.io/os: linux
node-role.kubernetes.io/worker: ""

disableDrain フィールドは、ノードを再起動する前、または特定の VF 構成を変更する前に、Kubernetes ノードのドレイン オペレーションを実行するかどうかを指定します。

SR-IOV ポリシーを作成する

クラスタ内の特定の VF を構成するには、SriovNetworkNodePolicy カスタム リソースを gke-operators 名前空間に作成する必要があります。

SriovNetworkNodePolicy カスタム リソースのマニフェストの例を次に示します。

apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovNetworkNodePolicy
metadata:
  name: policy-1
  namespace: gke-operators
spec:
  deviceType: "netdevice"
  mtu: 1600
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0
    deviceID: "1015"
    rootDevices:
    - 0000:01:00.0
    vendor: "15b3"
  numVfs: 4
  priority: 80
  resourceName: "mlnx"

nodeSelector セクションでは、VF を作成するノードをさらに制限できます。この制限は、前のセクションで説明した SriovOperatorConfig のセレクタの上に来ます。

deviceType フィールドは、VF に使用するカーネル モジュールを指定します。deviceType で使用できるオプションは次のとおりです。

  • netdevice: VF 固有の標準カーネル モジュール
  • vfio-pci: VFIO-PCI ドライバ

resourceName は、VF が Kubernetes ノードで表される名前を定義します。

構成プロセスが完了すると、選択したクラスタノードには次の例に示す定義済みのリソースが含まれます(gke.io/mlnx に注意してください)。

apiVersion: v1
kind: Node
metadata:
  name: worker-01
spec:
…
status:
  allocatable:
    cpu: 47410m
    ephemeral-storage: "210725550141"
    gke.io/mlnx: "4"
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 59884492Ki
    pods: "250"
  capacity:
    cpu: "48"
    ephemeral-storage: 228651856Ki
    gke.io/mlnx: "4"
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 65516492Ki
    pods: "250"

演算子は SriovNetworkNodePolicy で定義したすべてのリソースに常に gke.io/ 接頭辞を追加します。

NIC セレクタを指定する

SriovNetworkNodePolicy が正常に機能するには、nicSelector セクションに少なくとも 1 つのセレクタを指定する必要があります。このフィールドには、クラスタノード内の特定の物理関数(PF)を識別する複数のオプションが含まれます。このフィールドで必要な情報のほとんどは検出され、SriovNetworkNodeState カスタム リソースに保存されます。この演算子が処理できるオブジェクトは、ノードごとにあります。

使用可能なすべてのノードを表示するには、次のコマンドを使用します。

kubectl -n gke-operators get sriovnetworknodestates.sriovnetwork.k8s.cni.cncf.io -o yaml

ここで、ノードの例を示します。

apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovNetworkNodeState
metadata:
  name: worker-01
  namespace: gke-operators
spec:
  dpConfigVersion: "6368949"
status:
  interfaces:
  - deviceID: "1015"
    driver: mlx5_core
    eSwitchMode: legacy
    linkSpeed: 10000 Mb/s
    linkType: ETH
    mac: 1c:34:da:5c:2b:9c
    mtu: 1500
    name: enp1s0f0
    pciAddress: "0000:01:00.0"
    totalvfs: 4
    vendor: 15b3
  - deviceID: "1015"
    driver: mlx5_core
    linkSpeed: 10000 Mb/s
    linkType: ETH
    mac: 1c:34:da:5c:2b:9d
    mtu: 1500
    name: enp1s0f1
    pciAddress: "0000:01:00.1"
    totalvfs: 2
    vendor: 15b3
  syncStatus: Succeeded

物理関数パーティショニングの設定

nicSelector セクションの pfNames フィールドには特に注意してください。使用する正確な PF だけでなく、ポリシーで定義された特定の PF とリソースで使用する VF を正確に指定することもできます。

次に例を示します。

apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovNetworkNodePolicy
metadata:
  name: policy-1
  namespace: gke-operators
spec:
  deviceType: "netdevice"
  mtu: 1600
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0#3-6
    deviceID: "1015"
    rootDevices:
    - 0000:01:00.0
    vendor: "15b3"
  numVfs: 7
  priority: 80
  resourceName: "mlnx"

先に挙げた例では、gke.io/mlnx リソースは 3~6 の番号が付いた VF のみを使用し、利用可能な VF が 4 つだけ表示されています。VF は常にゼロ インデックスから作成されるため、要求される VF の数(numVfs)は、少なくとも範囲の終了値(ゼロから数える)と同じ値でなければなりません。この番号付けロジックのため、上の例では numVfs7 に設定されています。3~4(enp65s0f0#3-4)の範囲に設定する場合、numVfs は少なくとも 5 である必要があります。

パーティショニングが指定されていない場合、numVfs は、使用されている VF 範囲を定義します(これは常にゼロから始まります)。たとえば、パーティショニングを指定せずに numVfs=3 を設定した場合、VF は 0-2 が使用されます。

ポリシーの優先度を理解する

複数の SriovNetworkNodePolicy オブジェクトを指定して、さまざまなベンダーまたはさまざまな VF 構成を処理できます。複数のポリシーが同じ PF を参照している場合、複数のオブジェクトやベンダーの管理が難しくなる可能性があります。このような状況を処理するため、priority フィールドはノードごとに競合を解決します。

重複する PF ポリシーの優先順位付けのロジックは次のとおりです。

  1. 優先度の高いポリシーは常に優先度の低いポリシーを上書きします。

  2. 同じ優先度のポリシーは結合されます。

    1. ポリシーは名前で並べ替えられ、その順序で処理されます
    2. VF 範囲が重複するポリシーは上書きされます。
    3. PF パーティショニングが重複しないポリシーは結合され、すべて残ります

優先度の高いポリシーは、priority フィールドの値が小さいポリシーです。たとえば、priority: 10 のポリシーは priority: 20 のポリシーよりも優先度が高くなります。

以降のセクションでは、さまざまなパーティショニング構成のポリシーの例を示します。

パーティショニングされた PF

次の 2 つの SriovNetworkNodePolicy マニフェストをデプロイすると、gke.io/dev-kernelgke.io/dev-vfio の 2 つのリソースが使用可能になります。各リソースには、重複しない 2 つの VF があります。

kind: SriovNetworkNodePolicy
metadata:
  name: policy-1
spec:
  deviceType: "netdevice"
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0#0-1
  numVfs: 2
  priority: 70
  resourceName: "dev-kernel"
kind: SriovNetworkNodePolicy
metadata:
  name: policy-2
spec:
  deviceType: "vfio-pci"
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0#2-3
  numVfs: 4
  priority: 70
  resourceName: "dev-vfio"

VF 範囲の重複

次の 2 つの SriovNetworkNodePolicy マニフェストをデプロイすると、gke.io/dev-vfio リソースのみが使用可能になります。policy-1 VF 範囲は 0-2 であり、policy-2 と重複します。名前のために、policy-2 は最後に処理されます。したがって、policy-2 で指定されたリソース、gke.io/dev-vfio のみが利用可能になります。

kind: SriovNetworkNodePolicy
metadata:
  name: policy-1
spec:
  deviceType: "netdevice"
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0
  numVfs: 3
  priority: 70
  resourceName: "dev-kernel"
kind: SriovNetworkNodePolicy
metadata:
  name: policy-2
spec:
  deviceType: "vfio-pci"
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0#2-3
  numVfs: 4
  priority: 70
  resourceName: "dev-vfio"

SR-IOV ポリシーの設定ステータスを確認する

SR-IOV ポリシーを適用すると、特定のノードの SriovNetworkNodeState カスタム リソース内のノードの最終構成を追跡、表示できます。status セクションで、syncStatus フィールドは構成デーモンの現在のステージを表します。Succeeded 状態は、構成が完了したことを示します。SriovNetworkNodeState カスタム リソースの spec セクションは、ポリシーの数とその優先度に基づいて、そのノードの VF 構成の最終状態を定義します。作成されたすべての VF が、指定された PF の status セクションに一覧表示されます。

SriovNetworkNodeState カスタム リソースの例を次に示します。

apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovNetworkNodeState
metadata:
  name: worker-02
  namespace: gke-operators
spec:
  dpConfigVersion: "9022068"
  interfaces:
  - linkType: eth
    name: enp1s0f0
    numVfs: 2
    pciAddress: "0000:01:00.0"
    vfGroups:
    - deviceType: netdevice
      policyName: policy-1
      resourceName: mlnx
      vfRange: 0-1
status:
  interfaces:
  - Vfs:
    - deviceID: "1016"
      driver: mlx5_core
      mac: 96:8b:39:d8:89:d2
      mtu: 1500
      name: enp1s0f0np0v0
      pciAddress: "0000:01:00.2"
      vendor: 15b3
      vfID: 0
    - deviceID: "1016"
      driver: mlx5_core
      mac: 82:8e:65:fe:9b:cb
      mtu: 1500
      name: enp1s0f0np0v1
      pciAddress: "0000:01:00.3"
      vendor: 15b3
      vfID: 1
    deviceID: "1015"
    driver: mlx5_core
    eSwitchMode: legacy
    linkSpeed: 10000 Mb/s
    linkType: ETH
    mac: 1c:34:da:5c:2b:9c
    mtu: 1500
    name: enp1s0f0
    numVfs: 2
    pciAddress: "0000:01:00.0"
    totalvfs: 2
    vendor: 15b3
  - deviceID: "1015"
    driver: mlx5_core
    linkSpeed: 10000 Mb/s
    linkType: ETH
    mac: 1c:34:da:5c:2b:9d
    mtu: 1500
    name: enp1s0f1
    pciAddress: "0000:01:00.1"
    totalvfs: 2
    vendor: 15b3
  syncStatus: Succeeded

NetworkAttachmentDefinition カスタム リソースを作成する

クラスタの VF が正常に構成され、Kubernetes ノードにリソースとして表示されたら、そのリソースを参照する NetworkAttachmentDefinition を作成する必要があります。k8s.v1.cni.cncf.io/resourceName アノテーションを使用して参照を作成します。

gke.io/mlnx リソースを参照する NetworkAttachmentDefinition マニフェストの例を次に示します。

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: gke-sriov-1
  annotations:
    k8s.v1.cni.cncf.io/resourceName: gke.io/mlnx
spec:
  config: '{
      "cniVersion": "0.3.0",
      "name": "mynetwork",
      "type": "sriov",
      "ipam": {
        "type": "whereabouts",
        "range": "21.0.108.0/21",
        "range_start": "21.0.111.16",
        "range_end": "21.0.111.18"
      }
    }'

NetworkAttachmentDefinition は、CNI タイプとして sriov が必要です。k8s.v1.cni.cncf.io/networks アノテーションを使用して、Pod 内にデプロイされた NetworkAttachmentDefinition カスタム リソースを参照します。

Pod で上の NetworkAttachmentDefinition カスタム リソースを参照する方法の例を次に示します。

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

ワークロードで NetworkAttachmentDefinition カスタム リソースを参照する場合、Pod のリソース定義や特定のノードへの配置を気にする必要はありません。これらは自動的に行われます。

次の例は、VLAN 構成を持つ NetworkAttachmentDefinition カスタム リソースを示しています。このサンプルでは、各 VF は 100 VLAN に属します。

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: gke-sriov-vlan-100
  annotations:
    k8s.v1.cni.cncf.io/resourceName: gke.io/mlnx
spec:
  config: '{
      "cniVersion": "0.3.0",
      "name": "mynetwork",
      "type": "sriov",
      "vlan": 100,
      "ipam": {
        "type": "whereabouts",
        "range": "21.0.100.0/21"
      }
    }'

詳細情報

以下のセクションでは、SR-IOV ネットワークを構成する際に役立つ情報を説明します。

ノードの再起動

SR-IOV 演算子がノードを構成する場合で、ノードの再起動が必要となる場合があります。VF またはカーネル構成中にノードの再起動が必要になることがあります。カーネル構成では、オペレーティング システムで SR-IOV 機能のサポートを有効にする必要があります。

サポートされているネットワーク アダプター

バージョン 1.10.x クラスタでサポートされているネットワーク アダプターを次の表に示します。

名前 ベンダー ID デバイス ID VF デバイス ID
Intel i40e XXV710 8086 158a 154c
Intel i40e 25G SFP28 8086 158b 154c
Intel i40e 10G X710 SFP 8086 1572 154c
Intel i40e XXV710 N3000 8086 0d58 154c
Intel i40e 40G XL710 QSFP 8086 1583 154c
Intel ice Columbiaville E810-CQDA2 2CQDA2 8086 1592 1889
Intel ice Columbiaville E810-XXVDA4 8086 1593 1889
Intel ice Columbiaville E810-XXVDA2 8086 159b 1889
Nvidia mlx5 ConnectX-4 15b3 1013 1014
Nvidia mlx5 ConnectX-4LX 15b3 1015 1016
Nvidia mlx5 ConnectX-5 15b3 1017 1018
Nvidia mlx5 ConnectX-5 Ex 15b3 1019 101a
Nvidia mlx5 ConnectX-6 15b3 101b 101c
Nvidia mlx5 ConnectX-6_Dx 15b3 101d 101e
Nvidia mlx5 MT42822 BlueField-2 integrated ConnectX-6 Dx 15b3 a2d6 101e