Red Hat Training

A Red Hat training course is available for Red Hat OpenStack Platform

第5章 同一コンピュートノード上での SR-IOV および DPDK インターフェースの設定

本項では、同じコンピュートノード上に SR-IOV および DPDK インターフェースをデプロイする方法について説明します。

注記

本ガイドでは、CPU の割り当て、メモリーの確保、NIC の設定の例を紹介します。これらは、トポロジーとユースケースによって異なる場合があります。ハードウェアと設定のオプションについて理解するには、『ネットワーク機能仮想化 (NFV) の製品ガイド』および『ネットワーク機能仮想化 (NFV) のプランニングガイド』を参照してください。

同じコンピュートノード上に SR-IOV および DPDK インターフェースを作成およびデプロイするプロセスは以下のとおりです。

  • network-environment.yaml ファイルに SR-IOV ロールおよび OVS-DPDK ロール用のパラメーターを設定する。
  • compute.yaml ファイルに SR-IOV インターフェースおよび DPDK インターフェースを設定する。
  • 更新されたこのロールセットでオーバークラウドをデプロイする。
  • これらのインターフェース種別に対応する、適切な OpenStack フレーバー、ネットワークおよびポートを作成する。

以下のネットワーク設定を推奨します。

  • ゲストインスタンスに Floating IP アドレスを使用する。
  • ルーターを作成し、それを DPDK VXLAN ネットワーク (管理ネットワーク) に接続する。
  • プロバイダーネットワークに SR-IOV を使用する。
  • 2 つのポートをアタッチしたゲストインスタンスをブートする。ゲストインスタンスに cloud-init を使用して、管理ネットワークのデフォルトルートを設定することを推奨します。
  • ブートしたゲストインスタンスに Floating IP アドレスを追加する。
注記

最大限のパフォーマンスを得るために、必要に応じてゲストインスタンスに SR-IOV ボンディングを使用して、両方の SR-IOV インスタンスが同じ NUMA ノード上に設定されるようにしてください。

オーバークラウドにコンピュートノードをデプロイする前に、アンダークラウドのインストールと設定が完了している必要があります。詳しくは、『director のインストールと使用方法』を参照してください。

注記

このカスタムロールに一致する OpenStack フレーバーを作成するようにしてください。

5.1. first-boot.yaml ファイルの変更

first-boot.yaml ファイルを変更し、OVS および DPDK パラメーターを設定し、CPU アフィニティー用に tuned を設定します。

注記

以前のデプロイメントで first-boot.yaml ファイルに以下の行を追加している場合、Open vSwitch 2.9 を使用する Red Hat OpenStack Platform 10 ではこれらの行を削除してください。

ovs_service_path="/usr/lib/systemd/system/ovs-vswitchd.service"
grep -q "RuntimeDirectoryMode=.*" $ovs_service_path

if [ "$?" -eq 0 ]; then
    sed -i 's/RuntimeDirectoryMode=.*/RuntimeDirectoryMode=0775/' $ovs_service_path
else
    echo "RuntimeDirectoryMode=0775" >> $ovs_service_path
fi

grep -Fxq "Group=qemu" $ovs_service_path

if [ ! "$?" -eq 0 ]; then
    echo "Group=qemu" >> $ovs_service_path
fi

grep -Fxq "UMask=0002" $ovs_service_path

if [ ! "$?" -eq 0 ]; then
    echo "UMask=0002" >> $ovs_service_path
fi

ovs_ctl_path='/usr/share/openvswitch/scripts/ovs-ctl'
grep -q "umask 0002 \&\& start_daemon \"\$OVS_VSWITCHD_PRIORITY\"" $ovs_ctl_path

if [ ! "$?" -eq 0 ]; then
    sed -i 's/start_daemon \"\$OVS_VSWITCHD_PRIORITY.*/umask 0002 \&\& start_daemon \"$OVS_VSWITCHD_PRIORITY\" \"$OVS_VSWITCHD_WRAPPER\" \"$@\"/' $ovs_ctl_path
