9.4. TAP CNI を使用したカーネルアクセスでのルートレス DPDK ワークロード実行
DPDK アプリケーションは、ログメッセージなどの特定の種類のパケットを処理のためにカーネルに挿入するための例外パスとして virtio-user を使用できます。この機能の詳細は、例外パスとしての Virtio_user を参照してください。
OpenShift Container Platform バージョン 4.14 以降では、非権限 Pod を使用して、tap CNI プラグインと一緒に DPDK アプリケーションを実行できます。この機能を有効にするには、SriovNetworkNodePolicy オブジェクト内で needVhostNet パラメーターを true に設定して、vhost-net デバイスをマウントする必要があります。
図9.1 DPDK と TAP の設定例
前提条件
-
OpenShift CLI (
oc) がインストールされている。 - SR-IOV Network Operator がインストールされている。
-
cluster-admin権限を持つユーザーとしてログインしている。 すべてのノードで
setsebools container_use_devices=onが root として設定されていることを確認します。注記Machine Config Operator を使用して、この SELinux ブール値を設定します。
手順
次の例のような内容を含むファイル (
test-namespace.yamlなど) を作成します。apiVersion: v1 kind: Namespace metadata: name: test-namespace labels: pod-security.kubernetes.io/enforce: privileged pod-security.kubernetes.io/audit: privileged pod-security.kubernetes.io/warn: privileged security.openshift.io/scc.podSecurityLabelSync: "false"次のコマンドを実行して、
Namespaceオブジェクトを新規作成します。$ oc apply -f test-namespace.yaml次の例のようなコンテンツを含むファイル (
sriov-node-network-policy.yamlなど) を作成します。apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetworkNodePolicy metadata: name: sriovnic namespace: openshift-sriov-network-operator spec: deviceType: netdevice1 isRdma: true2 needVhostNet: true3 nicSelector: vendor: "15b3"4 deviceID: "101b"5 rootDevices: ["00:05.0"] numVfs: 10 priority: 99 resourceName: sriovnic nodeSelector: feature.node.kubernetes.io/network-sriov.capable: "true"- 1
- これは、プロファイルが Mellanox ネットワークインターフェイスコントローラー (NIC) 専用に調整されていることを示します。
- 2
isRdmaをtrueに設定する必要があるのは、Mellanox NIC の場合のみです。- 3
- これにより、
/dev/net/tunおよび/dev/vhost-netデバイスがコンテナーにマウントされ、アプリケーションがタップデバイスを作成し、タップデバイスを DPDK ワークロードに接続できるようになります。 - 4
- SR-IOV ネットワークデバイスのベンダーの 16 進数コード。値 15b3 は Mellanox NIC に関連付けられています。
- 5
- SR-IOV ネットワークデバイスのデバイスの 16 進数コード。
以下のコマンドを実行して
SriovNetworkNodePolicyオブジェクトを作成します。$ oc create -f sriov-node-network-policy.yaml次の
SriovNetworkオブジェクトを作成し、YAML をsriov-network-attachment.yamlファイルに保存します。apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetwork metadata: name: sriov-network namespace: openshift-sriov-network-operator spec: networkNamespace: test-namespace resourceName: sriovnic spoofChk: "off" trust: "on"注記SriovNetworkの各オプションに関する詳細は、「SR-IOV の追加ネットワークの設定」セクションを参照してください。オプションのライブラリー
app-netutilは、コンテナーの親 Pod に関するネットワーク情報を収集するための複数の API メソッドを提供します。以下のコマンドを実行して、
SriovNetworkオブジェクトを作成します。$ oc create -f sriov-network-attachment.yaml次の例のような内容を含む、ネットワーク割り当て定義を指定するファイル (
tap-example.yamlなど) を作成します。apiVersion: "k8s.cni.cncf.io/v1" kind: NetworkAttachmentDefinition metadata: name: tap-one namespace: test-namespace1 spec: config: '{ "cniVersion": "0.4.0", "name": "tap", "plugins": [ { "type": "tap", "multiQueue": true, "selinuxcontext": "system_u:system_r:container_t:s0" }, { "type":"tuning", "capabilities":{ "mac":true } } ] }'- 1
SriovNetworkオブジェクトが作成されるのと同じtarget_namespaceを指定します。
次のコマンドを実行して、
NetworkAttachmentDefinitionオブジェクトを作成します。$ oc apply -f tap-example.yaml次の例のような内容を含むファイル (
dpdk-pod-rootless.yamlなど) を作成します。apiVersion: v1 kind: Pod metadata: name: dpdk-app namespace: test-namespace1 annotations: k8s.v1.cni.cncf.io/networks: '[ {"name": "sriov-network", "namespace": "test-namespace"}, {"name": "tap-one", "interface": "ext0", "namespace": "test-namespace"}]' spec: nodeSelector: kubernetes.io/hostname: "worker-0" securityContext: fsGroup: 10012 runAsGroup: 10013 seccompProfile: type: RuntimeDefault containers: - name: testpmd image: <DPDK_image>4 securityContext: capabilities: drop: ["ALL"]5 add:6 - IPC_LOCK - NET_RAW #for mlx only7 runAsUser: 10018 privileged: false9 allowPrivilegeEscalation: true10 runAsNonRoot: true11 volumeMounts: - mountPath: /mnt/huge12 name: hugepages resources: limits: openshift.io/sriovnic: "1"13 memory: "1Gi" cpu: "4"14 hugepages-1Gi: "4Gi"15 requests: openshift.io/sriovnic: "1" memory: "1Gi" cpu: "4" hugepages-1Gi: "4Gi" command: ["sleep", "infinity"] runtimeClassName: performance-cnf-performanceprofile16 volumes: - name: hugepages emptyDir: medium: HugePages- 1
SriovNetworkオブジェクトが作成されるのと同じtarget_namespaceを指定します。Pod を別の namespace に作成する場合は、target_namespaceをPod仕様とSriovNetworkオブジェクトの両方で変更します。- 2
- ボリュームにマウントされたディレクトリーおよびそれらのボリューム内に作成されたファイルのグループ所有権を設定します。
- 3
- コンテナーの実行に使用するプライマリーグループ ID を指定します。
- 4
- アプリケーションを含む DPDK イメージとアプリケーションで使用される DPDK ライブラリーを指定します。
- 5
- コンテナーの securityContext からすべての機能 (
ALL) を削除すると、通常の操作に必要とされる権限以上の権限がコンテナーからなくなります。 - 6
- hugepage の割り当て、システムリソースの割り当て、およびネットワークインターフェイスアクセス用のコンテナー内のアプリケーションに必要な追加機能を指定します。これらの機能は、
setcapコマンドを使用してバイナリーファイルでも設定する必要があります。 - 7
- Mellanox ネットワークインターフェイスコントローラー (NIC) には、
NET_RAW機能が必要です。 - 8
- コンテナーの実行に使用するユーザー ID を指定します。
- 9
- この設定で、Pod 内のコンテナー (複数可) にホストシステムへの権限アクセスを許可しないように指定します。
- 10
- この設定を使用すると、コンテナーは、割り当てられている初期の root 以外の権限を超えて権限を昇格できます。
- 11
- また、この設定により、コンテナーは root 以外のユーザーで実行されます。これにより、最小権限の原則が適用され、コンテナーが不正アクセスされる可能性を最小限に抑えるとともに、攻撃対象領域を減少させます。
- 12
- hugepage ボリュームを
/mnt/hugeの下の DPDK Pod にマウントします。hugepage ボリュームは、メディアがHugepagesに指定されている emptyDir ボリュームタイプでサポートされます。 - 13
- オプション: DPDK Pod に割り当てられる DPDK デバイスの数を指定します。このリソース要求および制限は、明示的に指定されていない場合、SR-IOV ネットワークリソースインジェクターによって自動的に追加されます。SR-IOV ネットワークリソースインジェクターは、SR-IOV Operator によって管理される受付コントローラーコンポーネントです。これはデフォルトで有効にされており、デフォルト
SriovOperatorConfigCR でenableInjectorオプションをfalseに設定して無効にすることができます。 - 14
- CPU の数を指定します。DPDK Pod には通常、kubelet から排他的 CPU を割り当てる必要があります。これは、CPU マネージャーポリシーを
staticに設定し、GuaranteedQoS を持つ Pod を作成して実行されます。 - 15
- hugepage サイズ
hugepages-1Giまたはhugepages-2Miを指定し、DPDK Pod に割り当てられる hugepage の量を指定します。2Miおよび1Gihugepage を別々に設定します。1Gihugepage を設定するには、カーネル引数をノードに追加する必要があります。たとえば、カーネル引数default_hugepagesz=1GB、hugepagesz=1Gおよびhugepages=16を追加すると、16*1Gihugepage がシステムの起動時に割り当てられます。 - 16
- パフォーマンスプロファイルの名前が
cnf-performance profileでない場合は、その文字列を正しいパフォーマンスプロファイル名に置き換えます。
以下のコマンドを実行して DPDK Pod を作成します。
$ oc create -f dpdk-pod-rootless.yaml