最適なコンテナ ネットワークのための DPDK vRouter の導入
DPDK の概要
クラウドネイティブのContrail® Networking™ は、データプレーン開発キット(DPDK)をサポートしています。DPDK は、ライブラリとドライバーのオープン ソース セットで、迅速なパケット処理を実現します。クラウドネイティブのContrail Networkingは、DPDK(データプレーン開発キット)vRouter技術により、コンテナネットワークを高速化します。DPDK は、ネットワーク インターフェイス カード(NIC)がアプリケーションのアドレス 空間に直接メモリ アクセス(DMA)パケットを直接送信できるようにすることで、高速パケット処理を可能にします。このパケット ルーティング方法では、NIC からの割り込みのオーバーヘッドを回避するパケットをアプリケーションがポーリングできます。
クラウドネイティブのContrail vRouterは、DPDKを利用することで、コンテナサービス機能のカーネルモジュールDPDKインターフェイスとして実行する場合よりも多くのパケットを毎秒処理できます。クラウドネイティブのContrail Networkingは、DPDK vRouterの処理能力を活用して、需要の高いコンテナサービス機能を強化します。
DPDK を使用して Contrail コンピューティング ノードをプロビジョニングする場合、対応する YAML ファイルは、転送パケットに使用する CPU コア数、DPDK に割り当てる巨大ページの数、DPDK に使用する UIO ドライバを指定します。
DPDK および非 DPDK ワークロード向け DPDK vRouter のサポート
コンテナまたはポッドが DPDK vRouter にアクセスする必要がある場合、次のワークロード タイプが発生します。
- 非 DPDK ワークロード(ポッド):このワークロードには、基になる DPDK vRouter を認識していない非 DPDK ポッド アプリケーションが含まれています。これらのアプリケーションは DPDK 用に設計しておらず、DPDK 機能を使用しません。クラウドネイティブのContrail Networkingでは、このワークロードタイプは通常、DPDK vRouter対応クラスターで機能します。
- コンテナ化された DPDK ワークロード:これらのワークロードは DPDK プラットフォーム上に構築されています。DPDK インターフェイスは、管理および制御機能のデータパスとして機能する vHost プロトコルを使用して起動されます。ポッドはvHostサーバーとして機能し、基盤となるDPDK vRouterはvHostクライアントとして機能します。
- 非 DPDK と DPDK の連携:このポッド内のアプリケーションの管理または制御チャネルが非 DPDK(Veth ペア)で、データパスが DPDK インターフェイスである可能性があります。
非 DPDK ポッドの概要
仮想イーサネット(Veth)ペアが、非 DPDK ポッドのネットワークを配管します。Vethペアの一端はポッドの名前空間にアタッチします。もう一方のエンドはホスト マシンのカーネルにアタッチします。CNI(コンテナネットワークインターフェイス)はVethペアを確立し、IPAM(IPアドレス管理)を使用してIPアドレスを割り当てます。
DPDKポッドの概要
DPDKポッドには、vhostインターフェイスとvirtioインターフェイスが含まれています。ポッドは管理用にvhostインターフェイスを使用し、高スループットのパケット処理アプリケーションにはvirtioインターフェイスを使用します。ポッド内のDPDKアプリケーションは、ホスト内のDPDK vRouterとの通信を確立するためにvhostプロトコルを使用します。DPDK アプリケーションは、UNIX ソケットのファイルパスを確立するための引数を受け取ります。vRouter はこのソケットを使用して制御チャネルを確立し、ネゴシエーションを実行し、高速データパス用の巨大ページの共有メモリ上に vrings を作成します。
非 DPDK ポッドと DPDK ポッドの混在の概要
このポッドには、非 DPDK および DPDK アプリケーションが含まれている場合があります。DPDK 以外のアプリケーションは、非 DPDK インターフェイス(Veth ペア)を使用し、DPDK アプリケーションは DPDK インターフェイス(vhost、virtio)を使用します。この 2 つのワークロードは同時に発生します。
DPDK vRouter アーキテクチャ
Contrail DPDK vRouter は、Contrail コンピューティング ノード内で動作するコンテナです。vRouter は Linux カーネル モジュールまたはユーザー スペース DPDK プロセスとして動作し、物理デバイス上の仮想ワークロード(テナント、ゲスト)間でパケットを送信します。vRouter は、仮想インターフェイスと物理インターフェイス間でパケットも送信します。
クラウドネイティブのContrail vRouterは、以下のカプセル化プロトコルをサポートしています。
- MPLS over UDP(MPLSoUDP)
- MPLS over GRE(MPLSoGRE)
- VXLAN(仮想拡張LAN)
従来の Linux カーネル導入と比較して、ユーザー スペース DPDK プロセスとして vRouter を導入すると、vRouter アプリケーションのパフォーマンスと処理速度が大幅に向上します。このパフォーマンスの向上は、以下の要因によって発生します。
- ユーザー空間で動作する仮想ネットワーク機能(VNF)は、DPDK向けに構築されており、DPDKのパケット処理能力を活用するように設計されています。
- DPDK のポーリング モード ドライバー (PMD) は、Linux カーネルの割り込みベース ドライバーではなく、VM のホストの物理インターフェイス (NIC) を使用します。NIC のレジスタは、DPDK の PMD でアクセス可能なユーザー空間で動作します。
その結果、Linux OS は NIC のレジスタを管理する必要はありません。これは、DPDK アプリケーションが NIC のすべてのパケット ポーリング、パケット処理、およびパケット転送を管理することを意味します。DPDK アプリケーションは、I/O 割り込みが発生するのを待つ代わりに、パケットを常にポーリングし、受信した直後にこれらのパケットを処理します。
コンテナ向け DPDK インターフェイスのサポート
DPDK のメリットとアーキテクチャは、通常、VM ネットワークを最適化します。クラウドネイティブのContrail Networkingでは、Kubernetesコンテナでこれらの機能を最大限に活用できます。Kubernetesでは、コンテナ化されたDPDKポッドには通常、2つ以上のインターフェイスが含まれています。DPDKポッドのバックボーンを形成するインターフェイスは次のとおりです。
- Vhostユーザープロトコル(管理用): vhostユーザープロトコルは、ホストとインターフェイスするバックエンドコンポーネントです。クラウドネイティブのContrail Networkingでは、vhostインターフェイスは、ポッドとvRouter間の管理および制御機能のデータパスとして機能します。このプロトコルは、以下の 2 つのプレーンで構成されています。
- コントロールプレーンは、UNIXソケットを介してポッドとvRouterの間で情報(DMAのメモリマッピング、データプレーンの確立と終了のための機能ネゴシエーション)を交換します。
- データプレーンは、直接メモリアクセスを介して実装され、ポッドとvRouter間でデータパケットを送信します。
- Virtio インターフェイス(高スループットアプリケーション用): 高レベルでは、virtio はポッドと vRouter 間でパケットを送信する仮想デバイスです。virtioインターフェイスは、ポッドがDPDKライブラリと機能にアクセスできるようにする共有メモリ(shm)ソリューションです。
これらのインターフェイスにより、DPDK vRouter はポッド間でパケットを送信できます。インターフェイスは、vRouterが提供する高度なネットワーク機能(巨大ページ、ロックレスリングバッファ、ポーリングモードドライバー)へのアクセスをポッドに提供します。これらの機能の詳細については、 vhost-usersの領域への移行を参照してください。
アプリケーションは、DPDK を使用して vhost および virtio インターフェイスを作成します。アプリケーションまたはポッドは、DPDK ライブラリを直接使用して UNIX ドメイン ソケットを使用して制御チャネルを確立します。インターフェイスは、共有メモリvringsを使用して、ポッドとvRouterの間でデータパスを確立します。
DPDK vRouter ホストの前提条件
DPDK vRouter を展開するには、ホスト ノードで次の巨大ページと NIC 設定を実行する必要があります。
- 巨大ページ構成: DPDK 巨大ページ用に予約するホスト・メモリーの割合を指定します。次のコマンドラインは、2MBに設定された巨大ページを示しています。
GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0 default_hugepagesz=2M hugepagesz=2M hugepages=8192"
次の例では、4 つの 1 GB 巨大ページと 1024 2 MB の巨大ページを割り当てます。
GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0 default_hugepagesz=1G hugepagesz=1G hugepages=4 hugepagesz=2M hugepages=1024"
メモ:巨大ページのサイズに 1 GB を割り当てることをお勧めします。
- IOMMU(入出力メモリ管理ユニット)を有効にする:DPDK アプリケーションには IOMMU のサポートが必要です。IOMMU 設定を構成し、BIOS から IOMMU を有効にします。IOMMU を有効にするには、ブート パラメーターとして以下のフラグを適用します。
"intel_iommu=on iommu=pt"
- カーネル ドライバーがホストの NIC のポート転送 0 (ポート 0) に読み込まれていないことを確認します。DPDK PMD ドライバーがホストの NIC のポート転送 1 (ポート 1) にロードされていることを確認します。
メモ:
DPDK とカーネル ドライバーの両方が一般的な NIC の異なるポートを使用する環境では、NIC 上のポート 0 にバインドされているカーネル ドライバーと、その NIC のポート 1 にバインドされた DPDK PMD ドライバーを使用して DPDK ノードを展開することを強くお勧めします。他のポート割り当て構成では、パフォーマンスの問題が発生する可能性があります。詳細については、次の DPDK ドキュメントのセクション 24.9.11 を参照してください: I40E ポーリング モード ドライバー。
- PCIドライバー(vfio-pci、uio_pci_generic):NICタイプに基づいて使用するPCIドライバを指定します。
メモ:
vfio-pciが内蔵されています。
-
uio_pci_generic
- 必要に応じて、uio_pci_generic モジュールを手動で取り付けます。
root@node-dpdk1:~# apt install linux-modules-extra-$(uname -r)
- uio_pci_generic モジュールが取り付けられていることを確認します。
root@node-dpdk1:~# ls /lib/modules/5.4.0-59-generic/kernel/drivers/uio/ uio.ko uio_dmem_genirq.ko uio_netx.ko uio_pruss.ko uio_aec.ko uio_hv_generic.ko 'uio_pci_generic.ko' uio_sercos3.ko uio_cif.ko uio_mf624.ko uio_pdrv_genirq.ko
- 必要に応じて、uio_pci_generic モジュールを手動で取り付けます。
-
コンピューティング ノードに DPDK vRouter を使用した Kubernetes クラスタの導入
クラウドネイティブのContrail Networkingは、DPDK導入者を利用して、DPDK互換性のあるKubernetesクラスタを起動します。この導入者は、ライフサイクル管理機能を実行し、DPDK vRouter の前提条件を適用します。DPDK vRouter のカスタム リソース(CR)は、導入者のサブセットです。CR には次のものが含まれています。
-
クラウドネイティブのContrail Networkingリソースを導入するためのコントローラ
-
vRouter 用コントローラ ロジックが組み込まれています。
DPDK デプロイ者 YAML を適用し、次のコマンドを使用して DPDK vRouter CR agentModeType: dpdk
をデプロイします。
kubectl apply -f <vrouter_cr.yaml>
CR YAML を適用すると、デプロイ者は vRouter の デーモンセット を作成します。このデモンセットは、DPDKコンテナでポッドをスピンアップします。
エラーメッセージが表示された場合は、以下のコマンドを使用して、クラスターにvRouterのカスタムリソース定義(CRD)があることを確認してください。
kubectl get crds
以下に、受信した出力の例を示します。
NAME CREATED AT vrouters.dataplane.juniper.net 2021-06-16T16:06:34Z
クラスタに CRD が存在しない場合は、次のコマンドを使用して導入者を確認します。
kubectl get deployment contrail-k8s-deployer -n contrail-deploy -o yaml
コンテナで使用されているイメージを contrail-k8s-crdloader
確認します。この画像は、導入者が使用する最新の画像である必要があります。画像を更新し、新しいポッドがこのイメージを使用していることを確認します。
新しいポッドが最新のイメージを実行していることを確認した後、以下のコマンドを使用して、vRouter の CRD が存在することを確認します。
kubectl get crds
vRouter の CRD が存在することを確認した後、以下のコマンドを使用して vRouter CR を適用します。
kubectl apply -f <vrouter_cr.yaml>
DPDK vRouter カスタム リソース設定
vRouterのCRの以下の設定を行うことができます。
service_core_mask
:サービスコアマスクを指定します。サービスコアマスクにより、サービスにCPUコアを動的に割り当てることができます。以下の入力形式を入力できます。
-
16進法(例:0xf)
-
カンマで区切られた CPU のリスト(例:1,2,4)
-
ダッシュで区切られた CPU の範囲(1~4 など)
メモ:PMD には、パケット処理に使用可能な CPU コアの大部分が必要です。その結果、 および
dpdk_ctrl_thread_mask
には最大 1~2 CPU コアをservice_core_mask
予約することをお勧めします。この 2 つのコアは CPU 電力を共有します。-
cpu_core_mask
:CPU コア マスクを指定します。DPDK の PMD は、これらのコアを高スループットのパケット処理アプリケーションに使用します。以下は、サポートされている入力形式です。
-
16進法(例:0xf)
-
カンマで区切られた CPU のリスト(例:1,2,4)
-
ダッシュで区切られた CPU の範囲(1~4 など)
-
dpdk_ctrl_thread_mask
:制御スレッド マスクを指定します。DPDK は、これらのコア スレッドを内部処理に使用します。以下は、サポートされている入力形式です。
-
16進法(例:0xf)
-
カンマで区切られた CPU のリスト(例:1,2,4)
-
ダッシュで区切られた CPU の範囲(1~4 など)
メモ:PMD には、パケット処理に使用可能な CPU コアの大部分が必要です。その結果、 および
dpdk_ctrl_thread_mask
には最大 1~2 CPU コアをservice_core_mask
予約することをお勧めします。この 2 つのコアは CPU 電力を共有します。-
dpdk_command_additional_args
:デフォルト設定ではない DPDK vRouter 設定を指定します。ここで入力した引数は、DPDK PMD コマンド ラインの末尾に追加されます。引数の例を以下に示します。
.--yield_option 0