![OpenNebula (KVM) + OpenvSwitch, высокая загрузка ЦП при использовании высокой пропускной способности](https://rvso.com/image/697403/OpenNebula%20(KVM)%20%2B%20OpenvSwitch%2C%20%D0%B2%D1%8B%D1%81%D0%BE%D0%BA%D0%B0%D1%8F%20%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B0%20%D0%A6%D0%9F%20%D0%BF%D1%80%D0%B8%20%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B8%20%D0%B2%D1%8B%D1%81%D0%BE%D0%BA%D0%BE%D0%B9%20%D0%BF%D1%80%D0%BE%D0%BF%D1%83%D1%81%D0%BA%D0%BD%D0%BE%D0%B9%20%D1%81%D0%BF%D0%BE%D1%81%D0%BE%D0%B1%D0%BD%D0%BE%D1%81%D1%82%D0%B8.png)
Мы используем среду OpenNebula 5.0.2 на Ubuntu 16.04, используя OpenvSwitch 2.5 для мостового соединения виртуальных интерфейсов и транкинга LACP двух гигабитных портов, что работает отлично.
Но когда я запускаю тест пропускной способности iperf3 между виртуальной машиной и ее хостом, htop показывает 100% загрузку ЦП для QEMU, на котором запущена эта виртуальная машина, а iperf3 получает всего 100–200 Мбит/с, хотя нет других запущенных виртуальных машин, требовательных к пропускной способности. iperf3 между двумя хостами виртуальных машин обеспечивает почти полные 1 Гбит/с и не нагружает ЦП.
Раньше, когда мы ещё работали на версии 2.0.2, я думал, что это проблема OpenvSwitch, но теперь мне кажется, что это какая-то недостающая оптимизация виртуальной сети...
решение1
Все, что должно пройти через виртуальный мост, получит довольно большой удар. Это касается ovs и мостов Linux, поскольку они оба должны выполнять проверку пакетов в неразборчивом режиме, чтобы определить, куда что должно идти (по сути, коммутатор уровня 2).
В сценариях с высокой производительностью, например, с 10Gib ethernet, иногда разумнее выполнить сквозную передачу устройства srv-io, а не позволять хостовой ОС переключаться на уровень 2. Это имеет тот недостаток, что только этот один гость может использовать переданную карту ethernet. Сквозная передача PCI работает очень хорошо для сетевых карт, и KVM / libvirt в этом преуспевает.
Macvtap также может передавать трафик напрямую гостевой виртуальной машине практически без накладных расходов и без использования srv-io PCI pass-through (поэтому вам не нужно выделять оборудование для одной виртуальной машины). Macvtap ограничен тем, что он никогда не может обеспечить связь хост-гость или даже гостевая связь в пределах одного гипервизора (поскольку он использует один и тот же MAC-адрес вашего хоста, а не использует разные адреса для каждого гостя через виртуальный коммутатор). Один из способов обойти это — выполнить «прикрепление» на уровне коммутатора (если ваш коммутатор поддерживает это), позволяя устройству общаться с самим собой через своего рода петлю на одном порту и одном MAC-адресе.
Для взаимодействия хоста и гостя при использовании любого из этих методов, которые я упомянул выше, обычно предоставляется дополнительная мостовая сеть только для того, что не используется для высокопроизводительных коммуникаций. На самом деле это очень распространенная конфигурация при использовании >=10Gib Ethernet на виртуальных машинах.
решение2
Одна из самых важных оптимизаций, которую я смог успешно (и легко, без замены сетевой карты и т. д.) применить, заключалась в использовании модели virtio по умолчанию для всех сетевых карт в шаблоне виртуальной машины или для каждой сетевой карты отдельно, как описаноздесь:
NIC_DEFAULT = [
MODEL = "virtio" ]
Для уже созданной виртуальной машины выключите ее, отсоедините все сетевые карты и подключите их заново с помощью модели «virtio».
В моих первых тестах он увеличил пропускную способность iperf3 до 5,6 Гбит/с между хостом и гостем и снизил нагрузку на ЦП хоста примерно до 50–60 % на поток QEMU во время теста (< 5 % при скорости почти 1 Гбит/с при запуске клиента iperf3 с хоста, подключенного через Гбит/с).
Если вы знаете о дальнейших оптимизациях, смело добавляйте их!