Red Hat Training
A Red Hat training course is available for Red Hat OpenStack Platform
第4章 仮想ネットワーク向けの OVS-DPDK サポートの設定
本章では、コンポーザブルロールを使用して、DPDK (OVS-DPDK) を Open vSwitch とともに Red Hat OpenStack Platform 環境内にデプロイします。オーバークラウドは、通常コントローラーノードやコンピュートノードなどの事前定義済みロールのノードと、異なる種別のストレージノードで構成されます。これらのデフォルトロールにはそれぞれ、director ノード上のコア Heat テンプレートコレクションで定義されている一式のサービスが含まれます。
Red Hat OpenStack Platform 11 では、コンポーザブルロール機能を使用し、各ロールからサービスを追加/削除してカスタムのデプロイメントロールを作成できます。コンポーザブルロールの詳しい情報は「コンポーザブルサービスとカスタムロール」を参照してください。
OVS-DPDK の設定は、以下の作業で構成されます。
-
コンポーザブルロールを使用する場合には、
roles-data.yam
ファイルをコピーして編集し、OVS-DPDK 用のコンポーザブルロールを追加します。 -
適切な
network-environment.yaml
ファイルを更新して、カーネル引数と DPDK 引数のパラメーターを追加します。 -
compute.yaml
ファイルを更新して、DPDK インターフェース用のブリッジを追加します。 -
controller.yaml
ファイルを更新して、DPDK インターフェースパラメーター用の同じブリッジ情報を追加します。 -
overcloud_deploy.sh
スクリプトを実行して、DPDK パラメーターを使用してオーバークラウドをデプロイします。
手順を開始する前に、以下の項目が揃っていることを確認します。
- Red Hat Enterprise Linux 7.3 をベースとした Red Hat OpenStack Platform 11
- OVS-DPDK 2.6
- NIC: Dual port Intel x520
OVS-DPDK は Red Hat Enterprise Linux に依存しており、Red Hat Enterprise Linux 7.3 では OVS バージョン 2.6.* が必要です。
4.1. OVS-DPDK の設定パラメーターについての理解
本項では、OVS-DPDK 向けの OpenStack ネットワークを最適化するために network-environment.yaml ファイルで設定する一般的な OVS-DPDK パラメーターについて説明します。
- NeutronDpdkMemoryChannels: メモリーチャンネルを CPU にマッピングします。
- NeutronDpdkCoreList: DPDK PMD に使用される CPU コアを指定します。
- NeutronDpdkSocketMemory: NUMA ノードごとに、ヒュージページプールから事前に割り当てられるメモリー容量を指定します。たとえば、DPDK Poll Mode Driver (PMD) (NeutronDpdkCoreList) が 2 つの NUMA ノードを使用する場合には、NeutronDpdkSocketMemory の設定は 1024,1024 となります。
- NovaReservedHostMemory: ホスト上のタスク用のメモリーを確保します (例: 4096)。
- NovaVcpuPinSet: CPU ピニングのコアを設定します。このコアの範囲は、NeutronDpdkCoreList コアとは重複しないようにする必要があります。
- hugepagesz: CPU 上のヒュージページのサイズ。この値は、CPU ハードウェアによって異なる場合があります。
- hugepages count: 利用可能なヒュージページの数。この値は、ホストのメモリーの空き容量によって異なります。コンピュートノードに関連付けられている OpenStack フレーバー内のヒュージページ数の値を設定する必要もあります。
- Tuned CPU partitioning プロファイル: DPDK のパフォーマンスを設定するために適切な tuned プロファイルを設定します。
4.2. VLAN トンネリングを使用した単一ポートの OVS-DPDK の設定
本項では、OpenStack 環境で、単一のデータプレーンポートと 2 つのコントロールプレーンポート (1 つの Linux ボンディング) を使用する OVS-DPDK を設定およびデプロイする手順について説明します。
4.2.1. first-boot.yaml の編集
first-boot.yaml
ファイルを編集して、OVS と DPDK のパラメーターを設定し、tuned
を CPU アフィニティー向けに構成します。
追加のリソースを加えます。
resources: userdata: type: OS::Heat::MultipartMime properties: parts: - config: {get_resource: boot_config} - config: {get_resource: set_ovs_socket_config} - config: {get_resource: set_ovs_config} - config: {get_resource: set_dpdk_params} - config: {get_resource: install_tuned} - config: {get_resource: compute_kernel_args}
NeutronVhostUserSocketDir
の設定を決定します。set_ovs_socket_config: 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 mkdir -p $NEUTRON_VHOSTUSER_SOCKET_DIR chown -R qemu:qemu $NEUTRON_VHOSTUSER_SOCKET_DIR restorecon $NEUTRON_VHOSTUSER_SOCKET_DIR fi params: $COMPUTE_HOSTNAME_FORMAT: {get_param: ComputeHostnameFormat} $NEUTRON_VHOSTUSER_SOCKET_DIR: {get_param: NeutronVhostuserSocketDir}
OVS の構成を設定します。
set_ovs_config: 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 if [ -f /usr/lib/systemd/system/openvswitch-nonetwork.service ]; then ovs_service_path="/usr/lib/systemd/system/openvswitch-nonetwork.service" elif [ -f /usr/lib/systemd/system/ovs-vswitchd.service ]; then ovs_service_path="/usr/lib/systemd/system/ovs-vswitchd.service" fi 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 fi params: $COMPUTE_HOSTNAME_FORMAT: {get_param: ComputeHostnameFormat}
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)) 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 pmd_cpu_mask=$( get_mask $PMD_CORES ) host_cpu_mask=$( get_mask $TUNED_CORES ) 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_MEMORY 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} $TUNED_CORES: {get_param: HostCpusList} $PMD_CORES: {get_param: NeutronDpdkCoreList} $SOCKET_MEMORY: {get_param: NeutronDpdkSocketMemory}
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: HostCpusList}
カーネル引数を設定します。
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"/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}
4.2.2. post-install.yaml の編集
tuned
の設定で CPU アフィニティーを指定するように設定します。ExtraConfig: type: OS::Heat::SoftwareConfig properties: group: script config: str_replace: template: | #!/bin/bash set -x 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 tuned_service=/usr/lib/systemd/system/tuned.service grep -q "network.target" $tuned_service if [ "$?" -eq 0 ]; then sed -i '/After=.*/s/network.target//g' $tuned_service fi grep -q "Before=.*network.target" $tuned_service if [ ! "$?" -eq 0 ]; then grep -q "Before=.*" $tuned_service if [ "$?" -eq 0 ]; then sed -i 's/^\(Before=.*\)/\1 network.target openvswitch.service/g' $tuned_service else sed -i '/After/i Before=network.target openvswitch.service' $tuned_service fi fi systemctl daemon-reload fi params: $COMPUTE_HOSTNAME_FORMAT: {get_param: ComputeHostnameFormat}
4.2.3. network-environment.yaml の編集
resource_registry
の下に OVS-DPDK 用のカスタムリソースを追加します。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-ovs-dpdk.yaml OS::TripleO::Controller::Net::SoftwareConfig: nic-configs/controller.yaml OS::TripleO::NodeUserData: first-boot.yaml OS::TripleO::NodeExtraConfigPost: post-install.yaml
parameter_defaults
の下でトンネルの種別を無効にして (値を""
に設定)、ネットワーク種別をvlan
に設定します。NeutronTunnelTypes: "" NeutronNetworkType: 'vlan'
parameter_defaults
の下で、物理ネットワークを仮想ブリッジにマッピングします。NeutronBridgeMappings: 'dpdk_data:br-link0'
parameter_defaults
の下で、OpenStack Networking ML2 および Open vSwitch VLAN のマッピング範囲を指定します。NeutronNetworkVLANRanges: 'dpdk_data:22:22'
この例では、物理ネットワーク (
dpdk_data
) 上の VLAN 範囲を設定しています。parameter_defaults
の下で、OVS-DPDK の設定パラメーターを指定します。注記NeutronDPDKCoreList
およびNeutronDPDKMemoryChannels
はこの手順では 必須 の設定です。適切な値を指定せずに DPDK のデプロイを試みると、デプロイメントが失敗するか、不安定なデプロイメントとなってしまいます。[allowed_pattern: "'[0-9,-]+'"]
の形式で DPDK Poll Mode Driver (PMD) として使用可能なコアの一覧を指定します。NeutronDpdkCoreList: "'4,6,20,22'"
OVS-DPDK のパフォーマンスを最適化するには、以下のオプションを検討してください。
-
DPDK インターフェースの NUMA ノードに関連付けられた CPU を選択します。
cat /sys/class/net/<interface>/device/numa_node
を使用してインターフェースに関連付けられた NUMA ノードをリストし、lscpu
を使用してその NUMA ノードに関連付けられた CPU をリストします。 -
CPU のシブリングをグループにまとめます (ハイパースレッディングの場合)。CPU のシブリングを特定するには、
cat /sys/devices/system/cpu/<cpu>/topology/thread_siblings_list
コマンドを実行します。 - CPU 0 はホストのプロセス用に確保します。
- PMD に割り当てられた CPU を分離して、ホストのプロセスがそれらの CPU を使用しないようにします。
-
NovaVcpuPinset
を使用して、PDM に割り当てられている CPU を Compute のスケジューリングから除外します。
-
DPDK インターフェースの NUMA ノードに関連付けられた CPU を選択します。
[allowed_pattern: "[0-9]+"]
の形式でメモリーチャネル数を指定します。NeutronDpdkMemoryChannels: "4"
各ソケットに対してヒュージページプールから事前割り当てされるメモリーを設定します。
NeutronDpdkSocketMemory: "'2048,2048'"
これは、CPU ソケットを昇順で指定するコンマ区切りの文字列です。この例では、 2 NUMA ノード構成を前提としており、ヒュージページからソケット 0 に 2048 MB 、ソケット 1 に 2048 MB を事前に割り当てるように設定しています。単一 NUMA ノード構成のシステムの場合には、この値を 1024,0 に設定してください。
OVS ブリッジの DPDK ドライバーの種別とデータパスの種別を設定します。
NeutronDpdkDriverType: "vfio-pci" NeutronDatapathType: "netdev"
parameter_defaults
の下で、OVS 用の vhost-user ソケットディレクトリーを指定します。NeutronVhostuserSocketDir: "/var/lib/vhost_sockets"
parameter_defaults
の下で、ホストのプロセス用のメモリーを確保します。NovaReservedHostMemory: "2048"
parameter_defaults
の下で、仮想マシンのプロセス用に確保する物理 CPU コアのコンマ区切りリストまたは範囲を指定します。NovaVcpuPinSet: "8,10,12,14,18,24,26,28,30"
parameter_defaults
の下で、最も制約の多いフィルターからリストして、ノードのフィルタリングプロセスをさらに効率化します。コンピュートは、フィルターの配列を使用してノードをフィルタリングします。これらのフィルターは、リスト順に適用されます。
NovaSchedulerDefaultFilters: "RamFilter,ComputeFilter,AvailabilityZoneFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,PciPassthroughFilter,NUMATopologyFilter"
parameter_defaults
の下で、ComputeKernelArgs
パラメーターを追加して、初期ブート時にそれらのパラメーターがデフォルトのgrub
ファイルに追加されるようにします。ComputeKernelArgs: "default_hugepagesz=1GB hugepagesz=1G hugepages=32 iommu=pt intel_iommu=on"
注記これらのヒュージページは、仮想マシンにより消費されます。また、本手順に記載の
NeutronDpdkSocketMemory
パラメーターを使用すると OVS-DPDK により消費されます。仮想マシンが利用可能なヒュージページは、boot
パラメーターからNeutronDpdkSocketMemory
を減算した値です。DPDK に関連付けられたフレーバーに
hw:mem_page_size=1GB
を追加する必要があります。追加しなかった場合には、そのインスタンスは DHCP から割り当てを受けなくなります。parameter_defaults
の下に、チューニングする物理 CPU コアの一覧または範囲を指定します。指定の引数は、tuned
cpu-partitioning
プロファイルに追加されます。HostIsolatedCpusList: "'2,4,6,8,10,12,14,18,20,22,24,26,28,30'"
parameter_defaults
の下で、 OVS-DPDK プロセスが dpdk-lcore-mask に使用する論理コアの一覧を設定します。これらのコアは、NeutronDpdkCoreList
およびNovaVcpuPinSet
のコアリストとは相互に排他的である必要があります。HostCpusList: "'0,1,2,3,5,17,18,19,21'"
4.2.4. controller.yaml の編集
分離ネットワーク用にコントロールプレーンの Linux ボンディングを作成します。
- type: linux_bond name: bond_api members: - type: interface name: nic3 - type: interface name: nic4
この Linux ボンディングに VLAN を割り当てます。
- type: vlan vlan_id: {get_param: InternalApiNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: InternalApiIpSubnet} - type: vlan vlan_id: {get_param: TenantNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: TenantIpSubnet} - type: vlan vlan_id: {get_param: StorageNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: StorageIpSubnet} - type: vlan vlan_id: {get_param: StorageMgmtNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: StorageMgmtIpSubnet} - type: vlan vlan_id: {get_param: ExternalNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: ExternalIpSubnet} routes: - default: true next_hop: {get_param: ExternalInterfaceDefaultRoute} -
Compute ノードに接続する OVS ブリッジを作成します。
- type: ovs_bridge name: br-link0 use_dhcp: false dns_servers: {get_param: DnsServers} members: - type: interface name: nic5
4.2.5. compute.yaml の編集
分離ネットワーク用にコントロールプレーンの Linux ボンディングを作成します。
- type: linux_bond name: bond_api members: - type: interface name: nic3 - type: interface name: nic4
この Linux ボンディングに VLAN を割り当てます。
- type: vlan vlan_id: {get_param: InternalApiNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: InternalApiIpSubnet} - type: vlan vlan_id: {get_param: TenantNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: TenantIpSubnet} - type: vlan vlan_id: {get_param: StorageNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: StorageIpSubnet} -
コントローラーにリンクするための DPDK ポートを使用したブリッジを設定します。
- type: ovs_user_bridge name: br-link0 use_dhcp: false dns_servers: {get_param: DnsServers} members: - type: ovs_dpdk_port name: dpdk0 members: - type: interface name: nic5
注記複数の DPDK デバイスが含まれるようにするには、追加する各 DPDK デバイスごどに
type
コードスニペットを繰り返してください。注記OVS-DPDK を使用する場合には、すべての コンピュートノードのブリッジが
ovs_user_bridge
の種別である必要があります。director は設定を受け入れることができますが、Red Hat OpenStack Platform はovs_bridge
とovs_user_bridge
の混在する構成はサポートしていません。
4.2.6. overcloud_deploy.sh スクリプトの実行
以下の例では、Bash スクリプト内で、OVS-DPDK 環境向けの openstack overcloud deploy
コマンドを定義しています。
#!/bin/bash openstack overcloud deploy --templates \ -e /usr/share/openstack-tripleo-heat-templates/environments/neutron-ovs-dpdk.yaml \ -e /home/stack/ospd-11-vlan-dpdk-single-port-ctlplane-bonding/network-environment.yaml
ここで
-
/usr/share/openstack-tripleo-heat-templates/environments/neutron-ovs-dpdk.yaml
は、Compute ロールの OVS-DPDK パラメーターを有効にするデフォルトのneutron-ovs-dpdk.yaml
ファイルの場所です。 -
/home/stack/<relative-directory>/network-environment.yaml
は、network-environment.yaml
ファイルのパスです。このファイルを使用して、neutron-ovs-dpdk.yaml
ファイルからのデフォルト値を上書きします。
OVS-DPDK はセキュリティーグループおよびライブマイグレーションはサポートしていません。
4.3. VLAN トンネリングを使用した 2 ポートの OVS-DPDK の設定
本項では、OpenStack 環境にコントロールプレーンの Linux ボンディングを使用する 2 データプレーンポートの OVS-DPDK を設定およびデプロイする手順について説明します。
4.3.1. first-boot.yaml の編集
first-boot.yaml
ファイルを編集して、OVS と DPDK のパラメーターを設定し、tuned
を CPU アフィニティー向けに構成します。
追加のリソースを加えます。
resources: userdata: type: OS::Heat::MultipartMime properties: parts: - config: {get_resource: boot_config} - config: {get_resource: set_ovs_socket_config} - config: {get_resource: set_ovs_config} - config: {get_resource: set_dpdk_params} - config: {get_resource: install_tuned} - config: {get_resource: compute_kernel_args}
NeutronVhostUserSocketDir
の設定を決定します。set_ovs_socket_config: 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 mkdir -p $NEUTRON_VHOSTUSER_SOCKET_DIR chown -R qemu:qemu $NEUTRON_VHOSTUSER_SOCKET_DIR restorecon $NEUTRON_VHOSTUSER_SOCKET_DIR fi params: $COMPUTE_HOSTNAME_FORMAT: {get_param: ComputeHostnameFormat} $NEUTRON_VHOSTUSER_SOCKET_DIR: {get_param: NeutronVhostuserSocketDir}
OVS の構成を設定します。
set_ovs_config: 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 if [ -f /usr/lib/systemd/system/openvswitch-nonetwork.service ]; then ovs_service_path="/usr/lib/systemd/system/openvswitch-nonetwork.service" elif [ -f /usr/lib/systemd/system/ovs-vswitchd.service ]; then ovs_service_path="/usr/lib/systemd/system/ovs-vswitchd.service" fi 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 fi params: $COMPUTE_HOSTNAME_FORMAT: {get_param: ComputeHostnameFormat}
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)) 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 pmd_cpu_mask=$( get_mask $PMD_CORES ) host_cpu_mask=$( get_mask $TUNED_CORES ) 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_MEMORY 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} $TUNED_CORES: {get_param: HostCpusList} $PMD_CORES: {get_param: NeutronDpdkCoreList} $SOCKET_MEMORY: {get_param: NeutronDpdkSocketMemory}
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: HostCpusList}
カーネル引数を設定します。
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"/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}
4.3.2. post-install.yaml の編集
tuned
の設定で CPU アフィニティーを指定するように設定します。ExtraConfig: type: OS::Heat::SoftwareConfig properties: group: script config: str_replace: template: | #!/bin/bash set -x 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 tuned_service=/usr/lib/systemd/system/tuned.service grep -q "network.target" $tuned_service if [ "$?" -eq 0 ]; then sed -i '/After=.*/s/network.target//g' $tuned_service fi grep -q "Before=.*network.target" $tuned_service if [ ! "$?" -eq 0 ]; then grep -q "Before=.*" $tuned_service if [ "$?" -eq 0 ]; then sed -i 's/^\(Before=.*\)/\1 network.target openvswitch.service/g' $tuned_service else sed -i '/After/i Before=network.target openvswitch.service' $tuned_service fi fi systemctl daemon-reload fi params: $COMPUTE_HOSTNAME_FORMAT: {get_param: ComputeHostnameFormat}
4.3.3. network-environment.yaml の編集
resource_registry
の下に OVS-DPDK 用のカスタムリソースを追加します。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 OS::TripleO::NodeExtraConfigPost: post-install.yaml
parameter_defaults
の下でトンネルの種別を無効にして (値を""
に設定)、ネットワーク種別をvlan
に設定します。NeutronTunnelTypes: "" NeutronNetworkType: 'vlan'
parameter_defaults
の下で、物理ネットワークを仮想ブリッジにマッピングします。NeutronBridgeMappings: 'dpdk_mgmt:br-link0,dpdk_data:br-link1'
parameter_defaults
の下で、OpenStack Networking ML2 および Open vSwitch VLAN のマッピング範囲を指定します。NeutronNetworkVLANRanges: 'dpdk_mgmt:22:22,dpdk_data:25:28'
parameter_defaults
の下で、OVS-DPDK の設定パラメーターを指定します。注記NeutronDPDKCoreList
およびNeutronDPDKMemoryChannels
はこの手順では 必須 の設定です。適切な値を指定せずに DPDK のデプロイを試みると、デプロイメントが失敗するか、不安定なデプロイメントとなってしまいます。[allowed_pattern: "'[0-9,-]+'"]
の形式で DPDK Poll Mode Driver (PMD) として使用可能なコアの一覧を指定します。NeutronDpdkCoreList: "'4,6,20,22'"
OVS-DPDK のパフォーマンスを最適化するには、以下のオプションを検討してください。
-
DPDK インターフェースの NUMA ノードに関連付けられた CPU を選択します。
cat /sys/class/net/<interface>/device/numa_node
を使用してインターフェースに関連付けられた NUMA ノードをリストし、lscpu
を使用してその NUMA ノードに関連付けられた CPU をリストします。 -
CPU のシブリングをグループにまとめます (ハイパースレッディングの場合)。CPU のシブリングを特定するには、
cat /sys/devices/system/cpu/<cpu>/topology/thread_siblings_list
コマンドを実行します。 - CPU 0 はホストのプロセス用に確保します。
- PMD に割り当てられた CPU を分離して、ホストのプロセスがそれらの CPU を使用しないようにします。
-
NovaVcpuPinset
を使用して、PDM に割り当てられている CPU を Compute のスケジューリングから除外します。
-
DPDK インターフェースの NUMA ノードに関連付けられた CPU を選択します。
[allowed_pattern: "[0-9]+"]
の形式でメモリーチャネル数を指定します。NeutronDpdkMemoryChannels: "4"
各ソケットに対してヒュージページプールから事前割り当てされるメモリーを設定します。
NeutronDpdkSocketMemory: "2048,2048"
これは、CPU ソケットを昇順で指定するコンマ区切りの文字列です。この例では、 2 NUMA ノード構成を前提としており、ヒュージページからソケット 0 に 2048 MB 、ソケット 1 に 2048 MB を事前に割り当てるように設定しています。単一 NUMA ノード構成のシステムの場合には、この値を 1024,0 に設定してください。
OVS ブリッジの DPDK ドライバーの種別とデータパスの種別を設定します。
NeutronDpdkDriverType: "vfio-pci" NeutronDatapathType: "netdev"
parameter_defaults
の下で、OVS 用の vhost-user ソケットディレクトリーを指定します。NeutronVhostuserSocketDir: "/var/lib/vhost_sockets"
parameter_defaults
の下で、ホストのプロセス用のメモリーを確保します。NovaReservedHostMemory: "2048"
parameter_defaults
の下で、仮想マシンのプロセス用に確保する物理 CPU コアのコンマ区切りリストまたは範囲を指定します。NovaVcpuPinSet: "8,10,12,14,18,24,26,28,30"
parameter_defaults
の下で、最も制約の多いフィルターからリストして、ノードのフィルタリングプロセスをさらに効率化します。コンピュートは、フィルターの配列を使用してノードをフィルタリングします。これらのフィルターは、リスト順に適用されます。
NovaSchedulerDefaultFilters: "RamFilter,ComputeFilter,AvailabilityZoneFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,PciPassthroughFilter,NUMATopologyFilter"
parameter_defaults
の下で、ComputeKernelArgs
パラメーターを追加して、初期ブート時にそれらのパラメーターがデフォルトのgrub
ファイルに追加されるようにします。ComputeKernelArgs: "default_hugepagesz=1GB hugepagesz=1G hugepages=32 iommu=pt intel_iommu=on"
注記これらのヒュージページは、仮想マシンにより消費されます。また、本手順に記載の
NeutronDpdkSocketMemory
パラメーターを使用すると OVS-DPDK により消費されます。仮想マシンが利用可能なヒュージページは、boot
パラメーターからNeutronDpdkSocketMemory
を減算した値です。DPDK に関連付けられたフレーバーに
hw:mem_page_size=1GB
を追加する必要があります。追加しなかった場合には、そのインスタンスは DHCP から割り当てを受けなくなります。parameter_defaults
の下に、チューニングする物理 CPU コアの一覧または範囲を指定します。指定の引数は、tuned
cpu-partitioning
プロファイルに追加されます。HostIsolatedCpusList: "'2,4,6,8,10,12,14,18,20,22,24,26,28,30'"
parameter_defaults
の下で、 OVS-DPDK プロセスが dpdk-lcore-mask に使用する論理コアの一覧を設定します。これらのコアは、NeutronDpdkCoreList
およびNovaVcpuPinSet
のコアリストとは相互に排他的である必要があります。HostCpusList: "'0,1,2,3,5,17,18,19,21'"
4.3.4. controller.yaml の編集
分離ネットワーク用にコントロールプレーンの Linux ボンディングを作成します。
- type: linux_bond name: bond_api members: - type: interface name: nic3 - type: interface name: nic4 -
この Linux ボンディングに VLAN を割り当てます。
- type: vlan vlan_id: {get_param: InternalApiNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: InternalApiIpSubnet} - type: vlan vlan_id: {get_param: TenantNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: TenantIpSubnet} - type: vlan vlan_id: {get_param: StorageNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: StorageIpSubnet} - type: vlan vlan_id: {get_param: StorageMgmtNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: StorageMgmtIpSubnet} - type: vlan vlan_id: {get_param: ExternalNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: ExternalIpSubnet} routes: - default: true next_hop: {get_param: ExternalInterfaceDefaultRoute} -
コンピュートノードへの OVS ブリッジを 2 つ作成します。
- type: ovs_bridge name: br-link0 use_dhcp: false dns_servers: {get_param: DnsServers} members: - type: interface name: nic5 - type: ovs_bridge name: br-link1 use_dhcp: false dns_servers: {get_param: DnsServers} members: - type: interface name: nic6
4.3.5. compute.yaml の編集
分離ネットワーク用にコントロールプレーンの Linux ボンディングを作成します。
- type: linux_bond name: bond_api members: - type: interface name: nic3 - type: interface name: nic4
この Linux ボンディングに VLAN を割り当てます。
- type: vlan vlan_id: {get_param: InternalApiNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: InternalApiIpSubnet} - type: vlan vlan_id: {get_param: TenantNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: TenantIpSubnet} - type: vlan vlan_id: {get_param: StorageNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: StorageIpSubnet} -
コントローラーにリンクするための DPDK ポートを 1 つずつ使用した ブリッジを 2 つ設定します。
- type: ovs_user_bridge name: br-link0 use_dhcp: false dns_servers: {get_param: DnsServers} members: - type: ovs_dpdk_port name: dpdk0 members: - type: interface name: nic5 - type: ovs_user_bridge name: br-link1 use_dhcp: false dns_servers: {get_param: DnsServers} members: - type: ovs_dpdk_port name: dpdk1 members: - type: interface name: nic6
注記複数の DPDK デバイスが含まれるようにするには、追加する各 DPDK デバイスごどに
type
コードスニペットを繰り返してください。注記OVS-DPDK を使用する場合には、すべての コンピュートノードのブリッジが
ovs_user_bridge
の種別である必要があります。director は設定を受け入れることができますが、Red Hat OpenStack Platform はovs_bridge
とovs_user_bridge
の混在する構成はサポートしていません。
4.3.6. overcloud_deploy.sh スクリプトを実行します。
以下の例では、Bash スクリプト内で、OVS-DPDK 環境向けの openstack overcloud deploy
コマンドを定義しています。
#!/bin/bash openstack overcloud deploy --templates \ -e /usr/share/openstack-tripleo-heat-templates/environments/neutron-ovs-dpdk.yaml \ -e /home/stack/ospd-11-vlan-ovs-dpdk-bonding-dataplane-bonding-ctlplane/network-environment.yaml
ここで
-
/usr/share/openstack-tripleo-heat-templates/environments/neutron-ovs-dpdk.yaml
は、Compute ロールの OVS-DPDK パラメーターを有効にするデフォルトのneutron-ovs-dpdk.yaml
ファイルの場所です。 -
/home/stack/<relative-directory>/network-environment.yaml
は、network-environment.yaml
ファイルのパスです。このファイルを使用して、neutron-ovs-dpdk.yaml
ファイルからのデフォルト値を上書きします。
OVS-DPDK はセキュリティーグループおよびライブマイグレーションはサポートしていません。
4.4. VLAN トンネリングを使用した 2 ポートの OVS-DPDK データプレーンボンディングの設定
本項では、OpenStack 環境で、1 つの OVS-DPDK ボンディングが 2 つのデータポートで構成される OVS-DPDK を設定およびデプロイする手順について説明します。このユースケースでは、コントロールプレーンに Linux ボンディングも使用します。
4.4.1. first-boot.yaml の編集
first-boot.yaml
ファイルを編集して、OVS と DPDK のパラメーターを設定し、tuned
を CPU アフィニティー向けに構成します。
追加のリソースを加えます。
resources: userdata: type: OS::Heat::MultipartMime properties: parts: - config: {get_resource: boot_config} - config: {get_resource: set_ovs_socket_config} - config: {get_resource: set_ovs_config} - config: {get_resource: set_dpdk_params} - config: {get_resource: install_tuned} - config: {get_resource: compute_kernel_args}
NeutronVhostUserSocketDir
の設定を決定します。set_ovs_socket_config: 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 mkdir -p $NEUTRON_VHOSTUSER_SOCKET_DIR chown -R qemu:qemu $NEUTRON_VHOSTUSER_SOCKET_DIR restorecon $NEUTRON_VHOSTUSER_SOCKET_DIR fi params: $COMPUTE_HOSTNAME_FORMAT: {get_param: ComputeHostnameFormat} $NEUTRON_VHOSTUSER_SOCKET_DIR: {get_param: NeutronVhostuserSocketDir}
OVS の構成を設定します。
set_ovs_config: 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 if [ -f /usr/lib/systemd/system/openvswitch-nonetwork.service ]; then ovs_service_path="/usr/lib/systemd/system/openvswitch-nonetwork.service" elif [ -f /usr/lib/systemd/system/ovs-vswitchd.service ]; then ovs_service_path="/usr/lib/systemd/system/ovs-vswitchd.service" fi 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 fi params: $COMPUTE_HOSTNAME_FORMAT: {get_param: ComputeHostnameFormat}
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)) 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 pmd_cpu_mask=$( get_mask $PMD_CORES ) host_cpu_mask=$( get_mask $TUNED_CORES ) 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_MEMORY 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} $TUNED_CORES: {get_param: HostCpusList} $PMD_CORES: {get_param: NeutronDpdkCoreList} $SOCKET_MEMORY: {get_param: NeutronDpdkSocketMemory}
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: HostCpusList}
カーネル引数を設定します。
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"/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}
4.4.2. post-install.yaml の編集
tuned
の設定で CPU アフィニティーを指定するように設定します。ExtraConfig: type: OS::Heat::SoftwareConfig properties: group: script config: str_replace: template: | #!/bin/bash set -x 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 tuned_service=/usr/lib/systemd/system/tuned.service grep -q "network.target" $tuned_service if [ "$?" -eq 0 ]; then sed -i '/After=.*/s/network.target//g' $tuned_service fi grep -q "Before=.*network.target" $tuned_service if [ ! "$?" -eq 0 ]; then grep -q "Before=.*" $tuned_service if [ "$?" -eq 0 ]; then sed -i 's/^\(Before=.*\)/\1 network.target openvswitch.service/g' $tuned_service else sed -i '/After/i Before=network.target openvswitch.service' $tuned_service fi fi systemctl daemon-reload fi params: $COMPUTE_HOSTNAME_FORMAT: {get_param: ComputeHostnameFormat}
4.4.3. network-environment.yaml の編集
resource_registry
の下に OVS-DPDK 用のカスタムリソースを追加します。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-ovs-dpdk.yaml OS::TripleO::Controller::Net::SoftwareConfig: nic-configs/controller.yaml OS::TripleO::NodeUserData: first-boot.yaml OS::TripleO::NodeExtraConfigPost: post-install.yaml
parameter_defaults
の下でトンネルの種別を無効にして (値を""
に設定)、ネットワーク種別をvlan
に設定します。NeutronTunnelTypes: "" NeutronNetworkType: 'vlan'
parameter_defaults
の下で、物理ネットワークを仮想ブリッジにマッピングします。NeutronBridgeMappings: 'dpdk_mgmt:br-link'
parameter_defaults
の下で、OpenStack Networking ML2 および Open vSwitch VLAN のマッピング範囲を指定します。NeutronNetworkVLANRanges: 'dpdk_mgmt:22:22'
この例では、物理ネットワーク (
dpdk_data
) 上の VLAN 範囲を設定しています。parameter_defaults
の下で、OVS-DPDK の設定パラメーターを指定します。注記NeutronDPDKCoreList
およびNeutronDPDKMemoryChannels
はこの手順では 必須 の設定です。適切な値を指定せずに DPDK のデプロイを試みると、デプロイメントが失敗するか、不安定なデプロイメントとなってしまいます。[allowed_pattern: "'[0-9,-]+'"]
の形式で DPDK Poll Mode Driver (PMD) として使用可能なコアの一覧を指定します。NeutronDpdkCoreList: "'4,6,20,22'"
OVS-DPDK のパフォーマンスを最適化するには、以下のオプションを検討してください。
-
DPDK インターフェースの NUMA ノードに関連付けられた CPU を選択します。
cat /sys/class/net/<interface>/device/numa_node
を使用してインターフェースに関連付けられた NUMA ノードをリストし、lscpu
を使用してその NUMA ノードに関連付けられた CPU をリストします。 -
CPU のシブリングをグループにまとめます (ハイパースレッディングの場合)。CPU のシブリングを特定するには、
cat /sys/devices/system/cpu/<cpu>/topology/thread_siblings_list
コマンドを実行します。 - CPU 0 はホストのプロセス用に確保します。
- PMD に割り当てられた CPU を分離して、ホストのプロセスがそれらの CPU を使用しないようにします。
-
NovaVcpuPinset
を使用して、PDM に割り当てられている CPU を Compute のスケジューリングから除外します。
-
DPDK インターフェースの NUMA ノードに関連付けられた CPU を選択します。
[allowed_pattern: "[0-9]+"]
の形式でメモリーチャネル数を指定します。NeutronDpdkMemoryChannels: "4"
各ソケットに対してヒュージページプールから事前割り当てされるメモリーを設定します。
NeutronDpdkSocketMemory: "'1024,1024'"
これは、CPU ソケットの昇順で指定するコンマ区切りの文字列です。この例では、 2 NUMA ノード構成を前提としており、ヒュージページからソケット 0 に 1024 MB、ソケット 1 に 1024 MB を事前に割り当てるように設定しています。単一 NUMA ノード構成のシステムの場合には、この値を 1024,0 に設定してください。
OVS ブリッジの DPDK ドライバーの種別とデータパスの種別を設定します。
NeutronDpdkDriverType: "vfio-pci" NeutronDatapathType: "netdev"
parameter_defaults
の下で、OVS 用の vhost-user ソケットディレクトリーを指定します。NeutronVhostuserSocketDir: "/var/lib/vhost_sockets"
parameter_defaults
の下で、ホストのプロセス用のメモリーを確保します。NovaReservedHostMemory: "2048"
parameter_defaults
の下で、仮想マシンのプロセス用に確保する物理 CPU コアのコンマ区切りリストまたは範囲を指定します。NovaVcpuPinSet: "8,10,12,14,18,24,26,28,30"
parameter_defaults
の下で、最も制約の多いフィルターからリストして、ノードのフィルタリングプロセスをさらに効率化します。コンピュートは、フィルターの配列を使用してノードをフィルタリングします。これらのフィルターは、リスト順に適用されます。
NovaSchedulerDefaultFilters: "RamFilter,ComputeFilter,AvailabilityZoneFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,PciPassthroughFilter,NUMATopologyFilter"
parameter_defaults
の下で、ComputeKernelArgs
パラメーターを追加して、初期ブート時にそれらのパラメーターがデフォルトのgrub
ファイルに追加されるようにします。ComputeKernelArgs: "default_hugepagesz=1GB hugepagesz=1G hugepages=32 iommu=pt intel_iommu=on"
注記これらのヒュージページは、仮想マシンにより消費されます。また、本手順に記載の
NeutronDpdkSocketMemory
パラメーターを使用すると OVS-DPDK により消費されます。仮想マシンが利用可能なヒュージページは、boot
パラメーターからNeutronDpdkSocketMemory
を減算した値です。DPDK に関連付けられたフレーバーに
hw:mem_page_size=1GB
を追加する必要があります。追加しなかった場合には、そのインスタンスは DHCP から割り当てを受けなくなります。parameter_defaults
の下に、チューニングする物理 CPU コアの一覧または範囲を指定します。指定の引数は、tuned
cpu-partitioning
プロファイルに追加されます。HostIsolatedCpusList: "'2,4,6,8,10,12,14,18,20,22,24,26,28,30'"
parameter_defaults
の下で、 OVS-DPDK プロセスが dpdk-lcore-mask に使用する論理コアの一覧を設定します。これらのコアは、NeutronDpdkCoreList
およびNovaVcpuPinSet
のコアリストとは相互に排他的である必要があります。HostCpusList: "'0,1,2,3,5,17,18,19,21'"
4.4.4. controller.yaml の編集
分離ネットワーク用にコントロールプレーンの Linux ボンディングを作成します。
- type: linux_bond name: bond1 bonding_options: "mode=active-backup" use_dhcp: false dns_servers: {get_param: DnsServers} addresses: - ip_netmask: list_join: - '/' - - {get_param: ControlPlaneIp} - {get_param: ControlPlaneSubnetCidr} routes: - ip_netmask: 169.254.169.254/32 next_hop: {get_param: EC2MetadataIp} - default: true next_hop: {get_param: ExternalInterfaceDefaultRoute} members: - type: interface name: nic2 primary: true - type: interface name: nic3 -
この Linux ボンディングに VLAN を割り当てます。
- type: vlan vlan_id: {get_param: InternalApiNetworkVlanID} device: bond1 addresses: - ip_netmask: {get_param: InternalApiIpSubnet} - type: vlan vlan_id: {get_param: ExternalNetworkVlanID} device: bond1 addresses: - ip_netmask: {get_param: ExternalIpSubnet} - type: vlan vlan_id: {get_param: TenantNetworkVlanID} device: bond1 addresses: - ip_netmask: {get_param: TenantIpSubnet} -
Compute ノードに接続する OVS ブリッジを作成します。
- type: ovs_bridge name: br-link use_dhcp: false members: - type: interface name: nic4
4.4.5. compute.yaml の編集
分離ネットワーク用にコントロールプレーンの 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 -
この Linux ボンディングに VLAN を割り当てます。
- type: vlan vlan_id: {get_param: InternalApiNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: InternalApiIpSubnet} - type: vlan vlan_id: {get_param: TenantNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: TenantIpSubnet} -
コントローラーにリンクする OVS-DPDK ボンディングに 2 つの DPDK ポートにブリッジを設定します。
- type: ovs_user_bridge name: br-link use_dhcp: false members: - type: ovs_dpdk_bond name: bond_dpdk0 members: - type: ovs_dpdk_port name: dpdk0 members: - type: interface name: nic5 - type: ovs_dpdk_port name: dpdk1 members: - type: interface name: nic6
注記複数の DPDK デバイスが含まれるようにするには、追加する各 DPDK デバイスごどに
type
コードスニペットを繰り返してください。注記OVS-DPDK を使用する場合には、すべての コンピュートノードのブリッジが
ovs_user_bridge
の種別である必要があります。director は設定を受け入れることができますが、Red Hat OpenStack Platform はovs_bridge
とovs_user_bridge
の混在する構成はサポートしていません。
4.4.6. overcloud_deploy.sh スクリプトを実行します。
以下の例では、Bash スクリプト内で、OVS-DPDK 環境向けの openstack overcloud deploy
コマンドを定義しています。
#!/bin/bash openstack overcloud deploy --templates \ -e /usr/share/openstack-tripleo-heat-templates/environments/neutron-ovs-dpdk.yaml \ -e /home/stack/ospd-11-vlan-ovs-dpdk-bonding-dataplane-bonding-ctlplane/network-environment.yaml
ここで
-
/usr/share/openstack-tripleo-heat-templates/environments/neutron-ovs-dpdk.yaml
は、Compute ロールの OVS-DPDK パラメーターを有効にするデフォルトのneutron-ovs-dpdk.yaml
ファイルの場所です。 -
/home/stack/<relative-directory>/network-environment.yaml
は、network-environment.yaml
ファイルのパスです。このファイルを使用して、neutron-ovs-dpdk.yaml
ファイルからのデフォルト値を上書きします。
OVS-DPDK はセキュリティーグループおよびライブマイグレーションはサポートしていません。
4.5. VXLAN トンネリングを使用した単一ポートの OVS-DPDK の設定
本項では、OpenStack 環境にコントロールプレーンの Linux ボンディングと VXLAN トンネリングを使用する単一データプレーンポートの OVS-DPDK を設定およびデプロイする手順について説明します。
4.5.1. first-boot.yaml の編集
first-boot.yaml
ファイルを編集して、OVS と DPDK のパラメーターを設定し、tuned
を CPU アフィニティー向けに構成します。
追加のリソースを加えます。
resources: userdata: type: OS::Heat::MultipartMime properties: parts: - config: {get_resource: boot_config} - config: {get_resource: set_ovs_socket_config} - config: {get_resource: set_dpdk_params} - config: {get_resource: install_tuned} - config: {get_resource: compute_kernel_args}
NeutronVhostUserSocketDir
の設定を決定します。set_ovs_socket_config: 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 mkdir -p $NEUTRON_VHOSTUSER_SOCKET_DIR chown -R qemu:qemu $NEUTRON_VHOSTUSER_SOCKET_DIR fi params: $COMPUTE_HOSTNAME_FORMAT: {get_param: ComputeHostnameFormat} $NEUTRON_VHOSTUSER_SOCKET_DIR: {get_param: NeutronVhostuserSocketDir}
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)) 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 pmd_cpu_mask=$( get_mask $PMD_CORES ) host_cpu_mask=$( get_mask $TUNED_CORES ) 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_MEMORY 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} $TUNED_CORES: {get_param: HostCpusList} $PMD_CORES: {get_param: NeutronDpdkCoreList} $SOCKET_MEMORY: {get_param: NeutronDpdkSocketMemory}
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: HostCpusList}
カーネル引数を設定します。
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"/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}
4.5.2. post-install.yaml の編集
tuned
の設定で CPU アフィニティーを指定するように設定します。ExtraConfig: type: OS::Heat::SoftwareConfig properties: group: script config: str_replace: template: | #!/bin/bash set -x 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 tuned_service=/usr/lib/systemd/system/tuned.service grep -q "network.target" $tuned_service if [ "$?" -eq 0 ]; then sed -i '/After=.*/s/network.target//g' $tuned_service fi grep -q "Before=.*network.target" $tuned_service if [ ! "$?" -eq 0 ]; then grep -q "Before=.*" $tuned_service if [ "$?" -eq 0 ]; then sed -i 's/^\(Before=.*\)/\1 network.target openvswitch.service/g' $tuned_service else sed -i '/After/i Before=network.target openvswitch.service' $tuned_service fi fi systemctl daemon-reload fi params: $COMPUTE_HOSTNAME_FORMAT: {get_param: ComputeHostnameFormat}
4.5.3. network-environment.yaml の編集
resource_registry
の下に OVS-DPDK 用のカスタムリソースを追加します。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 OS::TripleO::NodeExtraConfigPost: post-install.yaml OS::TripleO::AllNodes::Validation: dummy_all_nodes-validation.yaml
parameter_defaults
の下でトンネルの種別とテナントの種別をvxlan
に設定します。NeutronTunnelTypes: "vxlan" NeutronNetworkType: 'vxlan'
parameter_defaults
の下で、OVS-DPDK の設定パラメーターを指定します。注記NeutronDPDKCoreList
およびNeutronDPDKMemoryChannels
はこの手順では 必須 の設定です。適切な値を指定せずに DPDK のデプロイを試みると、デプロイメントが失敗するか、不安定なデプロイメントとなってしまいます。[allowed_pattern: "'[0-9,-]+'"]
の形式で DPDK Poll Mode Driver (PMD) として使用可能なコアの一覧を指定します。NeutronDpdkCoreList: "'4,6,20,22'"
OVS-DPDK のパフォーマンスを最適化するには、以下のオプションを検討してください。
-
DPDK インターフェースの NUMA ノードに関連付けられた CPU を選択します。
cat /sys/class/net/<interface>/device/numa_node
を使用してインターフェースに関連付けられた NUMA ノードをリストし、lscpu
を使用してその NUMA ノードに関連付けられた CPU をリストします。 -
CPU のシブリングをグループにまとめます (ハイパースレッディングの場合)。CPU のシブリングを特定するには、
cat /sys/devices/system/cpu/<cpu>/topology/thread_siblings_list
コマンドを実行します。 - CPU 0 はホストのプロセス用に確保します。
- PMD に割り当てられた CPU を分離して、ホストのプロセスがそれらの CPU を使用しないようにします。
-
NovaVcpuPinset
を使用して、PDM に割り当てられている CPU を Compute のスケジューリングから除外します。
-
DPDK インターフェースの NUMA ノードに関連付けられた CPU を選択します。
[allowed_pattern: "[0-9]+"]
の形式でメモリーチャネル数を指定します。NeutronDpdkMemoryChannels: "4"
各ソケットに対してヒュージページプールから事前割り当てされるメモリーを設定します。
NeutronDpdkSocketMemory: "'2048,2048'"
これは、CPU ソケットを昇順で指定するコンマ区切りの文字列です。この例では、 2 NUMA ノード構成を前提としており、ヒュージページからソケット 0 に 2048 MB 、ソケット 1 に 2048 MB を事前に割り当てるように設定しています。単一 NUMA ノード構成のシステムの場合には、この値を 1024,0 に設定してください。
OVS ブリッジの DPDK ドライバーの種別とデータパスの種別を設定します。
NeutronDpdkDriverType: "vfio-pci" NeutronDatapathType: "netdev"
parameter_defaults
の下で、OVS 用の vhost-user ソケットディレクトリーを指定します。NeutronVhostuserSocketDir: "/var/lib/vhost_sockets"
parameter_defaults
の下で、ホストのプロセス用のメモリーを確保します。NovaReservedHostMemory: "2048"
parameter_defaults
の下で、仮想マシンのプロセス用に確保する物理 CPU コアのコンマ区切りリストまたは範囲を指定します。NovaVcpuPinSet: "8,10,12,14,18,24,26,28,30"
parameter_defaults
の下で、最も制約の多いフィルターからリストして、ノードのフィルタリングプロセスをさらに効率化します。コンピュートは、フィルターの配列を使用してノードをフィルタリングします。これらのフィルターは、リスト順に適用されます。
NovaSchedulerDefaultFilters: "RamFilter,ComputeFilter,AvailabilityZoneFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,PciPassthroughFilter,NUMATopologyFilter"
parameter_defaults
の下で、ComputeKernelArgs
パラメーターを追加して、初期ブート時にそれらのパラメーターがデフォルトのgrub
ファイルに追加されるようにします。ComputeKernelArgs: "default_hugepagesz=1GB hugepagesz=1G hugepages=32 intel_iommu=on"
注記これらのヒュージページは、仮想マシンにより消費されます。また、本手順に記載の
NeutronDpdkSocketMemory
パラメーターを使用すると OVS-DPDK により消費されます。仮想マシンが利用可能なヒュージページは、boot
パラメーターからNeutronDpdkSocketMemory
を減算した値です。DPDK に関連付けられたフレーバーに
hw:mem_page_size=1GB
を追加する必要があります。追加しなかった場合には、そのインスタンスは DHCP から割り当てを受けなくなります。parameter_defaults
の下に、チューニングする物理 CPU コアの一覧または範囲を指定します。指定の引数は、tuned
cpu-partitioning
プロファイルに追加されます。HostCpusList: "'2,4,6,8,10,12,14,18,20,22,24,26,28,30'"
4.5.4. controller.yaml の編集
分離ネットワーク用にコントロールプレーンの Linux ボンディングを作成します。
- type: linux_bond name: bond_api use_dhcp: false dns_servers: {get_param: DnsServers} addresses: - ip_netmask: list_join: - '/' - - {get_param: ControlPlaneIp} - {get_param: ControlPlaneSubnetCidr} routes: - ip_netmask: 169.254.169.254/32 next_hop: {get_param: EC2MetadataIp} - default: true next_hop: {get_param: ExternalInterfaceDefaultRoute} members: - type: interface name: nic2 - type: interface name: nic3 -
この Linux ボンディングに VLAN を割り当てます。
- type: vlan vlan_id: {get_param: InternalApiNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: InternalApiIpSubnet} - type: vlan vlan_id: {get_param: ExternalNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: ExternalIpSubnet} -
Compute ノードに接続する OVS ブリッジを作成します。
- type: ovs_bridge name: br-link use_dhcp: false members: - type: interface name: nic4 - type: vlan vlan_id: {get_param: TenantNetworkVlanID} addresses: - ip_netmask: {get_param: TenantIpSubnet}
4.5.5. compute.yaml の編集
分離ネットワーク用にコントロールプレーンの Linux ボンディングを作成します。
- type: linux_bond name: bond_api use_dhcp: false dns_servers: {get_param: DnsServers} members: - type: interface name: nic4
この Linux ボンディングに VLAN を割り当てます。
- type: vlan vlan_id: {get_param: InternalApiNetworkVlanID} device: bond_api addresses: - ip_netmask: {get_param: InternalApiIpSubnet} -
コントローラーにリンクするための DPDK ポートを使用したブリッジを設定します。
- type: ovs_user_bridge name: br-link use_dhcp: false ovs_extra: - str_replace: template: set port br-link tag=_VLAN_TAG_ params: _VLAN_TAG_: {get_param: TenantNetworkVlanID} addresses: - ip_netmask: {get_param: TenantIpSubnet} members: - type: ovs_dpdk_port name: dpdk0 members: - type: interface name: nic5
注記複数の DPDK デバイスが含まれるようにするには、追加する各 DPDK デバイスごどに
type
コードスニペットを繰り返してください。注記OVS-DPDK を使用する場合には、すべての コンピュートノードのブリッジが
ovs_user_bridge
の種別である必要があります。director は設定を受け入れることができますが、Red Hat OpenStack Platform はovs_bridge
とovs_user_bridge
の混在する構成はサポートしていません。
4.5.6. overcloud_deploy.sh スクリプトを実行します。
以下の例では、Bash スクリプト内で、OVS-DPDK 環境向けの openstack overcloud deploy
コマンドを定義しています。
#!/bin/bash openstack overcloud deploy --templates \ -e /usr/share/openstack-tripleo-heat-templates/environments/neutron-ovs-dpdk.yaml \ -e /home/stack/ospd-11-vxlan-dpdk-single-port-ctlplane-bonding/network-environment.yaml
ここで
-
/usr/share/openstack-tripleo-heat-templates/environments/neutron-ovs-dpdk.yaml
は、Compute ロールの OVS-DPDK パラメーターを有効にするデフォルトのneutron-ovs-dpdk.yaml
ファイルの場所です。 -
/home/stack/<relative-directory>/network-environment.yaml
は、network-environment.yaml
ファイルのパスです。このファイルを使用して、neutron-ovs-dpdk.yaml
ファイルからのデフォルト値を上書きします。
OVS-DPDK はセキュリティーグループおよびライブマイグレーションはサポートしていません。
4.6. OVS-DPDK コンポーザブルロールの設定
本項では、VLAN トンネリングを使用した OVS-DPDK および SR-IOV 向けのコンポーザブルロールの設定方法について説明します。コンポーザブルロールの作成/デプロイプロセスは、以下の作業が含まれます。
-
role_data.yaml
ファイルのローカルコピーで新規ロールを定義します。 -
network_environment.yaml
ファイルを編集して、この新規ロールを追加します。 - 更新したロールセットでオーバークラウドをデプロイします。
以下の例では、ComputeOvsDpdk と ComputeSriov は、コンピュートノード用のコンポーザブルロールで、サポートされている NIC が搭載されたノードでのみ DPDK または SR-IOV を有効にします。Red Hat OpenStack Platform によって提供される既存のデフォルトロールセットは、/home/stack/roles_data.yaml
ファイルに保管されます。
4.6.1. コンポーザブルロールを作成するための roles_data.yaml の編集
roles_data.yaml
ファイルを /home/stack/templates
ディレクトリーにコピーして、新しい ComputeOvsDpdk および ComputeSriov のロールを追加します。
OVS-DPDK のコンポーザブルロールの定義
- name: ComputeOvsDpdk CountDefault: 1 HostnameFormatDefault: compute-ovs-dpdk-%index% disable_upgrade_deployment: True ServicesDefault: - OS::TripleO::Services::CACerts - OS::TripleO::Services::CephClient - OS::TripleO::Services::CephExternal - OS::TripleO::Services::Timezone - OS::TripleO::Services::Ntp - OS::TripleO::Services::Snmp - OS::TripleO::Services::Sshd - OS::TripleO::Services::NovaCompute - OS::TripleO::Services::NovaLibvirt - OS::TripleO::Services::Kernel - OS::TripleO::Services::ComputeNeutronCorePlugin - OS::TripleO::Services::ComputeNeutronOvsDpdkAgent - OS::TripleO::Services::ComputeCeilometerAgent - OS::TripleO::Services::ComputeNeutronL3Agent - OS::TripleO::Services::ComputeNeutronMetadataAgent - OS::TripleO::Services::TripleoPackages - OS::TripleO::Services::TripleoFirewall - OS::TripleO::Services::OpenDaylightOvs - OS::TripleO::Services::SensuClient - OS::TripleO::Services::FluentdClient - OS::TripleO::Services::AuditD - OS::TripleO::Services::Collectd
この例では、新しい
ComputeOvsDpdk
ロールのサービスはすべて通常の Compute ロールのサービスと同じですが、ComputeNeutronOvsAgent
は例外で、OVS-DPDK サービスにマッピングするComputeNeutronOvsDpdkAgent
に置き換える必要があります。SR-IOV のコンポーザブルロールを定義します。
- name: ComputeSriov CountDefault: 1 HostnameFormatDefault: compute-sriov-%index% disable_upgrade_deployment: True ServicesDefault: - OS::TripleO::Services::CACerts - OS::TripleO::Services::CephClient - OS::TripleO::Services::CephExternal - OS::TripleO::Services::Timezone - OS::TripleO::Services::Ntp - OS::TripleO::Services::Snmp - OS::TripleO::Services::Sshd - OS::TripleO::Services::NovaCompute - OS::TripleO::Services::NovaLibvirt - OS::TripleO::Services::Kernel - OS::TripleO::Services::ComputeNeutronCorePlugin - OS::TripleO::Services::ComputeNeutronOvsAgent - OS::TripleO::Services::ComputeCeilometerAgent - OS::TripleO::Services::ComputeNeutronL3Agent - OS::TripleO::Services::ComputeNeutronMetadataAgent - OS::TripleO::Services::TripleoPackages - OS::TripleO::Services::TripleoFirewall - OS::TripleO::Services::NeutronSriovAgent - OS::TripleO::Services::OpenDaylightOvs - OS::TripleO::Services::SensuClient - OS::TripleO::Services::FluentdClient - OS::TripleO::Services::AuditD - OS::TripleO::Services::Collectd
4.6.2. 新規コンポーザブルロール向けの network-environment.yaml の編集
network-environment.yaml
ファイルに OVS-DPDK および SR-IOV サービス向けのリソースマッピングと、このノードのネットワーク設定を以下のように追加します。
resource_registry: # Specify the relative/absolute path to the config files you want to use for override the default. OS::TripleO::ComputeSriov::Net::SoftwareConfig: nic-configs/compute-sriov.yaml OS::TripleO::Controller::Net::SoftwareConfig: nic-configs/controller.yaml OS::TripleO::ComputeOvsDpdk::Net::SoftwareConfig: nic-configs/compute-ovs-dpdk.yaml OS::TripleO::Services::ComputeNeutronOvsDpdkAgent: /usr/share/openstack-tripleo-heat-templates/puppet/services/neutron-ovs-dpdk-agent.yaml OS::TripleO::Services::NeutronSriovAgent: /usr/share/openstack-tripleo-heat-templates/puppet/services/neutron-sriov-agent.yaml
network-environment.yaml
ファイルの残りを設定して、OpenStack デプロイメントの必要に応じて neutron-ovs-dpdk-agent.yaml
および neutron-sriov-agent.yaml
のファイルからのデフォルトのパラメーターを上書きします。
4.6.3. overcloud_deploy.sh スクリプトを実行します。
以下の例では、コンポーザブルロールを使用する openstack overcloud deploy
の Bash スクリプトを定義しています。
# #!/bin/bash openstack overcloud deploy --templates \ -r /home/stack/templates/roles_data.yaml \ -e /usr/share/openstack-tripleo-heat-templates/environments/network-isolation.yaml \ -e /home/stack/ospd-11-vlan-dpdk-sriov-single-port-composable-roles/network-environment.yaml
/home/stack/templates/roles_data.yaml
は、更新された roles_data.yaml
ファイルの場所です。このファイルが OVS-DPDK と SR-IOV のコンポーザブルロールを定義します。
4.7. 既知の制限事項
NFV のユースケース向けに Red Hat OpenStack Platform 11 で OVS-DPDK を設定する場合には特定の制限事項があります。
- ヒュージページは OVS-DPDK を使用するホスト上で実行される全インスタンスに必要です。ゲストのヒュージページがない場合には、インターフェースは表示されても機能しません。
TAP デバイスは DPDK をサポートしていないため、それらのデバイスを使用するサービスのパフォーマンスが低下します。たとえば、DVR、FWaaS、LBaaS などのサービスは TAP デバイスを使用します。
-
OVS-DPDK では、
netdev datapath
で DVR を有効化することができますが、パフォーマンスが低いので、実稼働環境には適していません。DVR はカーネルの名前空間と TAP デバイスを使用してルーティングを実行します。 - OVS-DPDK で DVR ルーティングのパフォーマンスを良好な状態にするには、OpenFlow ルールとしてルーティングを実装する ODL などのコントローラーを使用する必要があります。OVS-DPDK では、 OpenFlow ルーティングは、Linux カーネルインターフェースによって生じるボトルネックをなくすので、データパスの完全なパフォーマンスが維持されます。
-
OVS-DPDK では、
-
OVS-DPDK を使用する場合には、すべて のブリッジがコンピュートノード上で
ovs_user_bridge
の種別である必要があります。director は設定を受け入れることができますが、Red Hat OpenStack Platform はコンピュートノード上でovs_bridge
とovs_user_bridge
の混在する構成はサポートしていません。
4.8. フレーバーの作成と OVS-DPDK 用インスタンスのデプロイ
NFV を実装する Red Hat OpenStack Platform デプロイメントの OVS-DPDK の設定を完了した後には、以下の手順に従ってフレーバーを作成してインスタンスをデプロイすることができます。
アグリゲートグループを作成して、OVS-DPDK 用にホストを追加します。
# openstack aggregate create --zone=dpdk dpdk # openstack aggregate add host dpdk compute-ovs-dpdk-0.localdomain
フレーバーを作成します。
# openstack flavor create m1.medium_huge_4cpu --ram 4096 --disk 150 --vcpus 4
このコマンドでは、
m1.medium_huge_4cpu
はフレーバー名、4096
は MB 単位のメモリー容量、150
は GB 単位のディスク容量 (デフォルトでは 0 G)、4
は仮想 CPU 数を設定しています。フレーバーの追加のプロパティーを設定します。
# openstack flavor set --property hw:cpu_policy=dedicated --property hw:cpu_thread_policy=require --property hw:mem_page_size=large --property hw:numa_nodes=1 --property hw:numa_mempolicy=preferred --property hw:numa_cpus.0=0,1,2,3 --property hw:numa_mem.0=4096 m1.medium_huge_4cpu
このコマンドでは、
m1.medium_huge_4cpu
はフレーバー名を指定しており、残りはそのフレーバーのその他のプロパティーを設定しています。インスタンスをデプロイします。
# openstack server create --flavor m1.medium_huge_4cpu --availability-zone dpdk --image rhel_7.3 --nic net-id=<net-id>
このコマンドでは、
m1.medium_huge_4cpu
はフレーバーの名前または ID、dpdk
はサーバーのアベイラビリティーゾーン、rhel_7.3
はインスタンスの作成に使用するイメージ (名前または ID)、<net-id> はサーバー上の NIC を設定します。
これで、NFV ユースケースの OVS-DPDK 向けインスタンスのデプロイが完了しました。
multi-queue を OVS-DPDK で使用するには、上記の手順に数ステップを追加する必要があります。フレーバーを作成する前に、以下のステップを実行してください。
イメージのプロパティーを設定します。
# openstack image set --property hw_vif_multiqueue_enabled=true <image-id>
ここで、
hw_vif_multiqueue_enabled=true
はこのイメージ上でマルチキューを有効にするためのプロパティーで、<image-id>
は変更するイメージの名前または ID です。フレーバーの追加のプロパティーを設定します。
# openstack flavor set m1.vm_mq set hw:vif_multiqueue_enabled=true
ここで、
m1.vm_mq
はフレーバーの ID または名前で、残りのオプションはそのフレーバーのマルチキューを有効化します。
4.9. 設定のトラブルシューティング
本項では、DPDK-OVS 設定のトラブルシューティングの手順を説明します。
ブリッジの設定を見直して、ブリッジが
datapath_type=netdev
で作成されたことを確認します。# ovs-vsctl list bridge br0 _uuid : bdce0825-e263-4d15-b256-f01222df96f3 auto_attach : [] controller : [] datapath_id : "00002608cebd154d" datapath_type : netdev datapath_version : "<built-in>" external_ids : {} fail_mode : [] flood_vlans : [] flow_tables : {} ipfix : [] mcast_snooping_enable: false mirrors : [] name : "br0" netflow : [] other_config : {} ports : [52725b91-de7f-41e7-bb49-3b7e50354138] protocols : [] rstp_enable : false rstp_status : {} sflow : [] status : {} stp_enable : false
neutron-ovs-agent
が自動的に起動するように設定されていることを確認して、OVS サービスをレビューします。# systemctl status neutron-openvswitch-agent.service neutron-openvswitch-agent.service - OpenStack Neutron Open vSwitch Agent Loaded: loaded (/usr/lib/systemd/system/neutron-openvswitch-agent.service; enabled; vendor preset: disabled) Active: active (running) since Mon 2015-11-23 14:49:31 AEST; 25min ago
サービスの起動に問題がある場合には、以下のコマンドを実行して関連のメッセージを表示することができます。
# journalctl -t neutron-openvswitch-agent.service
ovs-dpdk
の PMD CPU マスクが CPU にピニングされていることを確認します。HT の場合には、シブリング CPU を使用します。たとえば
CPU4
を例に取ります。# cat /sys/devices/system/cpu/cpu4/topology/thread_siblings_list 4,20
CPU 4 と 20 を使用します。
# ovs-vsctl set Open_vSwitch . other_config:pmd-cpu-mask=0x100010
ステータスを表示します。
# tuna -t ovs-vswitchd -CP thread ctxt_switches pid SCHED_ rtpri affinity voluntary nonvoluntary cmd 3161 OTHER 0 6 765023 614 ovs-vswitchd 3219 OTHER 0 6 1 0 handler24 3220 OTHER 0 6 1 0 handler21 3221 OTHER 0 6 1 0 handler22 3222 OTHER 0 6 1 0 handler23 3223 OTHER 0 6 1 0 handler25 3224 OTHER 0 6 1 0 handler26 3225 OTHER 0 6 1 0 handler27 3226 OTHER 0 6 1 0 handler28 3227 OTHER 0 6 2 0 handler31 3228 OTHER 0 6 2 4 handler30 3229 OTHER 0 6 2 5 handler32 3230 OTHER 0 6 953538 431 revalidator29 3231 OTHER 0 6 1424258 976 revalidator33 3232 OTHER 0 6 1424693 836 revalidator34 3233 OTHER 0 6 951678 503 revalidator36 3234 OTHER 0 6 1425128 498 revalidator35 *3235 OTHER 0 4 151123 51 pmd37* *3236 OTHER 0 20 298967 48 pmd38* 3164 OTHER 0 6 47575 0 dpdk_watchdog3 3165 OTHER 0 6 237634 0 vhost_thread1 3166 OTHER 0 6 3665 0 urcu2