30 通信機能の設定 #
このセクションでは、ATIPがデプロイされたクラスタの通信事業者固有の機能について記述および説明します。
ダイレクトネットワークプロビジョニングのデプロイメント方法を使用します。この方法については、ATIPの自動プロビジョニング(第31章 「完全に自動化されたダイレクトネットワークプロビジョニング」)に関するセクションで説明しています。
このセクションでは、次のトピックについて説明します。
リアルタイム用のカーネルイメージ(30.1項 「リアルタイム用のカーネルイメージ」): リアルタイムカーネルで使用するカーネルイメージ。
CPU調整設定(30.2項 「CPU調整設定」): リアルタイムカーネルで使用するために調整した設定。
CNI設定(30.3項 「CNI設定」): Kubernetesクラスタで使用するCNI設定。
SR-IOV設定(30.4項 「SR-IOV」): Kubernetesワークロードで使用するSR-IOV設定。
DPDK設定(30.5項 「DPDK」): システムで使用するDPDK設定。
vRANアクセラレーションカード(30.6項 「vRANアクセラレーション(
Intel ACC100/ACC200
)」): Kubernetesワークロードで使用するアクセラレーションカードの設定。Huge Page (30.7項 「Huge Page」): Kubernetesワークロードで使用するHuge Pageの設定。
CPUピニング設定(30.8項 「CPUピニング設定」): Kubernetesワークロードで使用するCPUピニング設定。
NUMA対応のスケジューリング設定(30.9項 「NUMA対応のスケジューリング」): Kubernetesワークロードで使用するNUMA対応のスケジューリング設定。
Metal LB設定(30.10項 「MetalLB」): Kubernetesワークロードで使用するMetal LB設定。
プライベートレジストリ設定(30.11項 「プライベートレジストリ設定」): Kubernetesワークロードで使用するプライベートレジストリ設定。
30.1 リアルタイム用のカーネルイメージ #
リアルタイムカーネルイメージは必ずしも標準カーネルより優れているとは限りません。リアルタイムカーネルは、特定のユースケース用に調整された別のカーネルです。低レイテンシを実現するために調整されていますが、その結果、スループットが犠牲になります。リアルタイムカーネルは一般的な用途には推奨されませんが、ここでは低レイテンシが重要な要因である通信ワークロード用のカーネルとして推奨されています。
主に4つの機能があります。
決定論的実行:
予測可能性の向上 — 高負荷状態でも重要なビジネスプロセスが期限内に確実に完了し、常に高品質なサービスを提供します。高優先度プロセスのために重要なシステムリソースを保護することで、時間に依存するアプリケーションの予測可能性を向上できます。
低ジッタ:
高度に決定論的な技術に基づいてジッタが低く抑えられているため、アプリケーションと実世界との同期を維持できます。これは、継続的に繰り返し計算を行う必要があるサービスで役立ちます。
優先度の継承:
優先度の継承とは、優先度の高いプロセスがある状況において、そのプロセスがタスクを完了するためには優先度の低いプロセスが完了するのを待つ必要がある場合に、優先度の低いプロセスが高優先度を一時的に引き受ける機能です。SUSE Linux Enterprise Real Timeは、ミッションクリティカルなプロセスにおけるこのような優先度の逆転の問題を解決します。
スレッドの割り込み:
一般的なオペレーティングシステムでは、割り込みモードで実行中のプロセスはプリエンプト可能ではありません。SUSE Linux Enterprise Real Timeでは、このような割り込みをカーネルスレッドでカプセル化して割り込み可能にし、ユーザが定義した高優先度プロセスでハード割り込みとソフト割り込みをプリエンプトできます。
ここでは、
SLE Micro RT
のようなリアルタイムイメージをインストール済みの場合、カーネルリアルタイムはすでにインストールされています。リアルタイムカーネルイメージはSUSE Customer Centerからダウンロードできます。注記リアルタイムカーネルの詳細については、SUSE Real Timeを参照してください。
30.2 CPU調整設定 #
CPU調整設定を使用すると、リアルタイムカーネルが使用するCPUコアを分離できます。OSがリアルタイムカーネルと同じコアを使用しないようにすることが重要です。OSがそのコアを使用すると、リアルタイムカーネルの遅延が増加するためです。
この機能を有効にして設定するには、まず、分離するCPUコアのプロファイルを作成します。ここでは、コア1-30
および33-62
を分離しています。
$ 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.
次に、GRUBオプションを変更して、CPUコアと、CPUの使用法に関するその他の重要なパラメータを分離する必要があります。現在のハードウェア仕様で次のオプションをカスタマイズすることが重要です。
パラメータ | 値 | 説明 |
---|---|---|
isolcpus | 1-30、33-62 | コア1-30および33-62を分離します。 |
skew_tick | 1 | このオプションを使用すると、カーネルは分離されたCPU全体でタイマー割り込みをずらすことができます。 |
nohz | on | このオプションを使用すると、カーネルはシステムがアイドル状態のときに1つのCPU上でタイマーティックを実行できます。 |
nohz_full | 1-30、33-62 | カーネルブートパラメータは、完全なdynticksとCPU分離の設定を行うための現在の主要インタフェースです。 |
rcu_nocbs | 1-30、33-62 | このオプションを使用すると、カーネルはシステムがアイドル状態のときに1つのCPU上でRCUコールバックを実行できます。 |
kthread_cpus | 0、31、32、63 | このオプションを使用すると、システムがアイドル状態のときに1つのCPU上でkthreadsを実行できます。 |
irqaffinity | 0、31、32、63 | このオプションを使用すると、システムがアイドル状態のときに1つのCPU上で割り込みを実行できます。 |
processor.max_cstate | 1 | このオプションを使用すると、アイドル状態のときにCPUがスリープ状態になるのを防ぎます。 |
intel_idle.max_cstate | 0 | このオプションを使用すると、intel_idleドライバが無効になり、acpi_idleを使用できるようになります。 |
上記の値を使用することで、60個のコアを分離し、4個のコアをOSに使用します。
次のコマンドでGRUB設定を変更し、上記の変更を次回ブート時に適用します。
/etc/default/grub
ファイルを編集し、上記のパラメータを追加します。
GRUB_CMDLINE_LINUX="intel_iommu=on intel_pstate=passive processor.max_cstate=1 intel_idle.max_cstate=0 iommu=pt usbcore.autosuspend=-1 selinux=0 enforcing=0 nmi_watchdog=0 crashkernel=auto softlockup_panic=0 audit=0 mce=off hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 default_hugepagesz=1G kthread_cpus=0,31,32,63 irqaffinity=0,31,32,63 isolcpus=1-30,33-62 skew_tick=1 nohz_full=1-30,33-62 rcu_nocbs=1-30,33-62 rcu_nocb_poll"
GRUB設定を更新します。
$ transactional-update grub.cfg $ reboot
再起動後にパラメータが適用されていることを検証するには、次のコマンドを使用してカーネルコマンドラインを確認できます。
$ cat /proc/cmdline
30.3 CNI設定 #
30.3.1 Cilium #
Cilium
はATIPのデフォルトのCNIプラグインです。RKE2クラスタでCiliumをデフォルトのプラグインとして有効にするには、/etc/rancher/rke2/config.yaml
ファイルに次の設定が必要です。
cni:
- cilium
これはコマンドライン引数でも指定できます。具体的には、/etc/systemd/system/rke2-server
ファイルのサーバの行に--cni=cilium
を追加します。
次のセクション(30.4項 「SR-IOV」)で説明するSR-IOV
Network
Operatorを使用するには、Multus
とともに、Cilium
やCalico
などの別のCNIプラグインをセカンダリプラグインとして使用します。
cni:
- multus
- cilium
CNIプラグインの詳細については、「Network Options (ネットワークオプション)」を参照してください。
30.4 SR-IOV #
SR-IOVを使用すると、ネットワークアダプタなどのデバイスで、そのリソースへのアクセスをさまざまなPCIe
ハードウェア機能の間で分離することができます。SR-IOV
をデプロイするにはさまざまな方法がありますが、ここでは2つの方法を示します。
オプション1:
SR-IOV
CNIデバイスプラグインと設定マップを使用して適切に設定する。オプション2 (推奨): Rancher Primeから
SR-IOV
Helmチャートを使用してこのデプロイメントを簡単に行えるようにする。
オプション1 - SR-IOV CNIデバイスプラグインと設定マップをインストールして適切に設定する
デバイスプラグインの設定マップを準備する
設定マップに入力する情報を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)
設定マップはJSON
ファイルで構成され、このファイルで、フィルタを使用して検出を行うデバイスを記述し、インタフェースのグループを作成します。フィルタとグループを理解することが重要です。フィルタはデバイスを検出するために使用され、グループはインタフェースを作成するために使用されます。
フィルタを設定することもできます。
vendorID:
8086
(Intel)deviceID:
0d5c
(アクセラレータカード)driver:
vfio-pci
(ドライバ)pfNames:
p2p1
(物理インタフェース名)
フィルタを設定して、より複雑なインタフェース構文に一致させることもできます。次に例を示します。
pfNames:
["eth1#1,2,3,4,5,6"]
または[eth1#1-6]
(物理インタフェース名)
グループに関連して、FEC
カード用のグループを1つと、Intel
カード用のグループを1つ作成し、さらに、ユースケースに応じてプレフィックスを作成することもできます。
resourceName:
pci_sriov_net_bh_dpdk
resourcePrefix:
Rancher.io
リソースグループを検出して作成し、一部のVF
をPodに割り当てる組み合わせは多数あります。
フィルタとグループの詳細については、「sriov-network-device-plugin (sr-iovネットワークデバイスプラグイン)」を参照してください。
フィルタとグループを設定して、ハードウェアとユースケースに応じたインタフェースに一致させると、使用する例が次の設定マップに表示されます。
apiVersion: v1
kind: ConfigMap
metadata:
name: sriovdp-config
namespace: kube-system
data:
config.json: |
{
"resourceList": [
{
"resourceName": "intel_fec_5g",
"devicetype": "accelerator",
"selectors": {
"vendors": ["8086"],
"devices": ["0d5d"]
}
},
{
"resourceName": "intel_sriov_odu",
"selectors": {
"vendors": ["8086"],
"devices": ["1889"],
"drivers": ["vfio-pci"],
"pfNames": ["p2p1"]
}
},
{
"resourceName": "intel_sriov_oru",
"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: rancher/hardened-sriov-network-device-plugin:v3.5.1-build20231009-amd64
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.json
設定マップと
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 $(kubectl get nodes -oname) -o jsonpath='{.status.allocatable}' | jq { "cpu": "64", "ephemeral-storage": "256196109726", "hugepages-1Gi": "40Gi", "hugepages-2Mi": "0", "intel.com/intel_fec_5g": "1", "intel.com/intel_sriov_odu": "4", "intel.com/intel_sriov_oru": "4", "memory": "221396384Ki", "pods": "110" }
FEC
はintel.com/intel_fec_5g
で、値は1です。Helmチャートを使用せずに、デバイスプラグインと設定マップを使用してデプロイした場合、
VF
は、intel.com/intel_sriov_odu
またはintel.com/intel_sriov_oru
です。
ここにインタフェースがない場合、そのインタフェースをPodで使用することはできないため、続行しても意味がありません。まず、設定マップとフィルタを確認して問題を解決してください。
オプション2 (推奨) - Rancherを使用し、SR-IOV CNIおよびデバイスプラグイン用のHelmチャートを使用したインストール
Helmがない場合は入手します。
$ curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
SR-IOVをインストールします。
この部分は2つの方法で実行できます。CLI
を使用する方法と、Rancher
UI
を使用する方法です。
- CLIからのオペレータのインストール
helm repo add suse-edge https://suse-edge.github.io/charts helm install sriov-crd suse-edge/sriov-crd -n sriov-network-operator helm install install sriov-network-operator suse-edge/sriov-network-operator -n sriov-network-operator
- Rancher UIからのオペレータのインストール
クラスタがインストールされたら、
Rancher UI
にアクセスできるようになり、[Apps (アプリ)]タブでRancher UI
からSR-IOVオペレータ
をインストールできます。
必ず、正しいネームスペースを選択してオペレータをインストールしてください(例:
sriov-network-operator
)。
+ image::features_sriov.png[sriov.png]
デプロイしたリソースのcrdとPodを確認します。
$ kubectl get crd $ kubectl -n sriov-network-operator get pods
ノードのラベルを確認します。
すべてのリソースが実行されていると、ラベルがノードに自動的に表示されます。
$ 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 -A NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE calico-system calico-node 1 1 1 1 1 kubernetes.io/os=linux 15h 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 kube-system rke2-ingress-nginx-controller 1 1 1 1 1 kubernetes.io/os=linux 15h kube-system rke2-multus-ds 1 1 1 1 1 kubernetes.io/arch=amd64,kubernetes.io/os=linux 15h
数分後(更新に最大で10分かかる可能性があります)、ノードが検出されて、SR-IOV
の機能が設定されます。
$ kubectl get sriovnetworknodestates.sriovnetwork.openshift.io -A NAMESPACE NAME AGE sriov-network-operator xr11-2 83s
検出されたインタフェースを確認します。
検出されたインタフェースはネットワークデバイスのPCIアドレスである必要があります。この情報は、ホストでlspci
コマンドを使用して確認します。
$ kubectl get sriovnetworknodestates.sriovnetwork.openshift.io -n kube-system -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
デーモンセットの再起動が必要になります)。
NetworkNodeポリシー
を作成してVF
を設定します。
VF
(numVfs
)がデバイス(rootDevices
)から作成され、ドライバdeviceType
とMTU
が設定されます。
resourceName
フィールドには特殊文字を含めないでください。また、このフィールドはクラスタ全体で一意である必要があります。この例では、dpdk
をsr-iov
と組み合わせて使用するため、deviceType:
vfio-pci
を使用しています。dpdk
を使用しない場合は、deviceTypeを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
設定を検証します。
$ kubectl get $(kubectl get nodes -oname) -o jsonpath='{.status.allocatable}' | jq { "cpu": "64", "ephemeral-storage": "256196109726", "hugepages-1Gi": "60Gi", "hugepages-2Mi": "0", "intel.com/intel_fec_5g": "1", "memory": "200424836Ki", "pods": "110", "rancher.io/intelnicsDpdk": "8" }
sr-iovネットワークを作成します(別のネットワークが必要な場合のオプション)。
apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetwork
metadata:
name: network-dpdk
namespace: sriov-network-operator
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
作成されたネットワークを確認します。
$ kubectl get network-attachment-definitions.k8s.cni.cncf.io -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: sriov-network-operator resourceVersion: "13124" uid: df7c89f5-177c-4f30-ae72-7aef3294fb15 spec: config: '{ "cniVersion":"0.3.1", "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: ""
30.5 DPDK #
DPDK
(データプレーン開発キット)は、パケットの高速処理用の一連のライブラリとドライバです。DPDKは、広範なCPUアーキテクチャ上で実行されるパケット処理ワークロードを高速化するために使用されます。DPDKには、データプレーンライブラリと、以下のために最適化されたネットワークインタフェースコントローラ(NIC
)ドライバが含まれています。
キューマネージャはロックなしのキューを実装します。
バッファマネージャは固定サイズのバッファを事前割り当てします。
メモリマネージャは、メモリ内にオブジェクトのプールを割り当て、リングを使用してフリーオブジェクトを格納します。オブジェクトがすべての
DRAM
チャンネルに均等に分散されるようにします。ポールモードドライバ(
PMD
)は、非同期通知なしで動作するように設計されているため、オーバーヘッドが軽減されます。パケット処理を開発するためのヘルパである一連のライブラリとしてのパケットフレームワーク。
次の手順では、DPDK
を有効にする方法と、DPDK
インタフェースが使用するNIC
からVF
を作成する方法を示します。
DPDK
パッケージをインストールします。
$ transactional-update pkg install dpdk22 dpdk22-tools libdpdk-23 $ reboot
カーネルパラメータ:
DPDKを使用するには、ドライバをいくつか使用して、カーネルの特定のパラメータを有効にします。
パラメータ | 値 | 説明 |
---|---|---|
iommu | pt | このオプションを使用すると、DPDKインタフェースに |
intel_iommu | on | このオプションを使用すると、 |
これらのパラメータを有効にするには、各パラメータを/etc/default/grub
ファイルに追加します。
GRUB_CMDLINE_LINUX="intel_iommu=on intel_pstate=passive processor.max_cstate=1 intel_idle.max_cstate=0 iommu=pt usbcore.autosuspend=-1 selinux=0 enforcing=0 nmi_watchdog=0 crashkernel=auto softlockup_panic=0 audit=0 mce=off hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 default_hugepagesz=1G kthread_cpus=0,31,32,63 irqaffinity=0,31,32,63 isolcpus=1-30,33-62 skew_tick=1 nohz_full=1-30,33-62 rcu_nocbs=1-30,33-62 rcu_nocb_poll"
GRUBの設定を更新し、システムを再起動して変更を適用します。
$ transactional-update grub.cfg $ reboot
vfio-pci
カーネルモジュールを読み込み、NIC
でSR-IOV
を有効にします。
$ modprobe vfio-pci enable_sriov=1 disable_idle_d3=1
NIC
から仮想機能(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-pci
30.6 vRANアクセラレーション(Intel ACC100/ACC200
) #
4Gから5Gネットワークへの移行に伴い、多くの通信サービスプロバイダが仮想化無線アクセスネットワーク(vRAN
)アーキテクチャを採用して、チャンネル容量を増やし、エッジベースのサービスとアプリケーションのデプロイメントを容易にしようとしています。vRANソリューションは、ネットワーク上のリアルタイムのトラフィックと需要の量に応じて容量を柔軟に増減できるため、低レイテンシのサービスを提供するのに理想的です。
4Gおよび5Gで最も計算負荷が高いワークロードの1つがRANレイヤ1
(L1
)のFEC
です。これは、信頼性の低い通信チャンネルやノイズの多い通信チャンネルでのデータ伝送エラーを解消するものです。FEC
技術は、4Gまたは5Gデータの一定数のエラーを検出して訂正することで、再送信の必要性を解消します。FEC
アクセラレーショントランザクションにはセルの状態情報が含まれないため、簡単に仮想化でき、プールするメリットとセルの容易な移行が実現します。
カーネルパラメータ
vRAN
アクセラレーションを有効にするには、次のカーネルパラメータを有効にする必要があります(まだ存在しない場合)。
パラメータ | 値 | 説明 |
---|---|---|
iommu | pt | このオプションを使用すると、DPDKインタフェースにvfioを使用できます。 |
intel_iommu | on | このオプションを使用すると、VFにvfioを使用できます。 |
GRUBファイル/etc/default/grub
を変更して、これらのパラメータをカーネルコマンドラインに追加します。
GRUB_CMDLINE_LINUX="intel_iommu=on intel_pstate=passive processor.max_cstate=1 intel_idle.max_cstate=0 iommu=pt usbcore.autosuspend=-1 selinux=0 enforcing=0 nmi_watchdog=0 crashkernel=auto softlockup_panic=0 audit=0 mce=off hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 default_hugepagesz=1G kthread_cpus=0,31,32,63 irqaffinity=0,31,32,63 isolcpus=1-30,33-62 skew_tick=1 nohz_full=1-30,33-62 rcu_nocbs=1-30,33-62 rcu_nocb_poll"
GRUBの設定を更新し、システムを再起動して変更を適用します。
$ transactional-update grub.cfg $ reboot
再起動後にパラメータが適用されていることを確認するには、コマンドラインを確認します。
$ cat /proc/cmdline
vfio-pciカーネルモジュールを読み込み、
vRAN
アクセラレーションを有効にします。
$ modprobe vfio-pci enable_sriov=1 disable_idle_d3=1
インタフェース情報Acc100を取得します。
$ 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
)から作成します。
2つのVF
をPF
から作成し、次の手順に従ってvfio-pci
にバインドします。
$ echo 2 > /sys/bus/pci/devices/0000:8a:00.0/sriov_numvfs $ dpdk-devbind.py -b vfio-pci 0000:8b:00.0
提案された設定ファイルを使用してacc100を設定します。
$ pf_bb_config ACC100 -c /opt/pf-bb-config/acc100_config_vf_5g.cfg 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 ACC100 configuration complete Tue Jun 6 10:49:21 2023:INFO:ACC100 PF [0000:8a:00.0] configuration complete!
FEC PFから作成した新しい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=
30.7 Huge Page #
プロセスがRAM
を使用すると、CPU
はそのメモリ領域をプロセスが使用中であるとマークします。効率を高めるために、CPU
はRAM
をチャンクで割り当てます。多くのプラットフォームでは4K
バイトがチャンクのデフォルト値です。これらのチャンクをページと呼び、ディスクなどにスワップできます。
プロセスのアドレススペースは仮想であるため、CPU
とオペレーティングシステムは、どのページがどのプロセスに属していて、各ページがどこに保管されているかを覚えておく必要があります。ページ数が多いほど、メモリマッピングの検索に時間がかかります。プロセスが1GB
のメモリを使用する場合、検索するエントリは262,144個になります(1GB
/ 4K
)。1つのページテーブルエントリが8バイトを消費する場合、2MB
(262,144 * 8)を検索することになります。
最新のCPU
アーキテクチャはデフォルトより大きいページをサポートしているので、CPU/OS
が検索するエントリが減少します。
カーネルパラメータ
Huge Pageを有効にするには、次のカーネルパラメータを追加する必要があります。
パラメータ | 値 | 説明 |
---|---|---|
hugepagesz | 1G | このオプションを使用すると、Huge Pageを1Gに設定できます |
hugepages | 40 | 前に定義したHuge Pageの数です |
default_hugepagesz | 1G | Huge Pageを取得するためのデフォルト値です |
GRUBファイル/etc/default/grub
を変更して、これらのパラメータをカーネルコマンドラインに追加します。
GRUB_CMDLINE_LINUX="intel_iommu=on intel_pstate=passive processor.max_cstate=1 intel_idle.max_cstate=0 iommu=pt usbcore.autosuspend=-1 selinux=0 enforcing=0 nmi_watchdog=0 crashkernel=auto softlockup_panic=0 audit=0 mce=off hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 default_hugepagesz=1G kthread_cpus=0,31,32,63 irqaffinity=0,31,32,63 isolcpus=1-30,33-62 skew_tick=1 nohz_full=1-30,33-62 rcu_nocbs=1-30,33-62 rcu_nocb_poll"
GRUBの設定を更新し、システムを再起動して変更を適用します。
$ transactional-update grub.cfg $ reboot
再起動後にパラメータが適用されていることを検証するには、次のコマンドラインを確認できます。
$ cat /proc/cmdline
Huge Pageの使用
Huge Pageを使用するには、Huge Pageをマウントする必要があります。
$ mkdir -p /hugepages $ mount -t hugetlbfs nodev /hugepages
Kubernetesワークロードをデプロイし、リソースとボリュームを作成します。
...
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
...
30.8 CPUピニング設定 #
要件
こちらのセクション(30.2項 「CPU調整設定」)で説明したパフォーマンスプロファイルに合わせて
CPU
が調整されていること。次のブロック(例)を
/etc/rancher/rke2/config.yaml
ファイルに追加して、RKE2
クラスタのkubeletにCPU管理の引数が設定されていること。
kubelet-arg:
- "cpu-manager=true"
- "cpu-manager-policy=static"
- "cpu-manager-policy-options=full-pcpus-only=true"
- "cpu-manager-reconcile-period=0s"
- "kubelet-reserved=cpu=1"
- "system-reserved=cpu=1"
KubernetesでのCPUピニングの使用
kubeletで定義された静的ポリシー
を使ってCPUピニング機能を使用する方法は、ワークロードに対して定義した要求と制限に応じて3つあります。
BestEffort
QoSクラス:CPU
に対して要求または制限を定義していない場合、Podはシステムで使用できる最初のCPU
でスケジュールされます。BestEffort
QoSクラスを使用する例を次に示します。spec: containers: - name: nginx image: nginx
Burstable
QoSクラス: CPUに対して要求を定義し、その要求が制限と同じではない場合、またはCPUの要求がない場合。Burstable
QoSクラスを使用する例を次に示します。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"
Guaranteed
QoSクラス: CPUに対して要求を定義し、その要求が制限と同じである場合。Guaranteed
QoSクラスを使用する例を次に示します。spec: containers: - name: nginx image: nginx resources: limits: memory: "200Mi" cpu: "2" requests: memory: "200Mi" cpu: "2"
30.9 NUMA対応のスケジューリング #
Non-Uniform Memory AccessまたはNon-Uniform Memory Architecture
(NUMA
)は、SMP
(マルチプロセッサ)アーキテクチャにおいて使用される物理メモリ設計であり、メモリアクセス時間がプロセッサからのメモリの相対的な位置によって異なります。NUMA
では、プロセッサは専用のローカルメモリに、非ローカルメモリ、つまり別のプロセッサにローカルなメモリや複数のプロセッサで共有されているメモリよりも高速にアクセスできます。
30.9.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
関連のメッセージが上書きされた可能性があります。
30.10 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: repo: https://metallb.github.io/metallb/ chart: metallb targetNamespace: metallb-system --- apiVersion: helm.cattle.io/v1 kind: HelmChart metadata: name: endpoint-copier-operator namespace: kube-system spec: repo: https://suse-edge.github.io/endpoint-copier-operator chart: endpoint-copier-operator targetNamespace: endpoint-copier-operator EOF
IpAddressPool
および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-pool
VIP
を公開するためのエンドポイントサービスを作成します。
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: LoadBalancer
VIP
が作成され、MetalLB
のPodが実行中であることを確認します。
$ kubectl get svc -n default $ kubectl get pods -n default
30.11 プライベートレジストリ設定 #
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を再起動します。
詳細については、「Containerd Registry Configuration | RKE2 (Containerdのレジストリ設定 | RKE2)」を確認してください。