54 Telco機能 (DPDK、SR-IOV、CPUアイソレーション、huge pages、NUMAなど) #
ダイレクトネットワークプロビジョニングワークフローにより、ダウンストリームクラスターで使用されるTelco機能を自動化し、それらのサーバー上でTelcoワークロードを実行できるようになります。
要件
前のセクション (第49章 「接続されたシナリオ向けのダウンストリームクラスターイメージの準備」)で説明したように、`EIB`を使用して生成されたイメージは、このセクション (注記)で設定したパスと完全に一致する管理クラスター上に配置する必要があります。
`EIB`を使用して生成されたイメージには、このセクション (49.2.5項 「通信ワークロードの追加構成」)に従って特定のTelcoパッケージを含める必要があります。
作成され、以下のセクションで使用できる管理サーバーです。詳細については、「管理クラスター」セクションのパートV「管理クラスタのセットアップ」を参照してください。
設定
ホストの登録およびプロビジョニングの基礎として、以下の2つのセクションを使用してください。
ダイレクトネットワークプロビジョニングを使用したダウンストリームクラスターのプロビジョニング(シングルノード) (第51章 「ダイレクトネットワークプロビジョニング(シングルノード)によるダウンストリームクラスターのプロビジョニング」)
ダイレクトネットワークプロビジョニングを使用したダウンストリームクラスターのプロビジョニング(マルチノード) (第52章 「ダイレクトネットワークプロビジョニング(マルチノード)によるダウンストリームクラスターのプロビジョニング」)
本セクションで扱うTelco機能は以下の通りです。
DPDKおよびVFの作成
SR-IOVおよびワークロードで使用するVFの割り当て
CPUの分離およびパフォーマンスチューニング
Huge pagesの設定
カーネルパラメータのチューニング
上記で示したTelco機能を有効にするために必要な変更は、すべてプロビジョニングファイル`capi-provisioning-example.yaml`内の`RKE2ControlPlane`ブロックに含まれています。ファイル`capi-provisioning-example.yaml`内のその他の情報は、プロビジョニングセクション (第51章 「ダイレクトネットワークプロビジョニング(シングルノード)によるダウンストリームクラスターのプロビジョニング」)で提供されている情報と同じです。
プロセスを明確にするため、Telco機能を有効にするためにそのブロック(RKE2ControlPlane)で必要な変更は以下の通りです。
インターフェース、ドライバー、およびワークロードに対して作成・公開する`VFs`の数を定義するために使用するイグニッションファイル`/var/lib/rancher/rke2/server/manifests/configmap-sriov-custom-auto.yaml`。
設定マップ
sriov-custom-auto-config内の値のみが、実際の値に置き換えられます。${RESOURCE_NAME1}— 最初のPFインターフェースに使用されるリソース名(例:sriov-resource-du1)。これはプレフィックスrancher.ioに追加され、ワークロードで使用されるラベルとして使用されます(例:rancher.io/sriov-resource-du1)。${SRIOV-NIC-NAME1}— 使用する最初のPFインターフェースの名前(例:eth0)。${PF_NAME1}— 使用する最初の物理機能PFの名前。これを使用して、より複雑なフィルターを生成します(例:eth0#2-5)。${DRIVER_NAME1}— 最初のVFインターフェースに使用されるドライバー名(例:vfio-pci)。${NUM_VFS1}— 最初のPFインターフェースに対して作成されるVFsの数(例:8)。
/var/sriov-auto-filler.shは、高レベルの設定マップsriov-custom-auto-configと、低レベルのハードウェア情報を含むsriovnetworknodepolicyとの間の変換器として使用されます。このスクリプトは、ユーザーが事前にハードウェア情報を把握する必要がないように、その複雑さを抽象化するために作成されました。このファイルに変更を加える必要はありませんが、sr-iovを有効にしてVFsを作成する必要がある場合は、このファイルが存在している必要があります。以下の機能を有効にするために使用されるカーネル引数:
パラメータ | 値 | 説明 |
isolcpus | domain,nohz,managed_irq,1-30,33-62 | コア 1-30 および 33-62 を分離します。 |
skew_tick | 1 | カーネルが分離された CPU 間でタイマー割り込みを分散させることを可能にします。 |
nohz | on | システムがアイドル状態のときに、カーネルが単一の CPU 上でタイマーティックを実行できるようにします。 |
nohz_full | 1-30,33-62 | カーネルブートパラメータは、CPU 分離とともにフル dynticks を構成するための現在の主要なインターフェースです。 |
rcu_nocbs | 1-30,33-62 | システムがアイドル状態のときに、カーネルが単一の CPU 上で RCU コールバックを実行できるようにします。 |
irqaffinity | 0,31,32,63 | システムがアイドル状態のときに、カーネルが単一の CPU で割り込みを実行できるようにします。 |
アイドル | poll | アイドル状態から抜ける際のレイテンシを最小限に抑えます。 |
iommu | pt | dpdkインターフェースにvfioを使用できるようにします。 |
intel_iommu | on | VFに対してvfioの使用を有効にします。 |
hugepagesz | 1G | ヒュージページのサイズを1 Gに設定できるようにします。 |
hugepages | 40 | 事前に定義されたヒュージページの数。 |
default_hugepagesz | 1G | ヒュージページを有効にするためのデフォルト値。 |
nowatchdog | ウォッチドッグを無効にします。 | |
nmi_watchdog | 0 | NMIウォッチドッグを無効にします。 |
以下のsystemdサービスを使用して、以下を有効にします。
rke2-preinstall.serviceIronic情報を使用してプロビジョニングプロセス中にBAREMETALHOST_UUIDとnode-nameを自動的に置き換えるため。cpu-partitioning.serviceは、CPUの分離コアを有効にするために使用されます(例:1-30,33-62)。performance-settings.serviceは、CPUパフォーマンスチューニングを有効にするために使用されます。sriov-custom-auto-vfs.serviceを実行してsriovHelmチャートをインストールし、カスタムリソースが作成されるまで待機した後、/var/sriov-auto-filler.shを実行して設定マップsriov-custom-auto-configの値を置き換え、ワークロードで使用するsriovnetworknodepolicyを作成します。
${RKE2_VERSION}`は、この値を置き換えるために使用する`RKE2`のバージョンです(例: `v1.35.4+rke2r1)。
前述のすべての変更を行うと、capi-provisioning-example.yaml 内の RKE2ControlPlane ブロックは次のようになります。
apiVersion: controlplane.cluster.x-k8s.io/v1beta2
kind: RKE2ControlPlane
metadata:
name: single-node-cluster
namespace: default
spec:
infrastructureRef:
apiGroup: infrastructure.cluster.x-k8s.io
kind: Metal3MachineTemplate
name: single-node-cluster-controlplane
replicas: 1
version: ${RKE2_VERSION}
rolloutStrategy:
type: "RollingUpdate"
rollingUpdate:
maxSurge: 0
serverConfig:
cni: calico
cniMultusEnable: true
agentConfig:
format: ignition
additionalUserData:
config: |
variant: fcos
version: 1.4.0
storage:
files:
- path: /var/lib/rancher/rke2/server/manifests/configmap-sriov-custom-auto.yaml
overwrite: true
contents:
inline: |
apiVersion: v1
kind: ConfigMap
metadata:
name: sriov-custom-auto-config
namespace: kube-system
data:
config.json: |
[
{
"resourceName": "${RESOURCE_NAME1}",
"interface": "${SRIOV-NIC-NAME1}",
"pfname": "${PF_NAME1}",
"driver": "${DRIVER_NAME1}",
"numVFsToCreate": ${NUM_VFS1}
},
{
"resourceName": "${RESOURCE_NAME2}",
"interface": "${SRIOV-NIC-NAME2}",
"pfname": "${PF_NAME2}",
"driver": "${DRIVER_NAME2}",
"numVFsToCreate": ${NUM_VFS2}
}
]
mode: 0644
user:
name: root
group:
name: root
- path: /var/lib/rancher/rke2/server/manifests/sriov-crd.yaml
overwrite: true
contents:
inline: |
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: sriov-crd
namespace: kube-system
spec:
chart: oci://registry.suse.com/edge/charts/sriov-crd
targetNamespace: sriov-network-operator
version: 306.0.4+up1.6.0
createNamespace: true
- path: /var/lib/rancher/rke2/server/manifests/sriov-network-operator.yaml
overwrite: true
contents:
inline: |
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: sriov-network-operator
namespace: kube-system
spec:
chart: oci://registry.suse.com/edge/charts/sriov-network-operator
targetNamespace: sriov-network-operator
version: 306.0.4+up1.6.0
createNamespace: true
kernel_arguments:
should_exist:
- intel_iommu=on
- iommu=pt
- idle=poll
- mce=off
- hugepagesz=1G hugepages=40
- hugepagesz=2M hugepages=0
- default_hugepagesz=1G
- irqaffinity=${NON-ISOLATED_CPU_CORES}
- isolcpus=domain,nohz,managed_irq,${ISOLATED_CPU_CORES}
- nohz_full=${ISOLATED_CPU_CORES}
- rcu_nocbs=${ISOLATED_CPU_CORES}
- rcu_nocb_poll
- nosoftlockup
- nowatchdog
- nohz=on
- nmi_watchdog=0
- skew_tick=1
- quiet
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"
ExecStart=/bin/sh -c "echo \"node-label:\" >> /etc/rancher/rke2/config.yaml"
ExecStart=/bin/sh -c "echo \" - metal3.io/uuid=$(jq -r .uuid /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
ExecStartPost=/bin/sh -c "umount /mnt"
[Install]
WantedBy=multi-user.target
# rke2-traefik-deployment.service unit to be removed once "traefik" being the default ingress controller (starting with RKE2 v1.36)
- name: rke2-traefik-deployment.service
enabled: true
contents: |
[Unit]
Description=rke2-traefik-deployment
Wants=rke2-preinstall.service
Before=rke2-install.service
ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
[Service]
Type=oneshot
User=root
ExecStart=/bin/sh -c "echo \"ingress-controller: traefik\" >> /etc/rancher/rke2/config.yaml"
[Install]
WantedBy=multi-user.target
- name: cpu-partitioning.service
enabled: true
contents: |
[Unit]
Description=cpu-partitioning
Wants=network-online.target
After=network.target network-online.target
[Service]
Type=oneshot
User=root
ExecStart=/bin/sh -c "echo isolated_cores=${ISOLATED_CPU_CORES} > /etc/tuned/cpu-partitioning-variables.conf"
ExecStartPost=/bin/sh -c "tuned-adm profile cpu-partitioning"
ExecStartPost=/bin/sh -c "systemctl enable tuned.service"
[Install]
WantedBy=multi-user.target
- name: performance-settings.service
enabled: true
contents: |
[Unit]
Description=performance-settings
Wants=network-online.target
After=network.target network-online.target cpu-partitioning.service
[Service]
Type=oneshot
User=root
ExecStart=/bin/sh -c "/opt/performance-settings/performance-settings.sh"
[Install]
WantedBy=multi-user.target
- name: sriov-custom-auto-vfs.service
enabled: true
contents: |
[Unit]
Description=SRIOV Custom Auto VF Creation
Wants=network-online.target rke2-server.target
After=network.target network-online.target rke2-server.target
[Service]
User=root
Type=forking
TimeoutStartSec=900
ExecStart=/bin/sh -c "while ! /var/lib/rancher/rke2/bin/kubectl --kubeconfig=/etc/rancher/rke2/rke2.yaml wait --for condition=ready nodes --all ; do sleep 2 ; done"
ExecStartPost=/bin/sh -c "while [ $(/var/lib/rancher/rke2/bin/kubectl --kubeconfig=/etc/rancher/rke2/rke2.yaml get sriovnetworknodestates.sriovnetwork.openshift.io --ignore-not-found --no-headers -A | wc -l) -eq 0 ]; do sleep 1; done"
ExecStartPost=/bin/sh -c "/opt/sriov/sriov-auto-filler.sh"
RemainAfterExit=yes
KillMode=process
[Install]
WantedBy=multi-user.target
kubelet:
extraArgs:
- provider-id=metal3://BAREMETALHOST_UUID
nodeName: "localhost.localdomain"前のブロックを結合してファイルを作成したら、管理クラスターで次のコマンドを実行し、Telco機能を使用して新しいダウンストリームクラスターのプロビジョニングを開始する必要があります。
$ kubectl apply -f capi-provisioning-example.yaml