fi
  1. 新たなリソースを追加します。

      resources:
        userdata:
          type: OS::Heat::MultipartMime
          properties:
            parts:
            - config: {get_resource: set_dpdk_params}
            - config: {get_resource: install_tuned}
            - config: {get_resource: compute_kernel_args}
  2. DPDK パラメーターを設定します。

      set_dpdk_params:
        type: OS::Heat::SoftwareConfig
        properties:
          config:
            str_replace:
              template: |
                #!/bin/bash
                set -x
                get_mask()
                {
                  local list=$1
                  local mask=0
                  declare -a bm
                  max_idx=0
                  for core in $(echo $list | sed 's/,/ /g')
                  do
                      index=$(($core/32))
                      bm[$index]=0
                      if [ $max_idx -lt $index ]; then
                         max_idx=$(($index))
                      fi
                  done
                  for ((i=$max_idx;i>=0;i--));
                  do
                      bm[$i]=0
                  done
                  for core in $(echo $list | sed 's/,/ /g')
                  do
                      index=$(($core/32))
                      temp=$((1<<$(($core % 32))))
                      bm[$index]=$((${bm[$index]} | $temp))
                  done
    
                  printf -v mask "%x" "${bm[$max_idx]}"
                  for ((i=$max_idx-1;i>=0;i--));
                  do
                      printf -v hex "%08x" "${bm[$i]}"
                      mask+=$hex
                  done
                  printf "%s" "$mask"
                }
    
                FORMAT=$COMPUTE_HOSTNAME_FORMAT
                if [[ -z $FORMAT ]] ; then
                  FORMAT="compute" ;
                else
                  # Assumption: only %index% and %stackname% are the variables in Host name format
                  FORMAT=$(echo $FORMAT | sed  's/\%index\%//g' | sed 's/\%stackname\%//g') ;
                fi
                if [[ $(hostname) == *$FORMAT* ]] ; then
                  # 42477 is the kolla hugetlbfs gid value.
                  getent group hugetlbfs >/dev/null || \
                    groupadd hugetlbfs -g 42477 && groupmod -g 42477 hugetlbfs
    
                  pmd_cpu_mask=$( get_mask $PMD_CORES )
                  host_cpu_mask=$( get_mask $LCORE_LIST )
                  socket_mem=$(echo $SOCKET_MEMORY | sed s/\'//g )
                  ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true
                  ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-socket-mem=$socket_mem
                  ovs-vsctl --no-wait set Open_vSwitch . other_config:pmd-cpu-mask=$pmd_cpu_mask
                  ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-lcore-mask=$host_cpu_mask
                fi
              params:
                $COMPUTE_HOSTNAME_FORMAT: {get_param: ComputeHostnameFormat}
                $LCORE_LIST: {get_param: HostCpusList}
                $PMD_CORES: {get_param: NeutronDpdkCoreList}
                $SOCKET_MEMORY: {get_param: NeutronDpdkSocketMemory}
  3. tuned 設定を定義して CPU アフィニティーを提供します。

      install_tuned:
        type: OS::Heat::SoftwareConfig
        properties:
          config:
            str_replace:
              template: |
                #!/bin/bash
                FORMAT=$COMPUTE_HOSTNAME_FORMAT
                if [[ -z $FORMAT ]] ; then
                  FORMAT="compute" ;
                else
                  # Assumption: only %index% and %stackname% are the variables in Host name format
                  FORMAT=$(echo $FORMAT | sed  's/\%index\%//g' | sed 's/\%stackname\%//g') ;
                fi
                if [[ $(hostname) == *$FORMAT* ]] ; then
                  # Install the tuned package
                  yum install -y tuned-profiles-cpu-partitioning
    
                  tuned_conf_path="/etc/tuned/cpu-partitioning-variables.conf"
                  if [ -n "$TUNED_CORES" ]; then
                    grep -q "^isolated_cores" $tuned_conf_path
                    if [ "$?" -eq 0 ]; then
                      sed -i 's/^isolated_cores=.*/isolated_cores=$TUNED_CORES/' $tuned_conf_path
                    else
                      echo "isolated_cores=$TUNED_CORES" >> $tuned_conf_path
                    fi
                    tuned-adm profile cpu-partitioning
                  fi
                fi
              params:
                $COMPUTE_HOSTNAME_FORMAT: {get_param: ComputeHostnameFormat}
                $TUNED_CORES: {get_param: HostIsolatedCoreList}
  4. カーネルの引数を設定します。

      compute_kernel_args:
        type: OS::Heat::SoftwareConfig
        properties:
          config:
            str_replace:
              template: |
                #!/bin/bash
                FORMAT=$COMPUTE_HOSTNAME_FORMAT
                if [[ -z $FORMAT ]] ; then
                  FORMAT="compute" ;
                else
                  # Assumption: only %index% and %stackname% are the variables in Host name format
                  FORMAT=$(echo $FORMAT | sed  's/\%index\%//g' | sed 's/\%stackname\%//g') ;
                fi
                if [[ $(hostname) == *$FORMAT* ]] ; then
                  sed 's/^\(GRUB_CMDLINE_LINUX=".*\)"/\1 $KERNEL_ARGS isolcpus=$TUNED_CORES"/g' -i /etc/default/grub ;
                  grub2-mkconfig -o /etc/grub2.cfg
                  reboot
                fi
              params:
                $KERNEL_ARGS: {get_param: ComputeKernelArgs}
                $COMPUTE_HOSTNAME_FORMAT: {get_param: ComputeHostnameFormat}
                $TUNED_CORES: {get_param: HostIsolatedCoreList}

5.2. セキュリティーグループ用 openvswitch の設定 (テクノロジープレビュー)

データプレーンインターフェースのステートフルファイアウォールには、高いパフォーマンスが要求されます。これらのインターフェースを保護するためには、通信業界グレードのファイアウォール (VNF) をデプロイすることを検討してください。

コントロールプレーンインターフェースを設定するには、NeutronOVSFirewallDriver パラメーターに openvswitch を設定します。これにより、OpenStack Networking はフローベースの OVS ファイアウォールドライバーを使用するように設定されます。この設定は、network-environment.yaml ファイルの parameter_defaults セクションで行います。

以下に例を示します。

parameter_defaults:
  NeutronOVSFirewallDriver: openvswitch
注記

Openvswitch はテクノロジープレビューの機能で、テスト環境でのみ使用する必要があります。サポートされる NeutronOVSFirewallDriver パラメーターの値は noop だけです。

OVS ファイアウォールドライバーを使用する場合には、データプレーンインターフェース用にはこのドライバーを無効にすることが重要です。そのためには、openstack port set コマンドを使用します。

以下に例を示します。

openstack port set --no-security-group  --disable-port-security ${PORT}

5.3. SR-IOV および OVS-DPDK パラメーターの定義

network-environment.yaml ファイルを変更し、SR-IOV および OVS-DPDK ロールに固有のパラメーターを設定します。

  1. これらのノードのネットワーク設定と共に、OVS-DPDK および SR-IOV サービスのリソースマッピングを network-environment.yaml ファイルに追加します。

      resource_registry:
        # Specify the relative/absolute path to the config files you want to use for override the default.
        OS::TripleO::Compute::Net::SoftwareConfig: nic-configs/compute.yaml
        OS::TripleO::Controller::Net::SoftwareConfig: nic-configs/controller.yaml
        OS::TripleO::NodeUserData: first-boot.yaml
  2. フレーバーを定義します。

      OvercloudControlFlavor: controller
      OvercloudComputeFlavor: compute
  3. トンネルの種別を定義します。

      # The tunnel type for the tenant network (vxlan or gre). Set to '' to disable tunneling.
      NeutronTunnelTypes: 'vxlan'
      # The tenant network type for Neutron (vlan or vxlan).
      NeutronNetworkType: 'vlan'
  4. SR-IOV のパラメーターを設定します。lspci -nv を実行すると、NeutronSupportedPCIVendorDevs パラメーターに PCI ベンダーおよびデバイスの値が表示されます。

    注記

    以下の例に示すように、OpenvSwitch ファイアウォールドライバーはテクノロジープレビューの機能で、コントロールプレーンインターフェースにのみ使用する必要があります。サポートされる NeutronOVSFirewallDriver パラメーターの値は noop だけです。詳しくは、「セキュリティーグループ用 openvswitch の設定」を参照してください。

      NeutronSupportedPCIVendorDevs: ['8086:154d', '8086:10ed']
      NovaPCIPassthrough:
        - devname: "p5p2"
          physical_network: "tenant"
    
      NeutronPhysicalDevMappings: "tenant:p5p2"
      NeutronSriovNumVFs: "p5p2:5"
      # Global MTU.
      NeutronGlobalPhysnetMtu: 9000
      # Configure the classname of the firewall driver to use for implementing security groups.
      NeutronOVSFirewallDriver: openvswitch
  5. OVS-DPDK のパラメーターを設定します。

      ########################
      # OVS DPDK configuration
      ## NeutronDpdkCoreList and NeutronDpdkMemoryChannels are REQUIRED settings.
      ## Attempting to deploy DPDK without appropriate values will cause deployment to fail or lead to unstable deployments.
      # List of cores to be used for DPDK Poll Mode Driver
      NeutronDpdkCoreList: "'2,22,3,23'"
      # Number of memory channels to be used for DPDK
      NeutronDpdkMemoryChannels: "4"
      # NeutronDpdkSocketMemory
      NeutronDpdkSocketMemory: "'3072,1024'"
      # NeutronDpdkDriverType
      NeutronDpdkDriverType: "vfio-pci"
      # The vhost-user socket directory for OVS
      NeutronVhostuserSocketDir: "/var/lib/vhost_sockets"
    
      ########################
      # Additional settings
      ########################
      # Reserved RAM for host processes
      NovaReservedHostMemory: 4096
      # A list or range of physical CPU cores to reserve for virtual machine processes.
      # Example: NovaVcpuPinSet: ['4-12','^8'] will reserve cores from 4-12 excluding 8
      NovaVcpuPinSet: "4-19,24-39"
      # An array of filters used by Nova to filter a node.These filters will be applied in the order they are listed,
      # so place your most restrictive filters first to make the filtering process more efficient.
      NovaSchedulerDefaultFilters:
        - "RetryFilter"
        - "AvailabilityZoneFilter"
        - "RamFilter"
        - "ComputeFilter"
        - "ComputeCapabilitiesFilter"
        - "ImagePropertiesFilter"
        - "ServerGroupAntiAffinityFilter"
        - "ServerGroupAffinityFilter"
        - "PciPassthroughFilter"
        - "NUMATopologyFilter"
        - "AggregateInstanceExtraSpecsFilter"
      # Kernel arguments for Compute node
      ComputeKernelArgs: "default_hugepagesz=1GB hugepagesz=1G hugepages=32 iommu=pt intel_iommu=on"
      # A list or range of physical CPU cores to be tuned.
      # The given args will be appended to the tuned cpu-partitioning profile.
      HostIsolatedCoreList: "2-19,22-39"
      # List of logical cores to be used by ovs-dpdk processess (dpdk-lcore-mask)
      HostCpusList: "'2-19,22-39'"
    注記

    ゲストインスタンス作成の失敗を避けるために、DPDK PMD 用の DPDK NIC の有無にかかわらず、各 NUMA ノード上で少なくとも 1 つの CPU を (シブリングスレッドと共に) 割り当てる必要があります。

  6. 実際の OpenStack デプロイメントでの必要に応じて、network-environment.yaml ファイルの残りのパラメーターを設定して、neutron-ovs-dpdk-agent.yaml および neutron-sriov-agent.yaml ファイルからのデフォルトパラメーターをオーバーライドします。

OVS-DPDK 向けの OpenStack ネットワークを最適化するには、『ネットワーク機能仮想化 (NFV) のプランニングガイド』を参照し、network-environment.yaml ファイルで設定する OVS-DPDK パラメーターの最適値を決定する方法を確認してください。

5.4. SR-IOV および DPDK インターフェース用のコンピュートノードの設定

以下の例では、SR-IOV および DPDK インターフェースに対応する compute.yaml ファイルのサンプルを使用しています。

  1. 分離ネットワーク用のコントロールプレーンの Linux ボンディングを作成します。

      type: linux_bond
      name: bond_api
      bonding_options: "mode=active-backup"
      use_dhcp: false
      dns_servers: {get_param: DnsServers}
      members:
        -
          type: interface
          name: nic3
          primary: true
        -
          type: interface
          name: nic4
  2. この Linux ボンディングに VLAN を割り当てます。

      -
        type: vlan
        vlan_id: {get_param: InternalApiNetworkVlanID}
        device: bond_api
        addresses:
          -
            ip_netmask: {get_param: InternalApiIpSubnet}
      -
        type: vlan
        vlan_id: {get_param: StorageNetworkVlanID}
        device: bond_api
        addresses:
          -
            ip_netmask: {get_param: StorageIpSubnet}
  3. DPDK ポートを持つブリッジを設定し、コントローラーにリンクします。

      type: ovs_user_bridge
      name: br-link0
      ovs_extra:
        -
          str_replace:
            template: set port br-link0 tag=_VLAN_TAG_
            params:
              _VLAN_TAG_: {get_param: TenantNetworkVlanID}
      addresses:
        -
          ip_netmask: {get_param: TenantIpSubnet}
      use_dhcp: false
      members:
        -
          type: ovs_dpdk_port
          name: dpdk0
          mtu: 9000
          ovs_extra:
          - set interface $DEVICE mtu_request=$MTU
          - set interface $DEVICE optoins:n_rxq=2
          members:
            -
              type: interface
              name: nic7
              primary: true
    注記

    複数の DPDK デバイスを含めるには、追加する DPDK デバイスごとに type のコードセクションを繰り返します。

    注記

    OVS-DPDK を使用する場合には、同じコンピュートノード上の ブリッジが ovs_user_bridge の種別である必要があります。同じノード上で ovs_bridgeovs_user_bridge が混在する構成は、director では受け入れ可能ですが、Red Hat OpenStack Platform ではサポートされていません。

  4. コントローラーに SR-IOV インターフェースを作成します。

      - type: interface
        name: p7p2
        mtu: 9000
        use_dhcp: false
        defroute: false
        nm_controlled: true
        hotplug: true

5.5. オーバークラウドのデプロイ

OVS-DPDK と SR-IOV の両方をデプロイする overcloud_deploy.sh bash スクリプトの例を以下に示します。

#!/bin/bash

openstack overcloud deploy \
--templates \
-e /usr/share/openstack-tripleo-heat-templates/environments/network-isolation.yaml \
-e /usr/share/openstack-tripleo-heat-templates/environments/neutron-ovs-dpdk.yaml \
-e /usr/share/openstack-tripleo-heat-templates/environments/neutron-sriov.yaml \
-e /home/stack/ospd-10-vxlan-vlan-dpdk-sriov-ctlplane-bonding/network-environment.yaml

5.6. フレーバーの作成ならびに SR-IOV および DPDK インターフェースに対応したインスタンスのデプロイ

デプロイが正常に完了したオーバークラウドで、インスタンスのデプロイを開始することができます。source コマンドで /home/stack ディレクトリーに新たに作成した overcloudrc ファイルを読み込むことから始めます。続いて、フレーバーを作成してインスタンスをデプロイします。

  1. フレーバーを作成します。

    # source overcloudrc
    # openstack flavor create --vcpus 6 --ram 4096 --disk 40 compute

    それぞれのオプション引数についての説明は以下のとおりです。

    • compute: フレーバー名
    • 4096: メモリーの容量 (MB 単位)
    • 40: GB 単位のディスク容量 (デフォルトは 0)
    • 6: 仮想 CPU の数
  2. ラージページのフレーバーを設定します。

    # openstack flavor set compute --property hw:mem_page_size=1GB
  3. 外部ネットワークを作成します。

    # openstack network create --share --external \
    --provider-physical-network <net-mgmt-physnet> \
    --provider-network-type <flat|vlan> external
  4. SR-IOV および DPDK 用のネットワークを作成します。

    # openstack network create net-dpdk
    # openstack network create net-sriov
    # openstack subnet create --subnet-range <cidr/prefix> --network net-dpdk  net-dpdk-subnet
    # openstack subnet create --subnet-range <cidr/prefix> --network net-sriov  net-sriov-subnet
  5. SR-IOV ポートを作成します。

    1. SR-IOV VF ポートを作成するには、vnic-typedirect を使用します。

      # openstack port create --network net-sriov --vnic-type direct sriov_port
    2. SR-IOV PF ポートを作成するには、vnic-typedirect-physical を使用します。

      # openstack port create --network net-sriov --vnic-type direct-physical sriov_port
  6. ルーターを作成し、DPDK VXLAN ネットワークに接続します。

    # openstack router create router1
    # openstack router add subnet router1 net-dpdk-subnet
  7. Floating IP アドレスを作成し、それをゲストインスタンスのポートに関連付けます。

    # openstack floating ip create --floating-ip-address FLOATING-IP external
  8. インスタンスをデプロイします。

    # openstack server create --flavor compute --image rhel_7.3 --nic port-id=sriov_port --nic net-id=NET_DPDK_ID vm1

それぞれのオプション引数についての説明は以下のとおりです。

  • compute: フレーバーの名前または ID
  • rhel_7.3: インスタンスの作成に使用されるイメージ (名前または ID)
  • sriov_port: 前のステップで作成したポートの名前
  • NET_DPDK_ID: DPDK のネットワーク ID
  • vm1: インスタンス名

これで、同じコンピュートノード上の SR-IOV インターフェース および DPDK インターフェースを使用するインスタンスがデプロイされました。

注記

より多くのインターフェースを使用するインスタンスの場合は、cloud-init を使用することができます。詳しくは、「インスタンスの作成」の表 3.1 を参照してください。