9.4. 使用TAP CNI 运行具有内核访问权限的 rootless 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 权限的用户身份登录。
  • 确保在所有节点上将 container_use_devices=on 设置为 root。

    注意

    使用 Machine Config Operator 设置此 SELinux 布尔值。

流程

  1. 创建一个文件,如 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"
    Copy to Clipboard Toggle word wrap
  2. 运行以下命令来创建新的 Namespace 对象:

    $ oc apply -f test-namespace.yaml
    Copy to Clipboard Toggle word wrap
  3. 创建一个文件,如 sriov-node-network-policy.yaml,内容类似以下示例:

    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetworkNodePolicy
    metadata:
     name: sriovnic
     namespace: openshift-sriov-network-operator
    spec:
     deviceType: netdevice 
    1
    
     isRdma: true 
    2
    
     needVhostNet: true 
    3
    
     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"
    Copy to Clipboard Toggle word wrap
    1
    这表示配置集是为 Mellanox Network Interface Controller (NIC) 量身定制的。
    2
    只有 Mellanox NIC 才需要将 isRdma 设置为 true
    3
    这会将 /dev/net/tun/dev/vhost-net 设备挂载到容器中,以便应用可以创建 tap 设备,并将 tap 设备连接到 DPDK 工作负载。
    4
    SR-IOV 网络设备厂商的十六进制代码。值 15b3 代表与 Mellanox NIC 关联。
    5
    SR-IOV 网络设备的设备十六进制代码。
  4. 运行以下命令来创建 SriovNetworkNodePolicy 对象:

    $ oc create -f sriov-node-network-policy.yaml
    Copy to Clipboard Toggle word wrap
  5. 创建以下 SriovNetwork 对象,然后在 sriov-network-attachment.yaml 文件中保存 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"
    Copy to Clipboard Toggle word wrap
    注意

    如需 SriovNetwork 中的每个选项的详细说明,请参阅"Configuring SR-IOV additional network" 部分。

    一个可选的库 app-netutil 提供了多种 API 方法来收集有关容器父 pod 的网络信息。

  6. 运行以下命令来创建 SriovNetwork 对象:

    $ oc create -f sriov-network-attachment.yaml
    Copy to Clipboard Toggle word wrap
  7. 创建一个文件,如 tap-example.yaml,该文件定义网络附加定义,其内容类似以下示例:

    apiVersion: "k8s.cni.cncf.io/v1"
    kind: NetworkAttachmentDefinition
    metadata:
     name: tap-one
     namespace: test-namespace 
    1
    
    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
           }
         }
       ]
     }'
    Copy to Clipboard Toggle word wrap
    1
    指定创建 SriovNetwork 对象的 target_namespace
  8. 运行以下命令来创建 NetworkAttachmentDefinition 对象:

    $ oc apply -f tap-example.yaml
    Copy to Clipboard Toggle word wrap
  9. 创建一个文件,如 dpdk-pod-rootless.yaml,其内容类似以下示例:

    apiVersion: v1
    kind: Pod
    metadata:
      name: dpdk-app
      namespace: test-namespace 
    1
    
      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: 1001 
    2
    
          runAsGroup: 1001 
    3
    
          seccompProfile:
            type: RuntimeDefault
      containers:
      - name: testpmd
        image: <DPDK_image> 
    4
    
        securityContext:
          capabilities:
            drop: ["ALL"] 
    5
    
            add: 
    6
    
              - IPC_LOCK
              - NET_RAW #for mlx only 
    7
    
          runAsUser: 1001 
    8
    
          privileged: false 
    9
    
          allowPrivilegeEscalation: true 
    10
    
          runAsNonRoot: true 
    11
    
        volumeMounts:
        - mountPath: /mnt/huge 
    12
    
          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-performanceprofile 
    16
    
      volumes:
      - name: hugepages
        emptyDir:
          medium: HugePages
    Copy to Clipboard Toggle word wrap
    1
    指定 target_namespace 创建 SriovNetwork 对象。如果要在其他命名空间中创建 pod,在 Pod spec 和 SriovNetwork 对象中更改 target_namespace
    2
    设置在这些卷中创建的卷挂载目录和文件的组所有权。
    3
    指定用于运行容器的主要组 ID。
    4
    指定包含应用程序和应用程序使用的 DPDK 库的 DPDK 镜像。
    5
    从容器的 securityContext 中删除所有功能 (ALL) 意味着容器在正常操作之外没有特殊的特权。
    6
    指定容器内的应用程序进行大页分配、系统资源分配和网络接口访问所需的额外功能。这些功能还必须使用 setcap 命令在二进制文件中设置。
    7
    Mellanox 网络接口控制器(NIC)需要 NET_RAW 功能。
    8
    指定用于运行容器的用户 ID。
    9
    此设置表示 pod 中的容器或容器不应被授予对主机系统的特权访问权限。
    10
    此设置允许容器在可能已分配的初始非 root 特权外升级其特权。
    11
    此设置可确保容器以非 root 用户身份运行。这有助于强制实施最小特权的原则,限制对容器造成潜在的影响,并减少攻击面。
    12
    /mnt/huge 下将巨页卷挂载到 DPDK pod。巨页卷由 emptyDir 卷类型支持,medium 为Hugepages
    13
    可选:指定分配给 DPDK pod 的 DPDK 设备数。如果没有明确指定,则 SR-IOV 网络资源注入程序会自动添加此资源请求和限制。SR-IOV 网络资源注入程序是由 SR-IOV Operator 管理的准入控制器组件。它默认是启用的,可以通过把默认的 SriovOperatorConfig CR 中的 enableInjector 选项设置为 false 来禁用它。
    14
    指定 CPU 数量。DPDK pod 通常需要从 kubelet 分配专用 CPU。这可以通过将 CPU Manager 策略设置为 static,并创建带有有保障的 QoS 的 pod 来实现。
    15
    指定巨页大小 hugepages-1Gihugepages-2Mi 以及分配给 DPDK pod 的巨页数量。单独配置 2Mi1Gi 巨页。配置 1Gi 巨页需要在节点中添加内核参数。例如:添加内核参数 default_hugepagesz=1GBhugepagesz=1Ghugepages=16 将在系统引导时分配 16*1Gi 巨页。
    16
    如果您的性能配置集没有命名为 cnf-performance profile,请将该字符串替换为正确的性能配置集名称。
  10. 运行以下命令来创建 DPDK pod:

    $ oc create -f dpdk-pod-rootless.yaml
    Copy to Clipboard Toggle word wrap
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat