42 通信機能の設定 #
このセクションでは、SUSE Telco Cloudを介してデプロイされたクラスタの通信事業者固有の機能の設定について記述および説明します。
ダイレクトネットワークプロビジョニングのデプロイメント方法を使用します。この方法については、自動化されたプロビジョニング(第43章 「完全に自動化されたダイレクトネットワークプロビジョニング」)に関するセクションで説明しています。
このセクションでは、次のトピックについて説明します。
リアルタイム用のカーネルイメージ(42.1項 「リアルタイム用のカーネルイメージ」): リアルタイムカーネルで使用するカーネルイメージ。
低レイテンシとハイパフォーマンスのためのカーネル引数(42.2項 「低レイテンシとハイパフォーマンスのためのカーネル引数」): 通信ワークロードを最大のパフォーマンスと低レイテンシで実行するために、リアルタイムカーネルによって使用されるカーネル引数。
ホスト上のCPUピニング(42.3項 「ホスト上のCPUピニング」): カーネル引数とTuneDプロファイルを介してCPUを分離します。
Kubernetes上のCPUピニング(42.4項 「KubernetesでのCPUピニング」): Kubelet設定を介してKubernetes上のCPUを分離します。
CNI設定(42.5項 「CNI設定」): Kubernetesクラスタで使用するCNI設定。
SR-IOV設定(42.6項 「SR-IOV」): Kubernetesワークロードで使用するSR-IOV設定。
DPDK設定(42.7項 「DPDK」): システムで使用するDPDK設定。
vRANアクセラレーション(42.8項 「vRANアクセラレーション(
Intel ACC100/ACC200)」): FECアルゴリズムの計算をvRANアクセラレーション カードにオフロードします。Huge Page (42.9項 「Huge Page」): Kubernetesワークロードで使用するHuge Pageの設定。
NUMA対応のスケジューリング設定(42.10項 「NUMA対応のスケジューリング」): Kubernetesワークロードで使用するNUMA対応のスケジューリング設定。
Metal LB設定(42.11項 「MetalLB」): Kubernetesワークロードで使用するMetal LB設定。
プライベートレジストリ設定(42.12項 「プライベートレジストリ設定」): Kubernetesワークロードで使用するプライベートレジストリ設定。
Precision Time Protocolの設定(42.13項 「Precision Time Protocol」): 実行中のPTP通信事業者プロファイルの設定ファイル。
42.1 リアルタイム用のカーネルイメージ #
リアルタイムカーネルイメージは必ずしも標準カーネルより優れているとは限りません。リアルタイムカーネルは、特定のユースケース用に調整された別のカーネルです。低レイテンシを実現するために調整されていますが、その結果、スループットが犠牲になります。リアルタイムカーネルは一般的な用途には推奨されませんが、ここでは低レイテンシが重要な要因である通信ワークロード用のカーネルとして推奨されています。
主に4つの機能があります。
決定論的実行:
予測可能性の向上 — 高負荷状態でも重要なビジネスプロセスが期限内に確実に完了し、常に高品質なサービスを提供します。高優先度プロセスのために重要なシステムリソースを保護することで、時間に依存するアプリケーションの予測可能性を向上できます。
低ジッタ:
高度に決定論的な技術に基づいてジッターが低く抑えられているため、アプリケーションと実世界との同期を維持できます。これは、継続的に繰り返し計算を行う必要があるサービスで役立ちます。
優先度の継承:
優先度の継承とは、優先度の高いプロセスがある状況において、そのプロセスがタスクを完了するためには優先度の低いプロセスが完了するのを待つ必要がある場合に、優先度の低いプロセスが高優先度を一時的に引き受ける機能です。SUSE Linux Enterprise Real Timeは、ミッションクリティカルなプロセスにおけるこのような優先度の逆転の問題を解決します。
スレッドの割り込み:
一般的なオペレーティングシステムでは、割り込みモードで実行中のプロセスはプリエンプト可能ではありません。SUSE Linux Enterprise Real Timeでは、このような割り込みをカーネルスレッドでカプセル化して割り込み可能にし、ユーザが定義した高優先度プロセスでハード割り込みとソフト割り込みをプリエンプトできます。
ここでは、
SUSE Linux Micro RTのようなリアルタイムイメージをインストール済みの場合、カーネルリアルタイムはすでにインストールされています。リアルタイムカーネルイメージはSUSE Customer Centerからダウンロードできます。
42.2 低レイテンシとハイパフォーマンスのためのカーネル引数 #
リアルタイムカーネルを適切に動作させ、通信ワークロードを実行する際には、最高のパフォーマンスと低レイテンシ実現できるようにカーネル引数を設定することが重要です。このユースケースのカーネル引数を設定する際には、いくつかの重要な概念を念頭に置く必要があります。
SUSEリアルタイムカーネルを使用する際には、
kthread_cpusを削除します。このパラメータは、カーネルスレッドが作成されるCPUを制御します。また、PID 1とカーネルモジュール(kmodユーザスペースヘルパー)のロードにどのCPUが許可されるかも制御します。このパラメータは認識されず、影響は何もありません。isolcpus、nohz_full、rcu_nocbs、およびirqaffinityを使用してCPUコアを分離します。CPUピニング技術の包括的なリストについては、 「ホスト上のCPUピニング」(42.3項 「ホスト上のCPUピニング」)の章を参照してください。domain,nohz,managed_irqフラグをisolcpusカーネル引数に追加します。何もフラグを指定しない場合、isolcpusはdomainフラグのみを指定するのと同等になります。これにより、指定したCPUがカーネルタスクを含むスケジューリングから分離されます。nohzフラグは指定されたCPUのスケジューラティックを停止し(CPUで実行できるタスクが1つのみの場合)、managed_irqフラグは指定したCPUの管理対象の外部(デバイス)割り込みのルーティングを回避します。NVMeデバイスのIRQラインはカーネルによって完全に管理されており、その結果、非分離(ハウスキーピング)コアにルーティングされることに注意してください。たとえば、このセクションの最後に示されたコマンドラインを実行すると、システムに割り当てられるキューは4つ(および管理/制御キュー)のみとなります。for I in $(grep nvme0 /proc/interrupts | cut -d ':' -f1); do cat /proc/irq/${I}/effective_affinity_list; done | column 39 0 19 20 39この動作は、分離されたコア上で実行中の時間的制約のあるアプリケーションに対するディスク I/O による中断を防止します。ただし、ストレージに重点を置いたワークロードの場合、注意と慎重な設計が必要になる可能性があります。
ティック(カーネルの定期的なタイマー割り込み)を調整します。
skew_tick=1: ティックは同時に発生する場合があります。skew_tick=1を指定すると、すべてのCPUがタイマーティックを正確に同じタイミングで受信するのではなく、わずかにオフセットされたタイミングで発生させます。これにより、システムジッターが軽減され、より一貫性があり低い割り込み応答時間(レイテンシに敏感なアプリケーションにとって不可欠な要件)が可能になります。nohz=on: アイドル状態のCPUにおける定期的なタイマーティックを停止します。nohz_full=<cpu-cores>: リアルタイムアプリケーション専用の指定されたCPUにおける定期的なタイマーティックを停止します。
mce=offを指定して、マシンチェック例外(MCE)の処理を無効にします。MCEはプロセッサによって検出されるハードウェアエラーであり、無効にすることで、ノイズの多いログを回避できます。nowatchdogを追加して、タイマーのハード割り込みコンテキストで実行されるタイマーとして実装されるソフトロックアップウォッチドッグを無効にします。有効期限が切れると(すなわち、ソフトロックアップが検出されると)、(ハード割り込みコンテキストで)警告が出力され、あらゆるレイテンシターゲットを実行します。有効期限が切れていない場合でも、タイマーリストに追加され、タイマー割り込みのオーバーヘッドがわずかに増加します。このオプションは、NMIウォッチドッグも無効にするため、NMIが干渉できなくなります。nmi_watchdog=0は、NMI (Non-Maskable Interrupt)ウォッチドッグを無効にします。nowatchdogが使用される場合は省略できます。RCU (Read-Copy-Update)は、共有データに対して多数のリーダが同時にロックなしでアクセスできるようにするカーネルメカニズムです。RCUコールバックは、一定の「猶予期間」後にトリガされる関数で、すべての以前のリーダが終了していることを確認し、古いデータを安全に再利用できるようにします。SUSEでは、特に機密性の高いワークロード向けにRCUを微調整し、これらのコールバックを専用(ピニングされた)CPUからオフロードすることで、カーネル操作が重要な時間的制約のあるタスクと干渉しないようにしています。
rcu_nocbsでピニングされたCPUを指定し、RCUコールバックがそのCPU上で実行されないようにします。これにより、リアルタイムワークロードのジッターとレイテンシを軽減できます。rcu_nocb_pollは、コールバック処理が必要かどうかを確認するために、no-callback CPUを定期的に「ポーリング」させます。これにより、割り込みのオーバーヘッドを削減できます。rcupdate.rcu_cpu_stall_suppress=1は、RCU CPUストール警告を抑制します。これは、高負荷のリアルタイムシステムでは偽陽性となる場合があります。rcupdate.rcu_expedited=1は、RCU操作の猶予期間を短縮し、読み取り側のクリティカルセクションの応答性を向上させます。rcupdate.rcu_normal_after_boot=1: rcu_expeditedとともに使用する場合、システム起動後にRCUが通常の(非迅速)動作に戻ることができます。rcupdate.rcu_task_stall_timeout=0は、RCUタスクのストール検出機能を無効にし、長時間実行されるRCUタスクによる潜在的な警告やシステム停止を防止します。rcutree.kthread_prio=99は、RCUコールバックカーネルスレッドの優先度を可能な限り最高(99)に設定し、必要に応じてRCUコールバックがスケジュールされ、迅速に処理されるようにします。
Metal3とCluster APIに
ignition.platform.id=openstackを追加し、クラスタのプロビジョニング/プロビジョニング解除が正常に実行されるようにします。これは、Openstack Ironic由来のMetal3 Pythonエージェントによって使用されます。intel_pstate=passiveを削除します。このオプションは、intel_pstateを汎用cpufreqガバナーと連携するように設定しますが、この連携を行うには、副作用として、ハードウェア管理P状態(HWP)を無効にします。ハードウェアのレイテンシを削減するため、このオプションはリアルタイムワークロードには推奨されません。intel_idle.max_cstate=0 processor.max_cstate=1をidle=pollに置き換えます。C-Stateの遷移を回避するには、idle=pollオプションを使用してC-Stateの遷移を無効にし、CPUを最高のC-Stateに維持します。intel_idle.max_cstate=0オプションは、intel_idleを無効にするため、acpi_idleが使用され、acpi_idle.max_cstate=1がacpi_idleの最大のC-stateを設定します。AMD64/Intel 64アーキテクチャでは、最初のACPI C-Stateは常にPOLLですが、poll_idle()関数を使用しており、定期的にクロックを読み取ることで、タイムアウト後にdo_idle()でメインループを再起動する際に、若干のレイテンシが発生する可能性があります(これにはTIF_POLLタスクフラグのクリアと設定も含まれます)。これに対して、idle=pollはタイトなループで実行され、タスクが再スケジュールされるのをビジーウェイトします。これにより、アイドル状態から抜け出すまでのレイテンシが最小化されますが、その代償としてCPUがアイドルスレッドでフルスピードで稼働し続けることになります。BIOSのC1Eを無効にします。このオプションは、BIOSでC1E状態を無効にし、アイドル時にCPUがCIE状態になるのを回避します。C1E状態は、CPUがアイドル状態のときにレイテンシを発生される可能性のある低電力状態です。
このドキュメントの残りの部分では、追加のパラメータ(Huge PageやIOMMUなど)について説明します。
以下は、前述の調整を含む32コアのIntelサーバのカーネル引数の例です。
$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=77b713de-5cc7-4d4c-8fc6-f5eca0a43cf9 skew_tick=1 rd.timeout=60 rd.retry=45 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack intel_iommu=on iommu=pt irqaffinity=0,31,32,63 isolcpus=domain,nohz,managed_irq,1-30,33-62 nohz_full=1-30,33-62 nohz=on mce=off nosoftlockup nowatchdog nmi_watchdog=0 quiet rcu_nocb_poll rcu_nocbs=1-30,33-62 rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=poll以下は、64コアのAMDサーバのもう1つの設定例です。128個の論理プロセッサ(0-127)のうち、最初の8コア(0-7)はハウスキーピング用に指定され、残りの120コア(8-127)はアプリケーション用に固定されます。
$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=575291cf-74e8-42cf-8f2c-408a20dc00b8 skew_tick=1 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack amd_iommu=on iommu=pt irqaffinity=0-7 isolcpus=domain,nohz,managed_irq,8-127 nohz_full=8-127 rcu_nocbs=8-127 mce=off nohz=on nowatchdog nmi_watchdog=0 nosoftlockup quiet rcu_nocb_poll rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=poll42.3 ホスト上のCPUピニング #
CPUピニング(プロセッサアフィニティとも呼ばれる)は、特定のCPUコアにプロセスやスレッドをバインドし、オペレーティングシステムのスケジューラがそれを移動させないようにする手法です。プロセスが常に同じコアで確実に実行されるようにすることで、そのコアのキャッシュメモリに残っているデータへのアクセスが高速化されるメリットがあります。この手法は、パフォーマンスを劇的に改善し、オーバーヘッドを削減するため、ハイパフォーマンスコンピューティング環境で一般的に使用されています。
42.3.1 TuneDによるCPUの分離 #
tunedは、さまざまな事前定義済みプロファイルを使用して、システム状態を監視し、パフォーマンスを最適化するシステムチューニングツールです。主要な機能は、リアルタイムアプリケーションのなどの特定のワークロードに対してCPUコアを分離する機能です。この機能により、OSがこれらのコアを使用するのを防止し、潜在的にレイテンシが増加するのを回避します。
この機能を有効にして設定するには、まず、分離するCPUコアのプロファイルを作成します。この例では、64コアのうち、60コア(1-30、33-62)をアプリケーション専用にし、残りの4コアをハウスキーピングに使用します。分離されたCPUの設計は、リアルタイムアプリケーションに大きく依存することに注意してください。
$ echo "export tuned_params" >> /etc/grub.d/00_tuned
$ echo "isolated_cores=1-30,33-62" >> /etc/tuned/cpu-partitioning-variables.conf
$ tuned-adm profile cpu-partitioning
Tuned (re)started, changes applied.42.3.2 カーネル引数によるCPUの分離 #
次に、GRUBオプションを変更して、CPUコアと、CPUの使用法に関するその他の重要なパラメータを分離する必要があります。現在のハードウェア仕様で次のオプションをカスタマイズすることが重要です。
| パラメータ | 値 | 説明 |
|---|---|---|
isolcpus | domain、nohz、managed_irq、1-3、33-62 | コア1-30と33-62を分離します。 |
skew_tick | 1 | このオプションを使用すると、カーネルは分離されたCPU全体でタイマー割り込みをずらすことができます。 |
nohz | on | 有効にすると、カーネルの定期的なタイマー割り込み(「ティック」)は、アイドル状態のCPUコアで停止します。これにより、主にハウスキーピング用CPU
( |
nohz_full | 1-30、33-62 | 分離されたコアの場合、これによりティックが停止され、CPUが単一のアクティブなタスクを実行している場合でも停止されます。つまり、CPUは完全なティックレスモード(または「dyntick」)で動作します。カーネルは、実際に必要な場合にのみタイマー割り込みを発生させます。 |
rcu_nocbs | 1-30、33-62 | このオプションは、指定のCPUコアからRCUコールバック処理をオフロードします。 |
rcu_nocb_poll | このオプションを設定すると、no-RCU-callback CPUは、他のCPUによって明示的にウェイクアップされるのではなく、コールバック処理が必要かどうかを確認するために定期的に「ポーリング」します。これにより、割り込みオーバーヘッドを削減できます。 | |
irqaffinity | 0、31、32、63 | このオプションを使用すると、カーネルはハウスキーピング用コアに割り込みを実行できるようになります。 |
idle | poll | これにより、アイドル状態から抜け出すまでのレイテンシが最小化されますが、その代償として、CPUがアイドルスレッドでフルスピードで稼働し続けることになります。 |
nmi_watchdog | 0 | このオプションはNMIウォッチドッグのみを無効にします。 |
nowatchdog | このオプションは、タイマーのハード割り込みコンテキストで実行されるタイマーとして実装されるソフトロックアップウォッチドッグを無効にします。 |
次のコマンドでGRUB設定を変更し、上記の変更を次回ブート時に適用します。
上記パラメータを使用して/etc/default/grubファイルを編集します。ファイルは次のようになります。
GRUB_CMDLINE_LINUX="BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=77b713de-5cc7-4d4c-8fc6-f5eca0a43cf9 skew_tick=1 rd.timeout=60 rd.retry=45 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack intel_iommu=on iommu=pt irqaffinity=0,31,32,63 isolcpus=domain,nohz,managed_irq,1-30,33-62 nohz_full=1-30,33-62 nohz=on mce=off nosoftlockup nowatchdog nmi_watchdog=0 quiet rcu_nocb_poll rcu_nocbs=1-30,33-62 rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=poll"GRUB設定を更新します。
$ transactional-update grub.cfg
$ reboot再起動後にパラメータが適用されていることを検証するには、次のコマンドを使用してカーネルコマンドラインを確認できます。
$ cat /proc/cmdlineCPU設定を調整するために使用可能な別のスクリプトがあります。これは基本的には次の手順を実行します。
CPUガバナーを
パフォーマンスに設定します。分離されたCPUへのタイマーのマイグレーションの設定を解除します。
kdaemonスレッドをハウスキーピング用CPUに移行します。
分離したCPUレイテンシを可能な限り低い値に設定します。
vmstatの更新を300秒に遅延させます。
スクリプトはSUSE Telco Cloudサンプルリポジトリで入手できます。
42.4 KubernetesでのCPUピニング #
42.4.1 RKE2バージョン < v1.32 #
RKE2設定ファイルを編集して、RKE2クラスタでCPUピニングを有効にします。/etc/rancher/rke2/config.yamlファイルに以下のkubelet引数を追加します。kubelet-reservedおよびsystem-reserved引数でハウスキーピングCPUコアを指定してください。
kubelet-arg:
- "cpu-manager-policy=static"
- "cpu-manager-policy-options=full-pcpus-only=true"
- "cpu-manager-reconcile-period=0s"
- "kubelet-reserved=cpu=0,31,32,63"
- "system-reserved=cpu=0,31,32,63"42.4.2 RKE2バージョン >= v1.32 #
RKE2バージョンがv1.32以上の場合、アップストリームKubernetesの慣例に従い、コマンドライン引数を使用してkubeletを設定することはできません。CPUピニングを設定するには、kubelet設定ファイルを作成する必要があります。RKE2のドキュメントを参照してください。
01-cpu-pinning.confなどの新しいkubelet設定ファイルを作成し、/var/lib/rancher/rke2/agent/etc/kubelet.conf.d/ディレクトリに配置します。
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cpuManagerPolicy: static
reservedSystemCPUs: 0,31,32,63
topologyManagerPolicy: single-numa-node設定の変更を反映させるには、適切なRKE2サービス(サーバまたはエージェント)を再起動する必要があります。このアクションにより、ホスト上のRKE2サービスが一時的に中断します。ノードタイプに応じて、次のコマンドの1つのみを実行します。
# If the node is RKE2 agent
systemctl restart rke2-agent
# Else if the node is RKE2 server
systemctl restart rke2-server42.4.3 固定されたCPUを活用したワークロードのデプロイ #
kubeletで定義された静的ポリシーを使ってCPUピニング機能を使用する方法は、ワークロードに対して定義した要求と制限に応じて3つあります。
BestEffortQoSクラス:CPUに対して要求または制限を定義していない場合、Podはシステムで使用できる最初のCPUでスケジュールされます。BestEffortQoSクラスを使用する例を次に示します。spec: containers: - name: nginx image: nginxBurstableQoSクラス: CPUに対して要求を定義し、その要求が制限と同じではない場合、またはCPUの要求がない場合。BurstableQoSクラスを使用する例を次に示します。spec: containers: - name: nginx image: nginx resources: limits: memory: "200Mi" requests: memory: "100Mi"または
spec: containers: - name: nginx image: nginx resources: limits: memory: "200Mi" cpu: "2" requests: memory: "100Mi" cpu: "1"GuaranteedQoSクラス: CPUに対して要求を定義し、その要求が制限と同じである場合。GuaranteedQoSクラスを使用する例を次に示します。spec: containers: - name: nginx image: nginx resources: limits: memory: "200Mi" cpu: "2" requests: memory: "200Mi" cpu: "2"
42.5 CNI設定 #
42.5.1 Cilium #
CiliumはSUSE Telco
CloudのデフォルトのCNIプラグインです。RKE2クラスタでCiliumをデフォルトのプラグインとして有効にするには、/etc/rancher/rke2/config.yamlファイルに次の設定が必要です。
cni:
- ciliumこれはコマンドライン引数でも指定できます。具体的には、/etc/systemd/system/rke2-serverファイルのサーバの行に--cni=ciliumを追加します。
42.6.2項 「オプション2 (推奨): SR-IOV Network Operator」で説明されているSR-IOVネットワークをCiliumと併用するには、
multusメタプラグインをデプロイします。multusが他のCNIよりも前にリストされていることを確認してください。
cni:
- multus
- cilium42.5.2 Calico #
Calicoは、SUSE Edge for
Telco用の別のCNIプラグインです。RKE2クラスタ上でデフォルトプラグインとしてCalicoを有効にするには、/etc/rancher/rke2/config.yamlファイルに次の設定が必要です。
cni:
- calicoこれは、コマンドライン引数で指定することもできます。つまり、--cni=calicoを/etc/systemd/system/rke2-serverファイルのサーバ行に追加します。
42.6.2項 「オプション2 (推奨): SR-IOV Network Operator」で説明されているSR-IOVネットワークをCalicoと併用するには、
multusメタプラグインをデプロイします。multusが他のCNIよりも前にリストされていることを確認してください。
cni:
- multus
- calico42.5.3 Bond CNI #
一般的に、ボンディングは複数のネットワークインタフェースを単一の論理的な「ボンディング」インタフェースに集約する方法を提供します。これは通常、冗長なネットワーキングパスを導入することでサービスの可用性を向上させるために使用されますが、特定のボンディングモードで帯域幅を増やすためにも使用できます。multusと組み合わせてBond CNIプラグインでは、以下のCNIプラグインがサポートされています。
MACVLAN
ホストデバイス
SR-IOV
42.5.3.1 Bond CNIとMACVLAN #
Bond CNIプラグインとMACVLANを組み合わせて使用するには、コンテナ内に2つの空きインタフェースが必要です。以下の例では、「enp8s0」と「enp9s0」を使用しています。まず、これらのインタフェースに対するネットワークアタッチメント定義を作成します。
NetworkAttachmentDefinition enp8s0
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: enp8s0-conf
spec:
config: '{
"cniVersion": "0.3.1",
"plugins": [
{
"type": "macvlan",
"capabilities": { "ips": true },
"master": "enp8s0",
"mode": "bridge",
"ipam": {}
}, {
"capabilities": { "mac": true },
"type": "tuning"
}
]
}'NetworkAttachmentDefinition enp9s0
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: enp9s0-conf
spec:
config: '{
"cniVersion": "0.3.1",
"plugins": [
{
"type": "macvlan",
"capabilities": { "ips": true },
"master": "enp9s0",
"mode": "bridge",
"ipam": {}
}, {
"capabilities": { "mac": true },
"type": "tuning"
}
]
}'この後で、ボンド自体のネットワークアタッチメント定義を追加します。
NetworkAttachmentDefinition bond
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: bond-net1
spec:
config: '{
"type": "bond",
"cniVersion": "0.3.1",
"name": "bond-net1",
"mode": "active-backup",
"failOverMac": 1,
"linksInContainer": true,
"miimon": "100",
"mtu": 1500,
"links": [
{"name": "net1"},
{"name": "net2"}
],
"ipam": {
"type": "static",
"addresses": [
{
"address": "192.168.200.100/24",
"gateway": "192.168.200.1"
}
],
"subnet": "192.168.200.0/24",
"routes": [{
"dst": "0.0.0.0/0"
}]
}
}'ここでのIPアドレス割り当ては静的であり、ボンドのアドレスを/24ネットワーク上の「192.168.200.100」と定義し、ゲートウェイはネットワークで最初に利用可能なアドレス上に配置されます。ボンドのネットワークアタッチメントでは、必要なボンドのタイプも定義します。この場合はactive-backupです。
このボンドを使用するには、ポッドがすべてのインタフェースについて認識している必要があります。ポッド定義例は次のようになります。
apiVersion: v1
kind: Pod
metadata:
name: test-pod
annotations:
k8s.v1.cni.cncf.io/networks: '[
{"name": "enp8s0-conf",
"interface": "net1"
},
{"name": "enp9s0-conf",
"interface": "net2"
},
{"name": "bond-net1",
"interface": "bond0"
}]'
spec:
restartPolicy: Never
containers:
- name: bond-test
image: alpine:latest
command:
- /bin/sh
- "-c"
- "sleep 60m"
imagePullPolicy: IfNotPresentアノテーションがすべてのネットワークをどのように参照しているか、およびインタフェース「enp8s0 → net1」と「enp9s0→net2」間のマッピングをどのように定義しているかに注意してください。
42.5.3.2 Bond CNIとホストデバイス #
Bond CNIプラグインとホストデバイスを組み合わせて使用するには、ホスト上に2つの空きインタフェースが必要です。これらのインタフェースはコンテナにマッピングされます。以下の例では、「enp8s0」と「enp9s0」を使用しています。まず、これらのインタフェースに対するネットワークアタッチメント定義を作成します。
NetworkAttachmentDefinition enp8s0
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: enp8s0-hostdev
spec:
config: '{
"cniVersion": "0.3.1",
"plugins": [
{
"type": "host-device",
"name": "host0",
"device": "enp8s0",
"ipam": {}
}]
}'NetworkAttachmentDefinition enp9s0
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: enp9s0-hostdev
spec:
config: '{
"cniVersion": "0.3.1",
"plugins": [
{
"type": "host-device",
"name": "host0",
"device": "enp9s0",
"ipam": {}
}]
}'この後で、ボンド自体のネットワークアタッチメント定義を追加します。これはMACVLANの使用例と同様です。
NetworkAttachmentDefinition bond
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: bond-net1
spec:
config: '{
"type": "bond",
"cniVersion": "0.3.1",
"name": "bond-net1",
"mode": "active-backup",
"failOverMac": 1,
"linksInContainer": true,
"miimon": "100",
"mtu": 1500,
"links": [
{"name": "net1"},
{"name": "net2"}
],
"ipam": {
"type": "static",
"addresses": [
{
"address": "192.168.200.100/24",
"gateway": "192.168.200.1"
}
],
"subnet": "192.168.200.0/24",
"routes": [{
"dst": "0.0.0.0/0"
}]
}
}'ここでのIPアドレス割り当ては静的であり、ボンドのアドレスを/24ネットワーク上の「192.168.200.100」と定義し、ゲートウェイはネットワークで最初に利用可能なアドレス上に配置されます。ボンドのネットワークアタッチメントでは、ボンドのタイプを定義します。この場合はactive-backupです。
このボンドを使用するには、ポッドがすべてのインタフェースについて認識している必要があります。ホストデバイスとのボンドのポッド定義例は次のようになります。
apiVersion: v1
kind: Pod
metadata:
name: test-pod
annotations:
k8s.v1.cni.cncf.io/networks: '[
{"name": "enp8s0-hostdev",
"interface": "net1"
},
{"name": "enp9s0-hostdev",
"interface": "net2"
},
{"name": "bond-net1",
"interface": "bond0"
}]'
spec:
restartPolicy: Never
containers:
- name: bond-test
image: alpine:latest
command:
- /bin/sh
- "-c"
- "sleep 60m"
imagePullPolicy: IfNotPresent42.5.3.3 Bond CNIとSR-IOV #
Bond CNIをSR-IOVと組み合わせて使用するのは非常に簡単です。SR-IOVの設定方法の詳細については、42.6項 「SR-IOV」を参照してください。そこに記載されているとおりに、SriovNetworkNodePoliciesを作成し、resourceNamesや仮想機能の数などを定義する必要があります。resourceNamesは、ポッド定義でインタフェースとして使用されるSriovNetworkによって使用されます。ボンドの定義は、MACVLANとホストデバイスの場合とまったく同じです。
Bond CNIとSR-IOVの組み合わせは、カーネルドライバを使用するSRIOV仮想機能(VF)にのみ適用されます。DPDKワークロードで使用されるようなユーザスペースドライバのVFは、Bond CNIでボンディングできません。
42.6 SR-IOV #
SR-IOV
(シングルルートI/O仮想化)を使用すると、ネットワークアダプタなどの単一物理デバイスがそのリソースを複数のPCIeハードウェア機能に分割できます。これにより、さまざまなアプリケーションがリソースに直接アクセスできるようになります。
クラスタにSR-IOVをデプロイするには、次の2つの異なる方法があります。
42.6.1項 「オプション1: SR-IOVネットワークデバイスプラグインDaemonsetおよびconfigMap」: この方法はネットワークデバイスとvRANアクセラレータの両方をサポートしています。
42.6.2項 「オプション2 (推奨): SR-IOV Network Operator」: この自動化された方法により、デプロイメントがより単純化されます。この方法は、ネットワークデバイス専用です。
まれに、ネットワークデバイスにはNetwork Operatorを、vRANアクセラレータにはDevice Pluginを使用するといった両方のソリューションが必要な場合は、これらを別々のKubernetesネームスペースにデプロイする必要があります。この分離は2つのデプロイメント間での競合を防ぐために不可欠です。
42.6.1 オプション1: SR-IOVネットワークデバイスプラグインDaemonsetおよびconfigMap #
SR-IOVネットワークデバイスプラグインは、Kubernetesホスト上のPCI物理機能(PF)や仮想機能(VF)などのネットワークリソースを検出し、アドバタイズします。
デバイスプラグイン用の設定マップの準備
SR-IOVリソースプールを定義する設定マップを作成する必要があります。lspciコマンドを実行して情報を取得します。
$ lspci | grep -i acc
8a:00.0 Processing accelerators: Intel Corporation Device 0d5c
$ lspci | grep -i net
19:00.0 Ethernet controller: Broadcom Inc. and subsidiaries BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (rev 11)
19:00.1 Ethernet controller: Broadcom Inc. and subsidiaries BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (rev 11)
19:00.2 Ethernet controller: Broadcom Inc. and subsidiaries BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (rev 11)
19:00.3 Ethernet controller: Broadcom Inc. and subsidiaries BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (rev 11)
51:00.0 Ethernet controller: Intel Corporation Ethernet Controller E810-C for QSFP (rev 02)
51:00.1 Ethernet controller: Intel Corporation Ethernet Controller E810-C for QSFP (rev 02)
51:01.0 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:01.1 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:01.2 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:01.3 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:11.0 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:11.1 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:11.2 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:11.3 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)SR-IOVデバイスプラグインはJSONファイルを含むconfigMapを使用して、
Kubernetesが公開するハードウェアリソースを定義します。この設定は次の2つのコアコンセプトに基づいています:
セレクタ (ハードウェア検出用)とリソース
(Kubernetes公開用)です。
リソースとは、Podが使用する名前付きエンティティです(例:
rancher.io/intel_fec_5g)。リソースは次の2つのタイプのいずれかとして定義できます。
accelerator: vRANアクセラレータカード(ACC100/vRAN Boostなど)に使用されます。netdevice: 標準ネットワークインタフェース(NIC)に使用されます。
セレクタを使用してターゲットデバイス定義し、ノード上のハードウェアをフィルタリングします。
vendors:8086(Intel)devices:0d5d(FECカード)、1889(NIC)drivers:vfio-pcipfNames:p2p1(物理インタフェース名)
ネットワークカードの場合は、物理機能から仮想機能(VF)のサブセットを選択することもできます。
pfNames:["eth1#1,2,3,4,5,6"]または[eth1#1-6]
Podがデバイスを要求できるようにするには、各リソースにプレフィックスと名前で構成される名前を付ける必要があります。
resourceName:pci_sriov_net_bh_dpdkresourcePrefix:Rancher.io
Podは結合されたリソース名を要求します: rancher.io/pci_sriov_net_bh_dpdk。
このドキュメントでは、可能なセレクタをすべてリストしているわけではありません。リソースタイプによって使用するセレクタのセットが異なります。包括的な詳細については、SR-IOVネットワークデバイスプラグインのリポジトリを参照してください。
以下のConfigMapは 3つのリソースを作成する例です。vRANアクセラレータカード(FEC)用が1つ、2つの異なるNICポート用が2つです。
FECカードの場合、まずデバイスIDとVFIOトークンを取得する必要があります。 前提条件については、42.8項 「vRANアクセラレーション(Intel ACC100/ACC200)」の章の手順に従ってください。
apiVersion: v1
kind: ConfigMap
metadata:
name: sriovdp-config
namespace: kube-system
data:
config.json: |
{
"resourceList": [
{
"resourcePrefix": "rancher.io",
"resourceName": "intel_fec_5g",
"deviceType": "accelerator",
"selectors": {
"vendors": ["8086"],
"devices": ["0d5d"]
},
"additionalInfo": {
"*": {
"VFIO_TOKEN": "00112233-4455-6677-8899-aabbccddeeff"
}
}
},
{
"resourcePrefix": "rancher.io",
"resourceName": "intel_sriov_odu",
"deviceType": "netdevice",
"selectors": {
"vendors": ["8086"],
"devices": ["1889"],
"drivers": ["vfio-pci"],
"pfNames": ["p2p1"]
}
},
{
"resourcePrefix": "rancher.io",
"resourceName": "intel_sriov_oru",
"deviceType": "netdevice",
"selectors": {
"vendors": ["8086"],
"devices": ["1889"],
"drivers": ["vfio-pci"],
"pfNames": ["p2p2"]
}
}
]
}デバイスプラグインをデプロイするための
daemonsetファイルを準備します。
デバイスプラグインは複数のアーキテクチャ(arm、amd、ppc64le)をサポートしているため、アーキテクチャごとに複数のdaemonsetをデプロイすることで、同じファイルを異なるアーキテクチャに使用できます。
apiVersion: v1
kind: ServiceAccount
metadata:
name: sriov-device-plugin
namespace: kube-system
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-sriov-device-plugin-amd64
namespace: kube-system
labels:
tier: node
app: sriovdp
spec:
selector:
matchLabels:
name: sriov-device-plugin
template:
metadata:
labels:
name: sriov-device-plugin
tier: node
app: sriovdp
spec:
hostNetwork: true
nodeSelector:
kubernetes.io/arch: amd64
tolerations:
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
serviceAccountName: sriov-device-plugin
containers:
- name: kube-sriovdp
image: registry.suse.com/rancher/hardened-sriov-network-device-plugin:v3.9.0-build20250425
imagePullPolicy: IfNotPresent
args:
- --log-dir=sriovdp
- --log-level=10
securityContext:
privileged: true
resources:
requests:
cpu: "250m"
memory: "40Mi"
limits:
cpu: 1
memory: "200Mi"
volumeMounts:
- name: devicesock
mountPath: /var/lib/kubelet/
readOnly: false
- name: log
mountPath: /var/log
- name: config-volume
mountPath: /etc/pcidp
- name: device-info
mountPath: /var/run/k8s.cni.cncf.io/devinfo/dp
volumes:
- name: devicesock
hostPath:
path: /var/lib/kubelet/
- name: log
hostPath:
path: /var/log
- name: device-info
hostPath:
path: /var/run/k8s.cni.cncf.io/devinfo/dp
type: DirectoryOrCreate
- name: config-volume
configMap:
name: sriovdp-config
items:
- key: config.json
path: config.jsonconfigMapと
daemonsetを適用後、デバイスプラグインがデプロイされ、インタフェースが検出されて、Podで使用可能になります。$ kubectl get pods -n kube-system | grep sriov kube-system kube-sriov-device-plugin-amd64-twjfl 1/1 Running 0 2mインタフェースが検出され、Podで使用可能になっているかどうかすべてのノードを確認します。
$ kubectl get nodes -o json | jq '.items[] | {name: .metadata.name, allocatable: .status.allocatable}' { "name": "node1.suse.edge.com", "allocatable": { "cpu": "64", "ephemeral-storage": "256196109726", "hugepages-1Gi": "40Gi", "hugepages-2Mi": "0", "rancher.io/intel_fec_5g": "16", "rancher.io/intel_sriov_odu": "4", "rancher.io/intel_sriov_oru": "4", "memory": "221396384Ki", "pods": "110" } }FECアクセラレータのresourceNameはrancher.io/intel_fec_5gで、16個のVFが利用可能です。NICカードのresourceNameは
rancher.io/intel_sriov_oduとrancher.io/intel_sriov_oruです。各リソースは4個のVFを提供します。
kubernetesノードでインタフェースが割り当て可能なリソースとして検出されない場合、この問題を解決することが不可欠です。よくある原因の1つは、configMapの仕様の形式が正しくないことです。configMapとそのセレクタを再確認してください。
42.6.2 オプション2 (推奨): SR-IOV Network Operator #
Helmがない場合は入手します。
$ curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bashsriov-network-operatorネームスペースにSR-IOV Network Operatorをインストールします。
helm install sriov-crd oci://registry.suse.com/edge/charts/sriov-crd -n sriov-network-operator
helm install sriov-network-operator oci://registry.suse.com/edge/charts/sriov-network-operator -n sriov-network-operatorデプロイされたCRDとPodを確認します。
$ kubectl get crd
$ kubectl -n sriov-network-operator get podsSR-IOVラベルがノードに適用されているかどうかを確認します。
すべてのリソースが実行されていると、ラベルがノードに自動的に表示されます。
$ kubectl get nodes -oyaml | grep feature.node.kubernetes.io/network-sriov.capable
feature.node.kubernetes.io/network-sriov.capable: "true"daemonsetを確認し、新しいsriov-network-config-daemonおよびsriov-rancher-nfd-workerがアクティブで準備できていることを確認します。
$ kubectl get daemonset -n sriov-network-operator
NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
sriov-network-operator sriov-network-config-daemon 1 1 1 1 1 feature.node.kubernetes.io/network-sriov.capable=true 45m
sriov-network-operator sriov-rancher-nfd-worker 1 1 1 1 1 <none> 45m数分で、ノードが検出され、SR-IOV機能が完全に設定されます。更新には最大10分かかる場合があります。
$ kubectl get sriovnetworknodestates -A
NAMESPACE NAME AGE
sriov-network-operator xr11-2 83sインタフェースが検出されたかどうかを確認します。
検出されたインタフェースはネットワークデバイスのPCIアドレスである必要があります。この情報は、ホストでlspciコマンドを使用して確認します。
$ kubectl get sriovnetworknodestates -n sriov-network-operator -oyaml
apiVersion: v1
items:
- apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetworkNodeState
metadata:
creationTimestamp: "2023-06-07T09:52:37Z"
generation: 1
name: xr11-2
namespace: sriov-network-operator
ownerReferences:
- apiVersion: sriovnetwork.openshift.io/v1
blockOwnerDeletion: true
controller: true
kind: SriovNetworkNodePolicy
name: default
uid: 80b72499-e26b-4072-a75c-f9a6218ec357
resourceVersion: "356603"
uid: e1f1654b-92b3-44d9-9f87-2571792cc1ad
spec:
dpConfigVersion: "356507"
status:
interfaces:
- deviceID: "1592"
driver: ice
eSwitchMode: legacy
linkType: ETH
mac: 40:a6:b7:9b:35:f0
mtu: 1500
name: p2p1
pciAddress: "0000:51:00.0"
totalvfs: 128
vendor: "8086"
- deviceID: "1592"
driver: ice
eSwitchMode: legacy
linkType: ETH
mac: 40:a6:b7:9b:35:f1
mtu: 1500
name: p2p2
pciAddress: "0000:51:00.1"
totalvfs: 128
vendor: "8086"
syncStatus: Succeeded
kind: List
metadata:
resourceVersion: ""ここでインタフェースが検出されていない場合は、インタフェースが次の設定マップに存在することを確認してください。
$ kubectl get cm supported-nic-ids -oyaml -n sriov-network-operatorデバイスがリストされていない場合、検出される適切な値を追加して設定マップを編集します。次に更新を有効にするため、ノードごとにsriov-network-config-daemon
Podを再起動します。
VFを設定するためにSriovNetworkNodePolicyを作成します。
このポリシーはPodで使用するためのリソースintelnicsDpdkを作成します。また、指定されたPCIデバイスにvfio-pciドライバをバインドし、MTUサイズ1500の8個のVFを作成します。
resourceNameフィールドには、特殊文字を含めることはできず、クラスタ全体で一意である必要があります。
この例では、DPDKがSR-IOVと組み合わせて使用されるため、deviceType:
vfio-pciを使用しています。DPDKを使用しない場合は、deviceType:
netdevice (デフォルト値)を設定してください。
apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetworkNodePolicy
metadata:
name: policy-dpdk
namespace: sriov-network-operator
spec:
nodeSelector:
feature.node.kubernetes.io/network-sriov.capable: "true"
resourceName: intelnicsDpdk
deviceType: vfio-pci
numVfs: 8
mtu: 1500
nicSelector:
deviceID: "1592"
vendor: "8086"
rootDevices:
- 0000:51:00.0すべてのノードで設定を検証します。
事前定義されたresourcePrefix
rancher.ioを使用すると、8個のVFを備えたrancher.io/intelnicsDpdkが検出されるはずです。
$ kubectl get nodes -o jsonpath='{"items": [ { "name": @.metadata.name, "allocatable": @.status.allocatable } ]}' | jq
{
"name": "node1.suse.edge.com",
"allocatable": {
"cpu": "64",
"ephemeral-storage": "256196109726",
"hugepages-1Gi": "60Gi",
"hugepages-2Mi": "0",
"rancher.io/intel_fec_5g": "16",
"memory": "200424836Ki",
"pods": "110",
"rancher.io/intelnicsDpdk": "8"
}
}(オプション)
sriovnetworkを作成します。
この手順はオプションであり、カスタムネットワーク定義の場合にのみ必要です。以前に作成されたノードポリシーにバインドするresourceNameを指定します。
networkNamespaceが設定されている場合、ネットワークはそのネームスペース内のPodに公開されます。設定されていない場合、ネットワークはNetwork
Operatorのインストールネームスペースで利用できるようになります。
apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetwork
metadata:
name: network-dpdk
namespace: sriov-network-operator # where SRIOV Operator is installed
spec:
ipam: |
{
"type": "host-local",
"subnet": "192.168.0.0/24",
"rangeStart": "192.168.0.20",
"rangeEnd": "192.168.0.60",
"routes": [{
"dst": "0.0.0.0/0"
}],
"gateway": "192.168.0.1"
}
vlan: 500
resourceName: intelnicsDpdk
networkNamespace: default # where workloads are deployed更新が成功すると、ターゲットクラスタにNetworkAttachmentDefinition (NAD)が作成されます。
$ kubectl get net-attach-def -A -oyaml
apiVersion: v1
items:
- apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
annotations:
k8s.v1.cni.cncf.io/resourceName: rancher.io/intelnicsDpdk
creationTimestamp: "2023-06-08T11:22:27Z"
generation: 1
name: network-dpdk
namespace: default
resourceVersion: "13124"
uid: df7c89f5-177c-4f30-ae72-7aef3294fb15
spec:
config: '{ "cniVersion":"0.4.0", "name":"network-dpdk","type":"sriov","vlan":500,"vlanQoS":0,"ipam":{"type":"host-local","subnet":"192.168.0.0/24","rangeStart":"192.168.0.10","rangeEnd":"192.168.0.60","routes":[{"dst":"0.0.0.0/0"}],"gateway":"192.168.0.1"}
}'
kind: List
metadata:
resourceVersion: ""ワークロードPodは、ネットワークインタフェースのVFを使用するためにresourceName
rancher.io/intelnicsDpdkを使用できます。
42.7 DPDK #
DPDK
(データプレーン開発キット)は、パケットの高速処理用の一連のライブラリとドライバです。DPDKは、広範なCPUアーキテクチャ上で実行されるパケット処理ワークロードを高速化するために使用されます。DPDKには、データプレーンライブラリと、以下のために最適化されたネットワークインタフェースコントローラ(NIC)ドライバが含まれています。
キューマネージャはロックなしのキューを実装します。
バッファマネージャは固定サイズのバッファを事前割り当てします。
メモリマネージャは、メモリ内にオブジェクトのプールを割り当て、リングを使用してフリーオブジェクトを格納します。オブジェクトがすべての
DRAMチャンネルに均等に分散されるようにします。ポールモードドライバ(
PMD)は、非同期通知なしで動作するように設計されているため、オーバーヘッドが軽減されます。パケット処理を開発するためのヘルパーである一連のライブラリとしてのパケットフレームワーク。
次の手順では、DPDKを有効にする方法と、DPDKインタフェースが使用するNICからVFを作成する方法を示します。
DPDKパッケージをインストールします。
$ transactional-update pkg install dpdk dpdk-tools libdpdk-25
$ rebootカーネルパラメータ:
DPDKを使用するには、ドライバをいくつか使用して、カーネルの特定のパラメータを有効にします。
| パラメータ | 値 | 説明 |
|---|---|---|
iommu | pt | このオプションを使用すると、DPDKインタフェースに |
intel_iommuまたはamd_iommu | on | このオプションを使用すると、 |
これらのパラメータを有効にするには、各パラメータを/etc/default/grubファイルに追加します。
GRUB_CMDLINE_LINUX="BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=77b713de-5cc7-4d4c-8fc6-f5eca0a43cf9 skew_tick=1 rd.timeout=60 rd.retry=45 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack intel_iommu=on iommu=pt irqaffinity=0,31,32,63 isolcpus=domain,nohz,managed_irq,1-30,33-62 nohz_full=1-30,33-62 nohz=on mce=off nosoftlockup nowatchdog nmi_watchdog=0 quiet rcu_nocb_poll rcu_nocbs=1-30,33-62 rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=poll"GRUBの設定を更新し、システムを再起動して変更を適用します。
$ transactional-update grub.cfg
$ rebootvfio-pciカーネルモジュールを読み込み、NICでSR-IOVを有効にします。最初の引数はvfio-pciドライバがSR-IOVをサポートすることを示し、2番目の引数はPCIデバイスがアイドル時に低電力状態にならないようにします。
$ modprobe vfio-pci enable_sriov=1 disable_idle_d3=1NICから仮想機能(VF)をいくつか作成します。
たとえば、2つの異なるNICに対してVFを作成するには、次のコマンドが必要です。
$ echo 4 > /sys/bus/pci/devices/0000:51:00.0/sriov_numvfs
$ echo 4 > /sys/bus/pci/devices/0000:51:00.1/sriov_numvfs新しいVFを
vfio-pciドライバにバインドします。
$ dpdk-devbind.py -b vfio-pci 0000:51:01.0 0000:51:01.1 0000:51:01.2 0000:51:01.3 \
0000:51:11.0 0000:51:11.1 0000:51:11.2 0000:51:11.3設定が正しく適用されたことを確認します。
$ dpdk-devbind.py -s
Network devices using DPDK-compatible driver
============================================
0000:51:01.0 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:01.1 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:01.2 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:01.3 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:01.0 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:11.1 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:21.2 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:31.3 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
Network devices using kernel driver
===================================
0000:19:00.0 'BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet 1751' if=em1 drv=bnxt_en unused=igb_uio,vfio-pci *Active*
0000:19:00.1 'BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet 1751' if=em2 drv=bnxt_en unused=igb_uio,vfio-pci
0000:19:00.2 'BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet 1751' if=em3 drv=bnxt_en unused=igb_uio,vfio-pci
0000:19:00.3 'BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet 1751' if=em4 drv=bnxt_en unused=igb_uio,vfio-pci
0000:51:00.0 'Ethernet Controller E810-C for QSFP 1592' if=eth13 drv=ice unused=igb_uio,vfio-pci
0000:51:00.1 'Ethernet Controller E810-C for QSFP 1592' if=rename8 drv=ice unused=igb_uio,vfio-pci42.8 vRANアクセラレーション(Intel ACC100/ACC200) #
4Gから5Gネットワークへの移行に伴い、多くの通信サービスプロバイダが仮想化無線アクセスネットワーク(vRAN)アーキテクチャを採用して、チャンネル容量を増やし、エッジベースのサービスとアプリケーションのデプロイメントを容易にしようとしています。vRANソリューションは、ネットワーク上のリアルタイムのトラフィックと需要の量に応じて容量を柔軟に増減できるため、低レイテンシのサービスを提供するのに理想的です。
4Gおよび5Gで最も計算負荷が高いワークロードの1つがRANレイヤ1
(L1)のFECです。これは、信頼性の低い通信チャンネルやノイズの多い通信チャンネルでのデータ伝送エラーを解消するものです。FEC技術は、4Gまたは5Gデータの一定数のエラーを検出して訂正することで、再送信の必要性を解消します。FECアクセラレーショントランザクションにはセルの状態情報が含まれないため、簡単に仮想化でき、プールするメリットとセルの容易な移行が実現します。
これまでIntelは、レイヤ1 FECアルゴリズムを高速に実行し、ホストの処理能力をメインCPUに解放するために、ACC100
vRANアクセラレータカードを提供してきました。Intelはその後、この技術をSapphire
Rapids以降の新しいCPUにIntel vRAN Boost
(ACC200とも呼ばれる)という名称で直接統合しました。Intel vRAN
BoostはCPU自体のオフロードアクセラレータとして機能し、別個のハードウェアカードを必要としません。このセクションでは、ワークロードがACC100またはIntel
vRAN Boostを活用するためのSUSE Telco Cloudの設定について詳しく説明します。
42.8.1 カーネルパラメータ #
vRANアクセラレーションを有効にするには、次のカーネルパラメータを有効にする必要があります(まだ存在しない場合)。
| パラメータ | 値 | 説明 |
|---|---|---|
iommu | pt | このオプションを使用すると、DPDKインタフェースにvfioを使用できます。 |
intel_iommuまたはamd_iommu | on | このオプションを使用すると、VFにvfioを使用できます。 |
GRUBファイル/etc/default/grubを変更して、これらのパラメータをカーネルコマンドラインに追加します。
GRUB_CMDLINE_LINUX="BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=77b713de-5cc7-4d4c-8fc6-f5eca0a43cf9 skew_tick=1 rd.timeout=60 rd.retry=45 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack intel_iommu=on iommu=pt irqaffinity=0,31,32,63 isolcpus=domain,nohz,managed_irq,1-30,33-62 nohz_full=1-30,33-62 nohz=on mce=off nosoftlockup nowatchdog nmi_watchdog=0 quiet rcu_nocb_poll rcu_nocbs=1-30,33-62 rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=poll"GRUBの設定を更新し、システムを再起動して変更を適用します。
$ transactional-update grub.cfg
$ reboot再起動後にパラメータが適用されていることを確認するには、コマンドラインを確認します。
$ cat /proc/cmdline42.8.2 FECアクセラレータのSR-IOVの設定 #
vRANアクセラレーションを有効にするには、
vfio-pciカーネルモジュールを読み込みます。最初の引数はvfio-pciモジュールがSR-IOVをサポートすることを示し、2番目の引数はPCIデバイスがアイドル時に低電力状態にならないようにします。
$ modprobe vfio-pci enable_sriov=1 disable_idle_d3=1FECアクセラレータのPCIデバイスアドレスを取得します。
$ lspci | grep -i acc
8a:00.0 Processing accelerators: Intel Corporation Device 0d5c物理インタフェース(
PF)をvfio-pciドライバにバインドします。
$ dpdk-devbind.py -b vfio-pci 0000:8a:00.0仮想機能(
VF)を物理インタフェース(PF)から作成します。
アクセラレータカードの最大VF容量を確認します。次に、最大数を超えない範囲で、希望する数のVFを公開するようにカードを設定します。この例では、カードの最大容量である16個のVFを設定します。
$ cat /sys/bus/pci/devices/0000:8a:00.0/sriov_totalvfs
16
$ echo 16 > /sys/bus/pci/devices/0000:8a:00.0/sriov_numvfsアクセラレータカードとその仮想機能を4Gまたは5Gプロファイルで設定します。固有のVFトークン(UUID)を指定する必要があります。ワークロードはこのVFトークンを使用して、カードのFECアクセラレーション機能を活用します。
$ pf_bb_config ACC200 -c /opt/pf-bb-config/acc200_config_vf_5g.cfg -v 00112233-4455-6677-8899-aabbccddeeff
Tue Jun 6 10:49:20 2023:INFO:Queue Groups: 2 5GUL, 2 5GDL, 2 4GUL, 2 4GDL
Tue Jun 6 10:49:20 2023:INFO:Configuration in VF mode
Tue Jun 6 10:49:21 2023:INFO: ROM version MM 99AD92
Tue Jun 6 10:49:21 2023:WARN:* Note: Not on DDR PRQ version 1302020 != 10092020
Tue Jun 6 10:49:21 2023:INFO:PF ACC200 configuration complete
Tue Jun 6 10:49:21 2023:INFO:ACC200 PF [0000:8a:00.0] configuration complete!FEC PFから作成された新しいVFを確認します。VFが
0d5dデバイスIDを取得していることに注意してください。この情報は、次の手順でKubernetesリソースとしてこれらのVFを公開するために必要です。
$ dpdk-devbind.py -s
Baseband devices using DPDK-compatible driver
=============================================
0000:8a:00.0 'Device 0d5c' drv=vfio-pci unused=
0000:8b:00.0 'Device 0d5d' drv=vfio-pci unused=
Other Baseband devices
======================
0000:8b:00.1 'Device 0d5d' unused=42.8.3 FECアクセラレーションのためのKubernetesの設定 #
最後の手順は、SR-IOVデバイスプラグインを使用してKubernetesにVFを公開することです。前の手順で収集したVFのデバイスIDを使用してConfigMapを作成し、SR-IOVデバイスプラグインをインストールします。
KubernetesノードでFEC
VFがAllocatableリソースとして表示されると、クラスタでFECアクセラレーションを活用したワークロードを実行する準備が整います。
42.6項 「SR-IOV」の章のオプション1の手順に従ってください。SRIOV Network OperatorはFECアクセラレータには適用されないため、オプション2は適用されません。
42.9 Huge Page #
プロセスがRAMを使用すると、CPUはそのメモリ領域をプロセスが使用中であるとマークします。効率を高めるために、CPUはRAMをチャンクで割り当てます。多くのプラットフォームでは4Kバイトがチャンクのデフォルト値です。これらのチャンクをページと呼び、ディスクなどにスワップできます。
プロセスのアドレススペースは仮想であるため、CPUとオペレーティングシステムは、どのページがどのプロセスに属していて、各ページがどこに保管されているかを覚えておく必要があります。ページ数が多いほど、メモリマッピングの検索に時間がかかります。プロセスが1GBのメモリを使用する場合、検索するエントリは262,144個になります(1GB
/ 4K)。1つのページテーブルエントリが8バイトを消費する場合、2MB
(262,144 * 8)を検索することになります。
最新のCPUアーキテクチャはデフォルトより大きいページをサポートしているので、CPU/OSが検索するエントリが減少します。
カーネルパラメータ
Huge Pageを有効にするには、次のカーネルパラメータを追加する必要があります。この例では、40個の1Gページを設定していますが、Huge Pageのサイズと正確な数は、アプリケーションのメモリ要件に合わせて調整する必要があります。
| パラメータ | 値 | 説明 |
|---|---|---|
hugepagesz | 1G | このオプションを使用すると、Huge Pageを1Gに設定できます |
hugepages | 40 | 前に定義したHuge Pageの数です |
default_hugepagesz | 1G | Huge Pageを取得するためのデフォルト値です |
GRUBファイル/etc/default/grubを変更して、これらのパラメータをGRUB_CMDLINE_LINUXに追加します。
default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0GRUBの設定を更新し、システムを再起動して変更を適用します。
$ transactional-update grub.cfg
$ reboot再起動後にパラメータが適用されていることを検証するには、次のコマンドラインを確認できます。
$ cat /proc/cmdlineHuge Pageの使用
Huge Pageを使用するには、Huge Pageをマウントする必要があります。
$ mkdir -p /hugepages
$ mount -t hugetlbfs nodev /hugepagesKubernetesワークロードをデプロイし、リソースとボリュームを作成します。
...
resources:
requests:
memory: "24Gi"
hugepages-1Gi: 16Gi
intel.com/intel_sriov_oru: '4'
limits:
memory: "24Gi"
hugepages-1Gi: 16Gi
intel.com/intel_sriov_oru: '4'
......
volumeMounts:
- name: hugepage
mountPath: /hugepages
...
volumes:
- name: hugepage
emptyDir:
medium: HugePages
...42.10 NUMA対応のスケジューリング #
Non-Uniform Memory AccessまたはNon-Uniform Memory Architecture
(NUMA)は、SMP
(マルチプロセッサ)アーキテクチャにおいて使用される物理メモリ設計であり、メモリアクセス時間がプロセッサからのメモリの相対的な位置によって異なります。NUMAでは、プロセッサは専用のローカルメモリに、非ローカルメモリ、つまり別のプロセッサにローカルなメモリや複数のプロセッサで共有されているメモリよりも高速にアクセスできます。
42.10.1 NUMAノードの特定 #
NUMAノードを特定するには、システムで次のコマンドを使用します。
$ lscpu | grep NUMA
NUMA node(s): 1
NUMA node0 CPU(s): 0-63この例では、NUMAノードが1つだけあり、64個のCPUが表示されています。
NUMAはBIOSで有効にする必要があります。dmesgにブート時のNUMA初期化レコードがない場合、カーネルリングバッファ内のNUMA関連のメッセージが上書きされた可能性があります。
42.11 MetalLB #
MetalLBは、ベアメタルKubernetesクラスタ用のロードバランサの実装であり、L2やBGPなどの標準ルーティングプロトコルをアドバタイズプロトコルとして使用します。ベアメタル環境ではKubernetesサービスタイプLoadBalancerを使用する必要があるため、Kubernetesクラスタ内のサービスを外部に公開するために使用できるのは、ネットワークロードバランサです。
RKE2クラスタでMetalLBを有効にするには、次の手順を実行する必要があります。
次のコマンドを使用して
MetalLBをインストールします。
$ kubectl apply <<EOF -f
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: metallb
namespace: kube-system
spec:
chart: oci://registry.suse.com/edge/charts/metallb
targetNamespace: metallb-system
version: 305.0.1+up0.15.2
createNamespace: true
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: endpoint-copier-operator
namespace: kube-system
spec:
chart: oci://registry.suse.com/edge/charts/endpoint-copier-operator
targetNamespace: endpoint-copier-operator
version: 305.0.1+up0.3.0
createNamespace: true
EOFIpAddressPoolおよびL2advertisementの設定を作成します。
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: kubernetes-vip-ip-pool
namespace: metallb-system
spec:
addresses:
- 10.168.200.98/32
serviceAllocation:
priority: 100
namespaces:
- default
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: ip-pool-l2-adv
namespace: metallb-system
spec:
ipAddressPools:
- kubernetes-vip-ip-poolVIPを公開するためのエンドポイントサービスを作成します。
apiVersion: v1
kind: Service
metadata:
name: kubernetes-vip
namespace: default
spec:
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: rke2-api
port: 9345
protocol: TCP
targetPort: 9345
- name: k8s-api
port: 6443
protocol: TCP
targetPort: 6443
sessionAffinity: None
type: LoadBalancerVIPが作成され、MetalLBのPodが実行中であることを確認します。
$ kubectl get svc -n default
$ kubectl get pods -n default42.12 プライベートレジストリ設定 #
Containerdをプライベートレジストリに接続するように設定し、そのプライベートレジストリを使用して各ノードにプライベートイメージをプルできます。
起動時に、RKE2は、registries.yamlファイルが/etc/rancher/rke2/に存在するかどうかを確認し、このファイルで定義されたレジストリを使用するようにcontainerdに指示します。プライベートレジストリを使用するには、このファイルを、レジストリを使用する各ノードにルートとして作成します。
プライベートレジストリを追加するには、ファイル/etc/rancher/rke2/registries.yamlを作成して次の内容を設定します。
mirrors:
docker.io:
endpoint:
- "https://registry.example.com:5000"
configs:
"registry.example.com:5000":
auth:
username: xxxxxx # this is the registry username
password: xxxxxx # this is the registry password
tls:
cert_file: # path to the cert file used to authenticate to the registry
key_file: # path to the key file for the certificate used to authenticate to the registry
ca_file: # path to the ca file used to verify the registry's certificate
insecure_skip_verify: # may be set to true to skip verifying the registry's certificateまたは、認証を使用しない場合は次のように設定します。
mirrors:
docker.io:
endpoint:
- "https://registry.example.com:5000"
configs:
"registry.example.com:5000":
tls:
cert_file: # path to the cert file used to authenticate to the registry
key_file: # path to the key file for the certificate used to authenticate to the registry
ca_file: # path to the ca file used to verify the registry's certificate
insecure_skip_verify: # may be set to true to skip verifying the registry's certificateレジストリの変更を有効にするには、ノード上でRKE2を起動する前にこのファイルを設定するか、または設定した各ノードでRKE2を再起動します。
42.13 Precision Time Protocol #
Precision Time Protocol (PTP)は、 電気電子学会(IEEE)によって開発されたネットワークプロトコルで、コンピュータネットワークにおけるサブマイクロ秒単位の時間同期を可能にします。PTPは、その誕生以来数十年にわたり、多くの業界で利用されてきました。最近では、5Gネットワークの重要な要素として、通信ネットワークにおける採用が急増しています。比較的シンプルなプロトコルであるものの、アプリケーションに応じて設定が大幅に異なります。そのため、複数のプロファイルが定義され標準化されています。
このセクションでは、通信事業者固有のプロファイルのみについて説明します。そのため、NICにタイムスタンプ機能とPTPハードウェアクロック(PHC)が搭載されていることを前提とします。現在、すべての通信事業者グレードのネットワークアダプタにはハードウェアPTPサポートが付属していますが、以下のコマンドでその機能を確認できます。
# ethtool -T p1p1
Time stamping parameters for p1p1:
Capabilities:
hardware-transmit
software-transmit
hardware-receive
software-receive
software-system-clock
hardware-raw-clock
PTP Hardware Clock: 0
Hardware Transmit Timestamp Modes:
off
on
Hardware Receive Filter Modes:
none
allp1p1を、PTPに使用されるインタフェースの名前に置き換えます。
以下のセクションでは、SUSE Telco CloudにPTPをインストールして設定する方法について具体的に説明しますが、PTPの基本的な概念を理解していることが前提となります。PTPの概要と、SUSE Telco Cloudに含まれる実装については、https://documentation.suse.com/sles/html/SLES-all/cha-tuning-ptp.htmlを参照してください。
42.13.1 PTPソフトウェアコンポーネントのインストール #
SUSE Telco
Cloudでは、PTP実装がlinuxptpパッケージで提供されています。このパッケージには次の2つのコンポーネントが含まれています。
ptp4l: NIC上のPHCを制御し、PTPプロトコルを実行するデーモンphc2sys: NIC上のPTP同期PHCとシステムクロックとの同期を維持するデーモン
システム同期が完全に機能するには、両方のデーモンが必要であり、セットアップに従って正しく設定する必要があります。詳細については、42.13.2項 「通信事業者のデプロイメント向けPTPの設定」を参照してください。
ダウンストリームクラスタにPTPを統合する最も簡単で最良の方法は、Edge Image Builder
(EIB)定義ファイルのpackageListの下にlinuxptpパッケージを追加することです。これにより、クラスタプロビジョニング中にPTPコントロールプレーンソフトウェアが自動的にインストールされます。パッケージのインストールの詳細については、EIBのドキュメント(3.3.6項 「RPMパッケージの設定」)を参照してください。
以下に、linuxptpを使用したEIBマニフェストのサンプルを示します。
apiVersion: 1.3
image:
imageType: RAW
arch: x86_64
baseImage: SL-Micro.x86_64-6.2-Base-RT-GM.raw
outputImageName: eibimage-slmicrort-telco.raw
operatingSystem:
time:
timezone: America/New_York
kernelArgs:
- ignition.platform.id=openstack
systemd:
disable:
- rebootmgr
- transactional-update.timer
- transactional-update-cleanup.timer
- fstrim
- time-sync.target
enable:
- ptp4l
- phc2sys
users:
- username: root
encryptedPassword: $ROOT_PASSWORD
packages:
packageList:
- jq
- dpdk
- dpdk-tools
- libdpdk-25
- pf-bb-config
- open-iscsi
- tuned
- cpupower
- linuxptp
sccRegistrationCode: $SCC_REGISTRATION_CODESUSE Telco
Cloudに含まれるlinuxptpパッケージでは、デフォルトでptp4lおよびphc2sysが有効になりません。プロビジョニング時にシステム固有の設定ファイルがデプロイされている場合は(42.13.3項 「Cluster APIの統合」を参照)、これらを有効にする必要があります。上記の例のように、マニフェストのsystemdセクションに追加して有効にしてください。
EIBのドキュメントで説明されている通常のプロセスに従って、イメージを構築し(3.4項 「イメージの構築」)、そのイメージを使用してクラスタをデプロイします。EIBを初めて使用する場合は、第11章 「Edge Image Builder」から開始してください。
42.13.2 通信事業者のデプロイメント向けPTPの設定 #
多くの通信事業者向けアプリケーションでは、わずかな偏差で厳格な位相と時刻同期が求められるため、通信事業者向けの2つのプロファイルが定義されました(ITU-T
G.8275.1とITU-T G.8275.2)。これら両プロファイルは、同期メッセージの送信頻度が高く、代替Best Master Clock
Algorithm
(BMCA)の使用など、他の特徴的な特性を備えています。このような動作は、ptp4lが使用する設定ファイルに特定の設定を必要とします。これらの設定は以下のセクションで参照用に提供されています。
両セクションは、タイムレシーバー設定の通常のクロックの場合のみを対象としてます。
このようなプロファイルは、適切に計画されたPTPインフラストラクチャで使用する必要があります。
特定のPTPネットワークには、追加の設定の調整が必要な場合があります。必要に応じて、提供された例を確認して調整してください。
42.13.2.1 PTPプロファイルITU-T G.8275.1 #
G.8275.1プロファイルには、次の特徴があります。
Ethernet上で直接実行し、完全なネットワークサポートが必要です(隣接するノード/スイッチはPTPをサポートしている必要があります)。
デフォルトのドメイン設定は24です。
データセットの比較は、G.8275.xアルゴリズムと、
priority2以降のlocalPriority値に基づいています。
次のコンテンツを/etc/ptp4l-G.8275.1.confという名前のファイルにコピーします。
# Telecom G.8275.1 example configuration [global] domainNumber 24 priority2 255 dataset_comparison G.8275.x G.8275.portDS.localPriority 128 G.8275.defaultDS.localPriority 128 maxStepsRemoved 255 logAnnounceInterval -3 logSyncInterval -4 logMinDelayReqInterval -4 announceReceiptTimeout 3 serverOnly 0 ptp_dst_mac 01:80:C2:00:00:0E network_transport L2
ファイルが作成されたら、デーモンが正常に起動するように/etc/sysconfig/ptp4lで参照される必要があります。これを行うには、
OPTIONS=行を次のように変更します。
OPTIONS="-f /etc/ptp4l-G.8275.1.conf -i $IFNAME --message_tag ptp-8275.1"
より正確な説明は次のとおりです。
-fには、使用する設定ファイルのファイル名が必要です。この場合は/etc/ptp4l-G.8275.1.conf。-iには、使用するインタフェースの名前が必要です。$IFNAMEを実際のインタフェース名に置き換えます。--message_tagは、システムログ内のptp4l出力を適切に特定できるようにし、オプションです。
上記の手順が完了したら、ptp4lデーモンを(再)起動する必要があります。
# systemctl restart ptp4l次のコマンドを使用してログを調べ、同期ステータスを確認します。
# journalctl -e -u ptp4l42.13.2.2 PTPプロファイルITU-T G.8275.2 #
G.8275.2プロファイルには、次の特徴があります。
IP上で実行し、完全なネットワークサポートは不要です(隣接するノード/スイッチはPTPをサポートしていない場合があります)。
デフォルトのドメイン設定は44です。
データセットの比較は、G.8275.xアルゴリズムと、
priority2以降のlocalPriority値に基づいています。
次のコンテンツを/etc/ptp4l-G.8275.2.confという名前のファイルにコピーします。
# Telecom G.8275.2 example configuration [global] domainNumber 44 priority2 255 dataset_comparison G.8275.x G.8275.portDS.localPriority 128 G.8275.defaultDS.localPriority 128 maxStepsRemoved 255 logAnnounceInterval 0 serverOnly 0 hybrid_e2e 1 inhibit_multicast_service 1 unicast_listen 1 unicast_req_duration 60 logSyncInterval -5 logMinDelayReqInterval -4 announceReceiptTimeout 2 # # Customize the following for slave operation: # [unicast_master_table] table_id 1 logQueryInterval 2 UDPv4 $PEER_IP_ADDRESS [$IFNAME] unicast_master_table 1
次のプレースホルダーを必ず置き換えます。
$PEER_IP_ADDRESS- 同期を提供するマスタまたは境界クロックなど、通信する次のPTPノードのIPアドレス。$IFNAME-ptp4lにPTPに使用するインタフェースを示します。
ファイルが作成されると、デーモンが正常に起動するように、PTPに使用するインタフェースの名前とともに、/etc/sysconfig/ptp4lで参照される必要があります。これを行うには、OPTIONS=行を次のように変更します。
OPTIONS="-f /etc/ptp4l-G.8275.2.conf --message_tag ptp-8275.2"より正確な説明は次のとおりです。
-fには、使用する設定ファイルのファイル名が必要です。この場合は、/etc/ptp4l-G.8275.2.confです。--message_tagは、システムログ内のptp4l出力を適切に特定できるようにし、オプションです。
上記の手順が完了したら、ptp4lデーモンを(再)起動する必要があります。
# systemctl restart ptp4l次のコマンドを使用してログを調べ、同期ステータスを確認します。
# journalctl -e -u ptp4l42.13.2.3 phc2sysの設定 #
必須ではありませんが、phc2sysに移る前に、ptp4lの設定を完全に完了しておくことをお勧めします。phc2sysは設定ファイルを必要とせず、その実行パラメータはptp4lと同様に、/etc/sysconfig/ptp4lに存在するOPTIONS=変数を通じてのみ制御できます。
OPTIONS="-s $IFNAME -w"
ここで、$IFNAMEはシステムクロックのソースとして使用される、ptp4lですでに設定されているインタフェースの名前です。これはソースPHCを識別するために使用されます。
42.13.3 Cluster APIの統合 #
クラスタが管理クラスタおよびダイレクトネットワークプロビジョニングを通じてデプロイされるときは常に、プロビジョニング時に設定ファイルと/etc/sysconfig内の2つの設定変数の両方をホスト上にデプロイできます。以下は、同じG.8275.1設定ファイルをすべてのホスト上にデプロイする、変更されたRKE2ControlPlaneオブジェクトに焦点を当てたクラスタ定義の抜粋です。
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: RKE2ControlPlane
metadata:
name: single-node-cluster
namespace: default
spec:
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3MachineTemplate
name: single-node-cluster-controlplane
replicas: 1
version: ${RKE2_VERSION}
rolloutStrategy:
type: "RollingUpdate"
rollingUpdate:
maxSurge: 0
registrationMethod: "control-plane-endpoint"
serverConfig:
cni: canal
agentConfig:
format: ignition
cisProfile: cis
additionalUserData:
config: |
variant: fcos
version: 1.4.0
systemd:
units:
- name: rke2-preinstall.service
enabled: true
contents: |
[Unit]
Description=rke2-preinstall
Wants=network-online.target
Before=rke2-install.service
ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
[Service]
Type=oneshot
User=root
ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
ExecStart=/bin/sh -c "sed -i \"s/BAREMETALHOST_UUID/$(jq -r .uuid /mnt/openstack/latest/meta_data.json)/\" /etc/rancher/rke2/config.yaml"
ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
ExecStartPost=/bin/sh -c "umount /mnt"
[Install]
WantedBy=multi-user.target
storage:
files:
- path: /etc/ptp4l-G.8275.1.conf
overwrite: true
contents:
inline: |
# Telecom G.8275.1 example configuration
[global]
domainNumber 24
priority2 255
dataset_comparison G.8275.x
G.8275.portDS.localPriority 128
G.8275.defaultDS.localPriority 128
maxStepsRemoved 255
logAnnounceInterval -3
logSyncInterval -4
logMinDelayReqInterval -4
announceReceiptTimeout 3
serverOnly 0
ptp_dst_mac 01:80:C2:00:00:0E
network_transport L2
mode: 0644
user:
name: root
group:
name: root
- path: /etc/sysconfig/ptp4l
overwrite: true
contents:
inline: |
## Path: Network/LinuxPTP
## Description: Precision Time Protocol (PTP): ptp4l settings
## Type: string
## Default: "-i eth0 -f /etc/ptp4l.conf"
## ServiceRestart: ptp4l
#
# Arguments when starting ptp4l(8).
#
OPTIONS="-f /etc/ptp4l-G.8275.1.conf -i $IFNAME --message_tag ptp-8275.1"
mode: 0644
user:
name: root
group:
name: root
- path: /etc/sysconfig/phc2sys
overwrite: true
contents:
inline: |
## Path: Network/LinuxPTP
## Description: Precision Time Protocol (PTP): phc2sys settings
## Type: string
## Default: "-s eth0 -w"
## ServiceRestart: phc2sys
#
# Arguments when starting phc2sys(8).
#
OPTIONS="-s $IFNAME -w"
mode: 0644
user:
name: root
group:
name: root
kubelet:
extraArgs:
- provider-id=metal3://BAREMETALHOST_UUID
nodeName: "localhost.localdomain"上記の定義は、他の変数に加え、第43章 「完全に自動化されたダイレクトネットワークプロビジョニング」で説明されているように、インタフェース名と他のCluster APIオブジェクトで補完する必要があります。
このアプローチは、クラスタのハードウェアが均一であり、インタフェース名を含め、すべてのホスト上で同じ設定が必要な場合にのみ便利です。
代替アプローチが可能であり、今後のリリースで取り上げる予定です。
この時点で、ホストには機能していて実行中のPTPスタックがあり、PTP役割のネゴシエーションを開始するはずです。