Предыстория

В этом году руководство приняло решение обновлять железо в серверной. С учетом древности, требовалось обновить если не всё, то почти всё.
На момент принятия решения об обновлении мы имели полку HP C3000 с блэйд серверами g6-g7 поколений, подключенную к дисковым хранилищам через ethernet 1GbE аплинки. Дисковые хранилища с sas 10k без кэша. Все это добро работало по iSCSI протоколу, на блэйд серверах были старенькие ESXi. Из нагрузки имелось порядка 70-80 vm разной направленности: виртуальный роутер, почта, AD, DNS, 1С, базы и остальные сервисы разной направленности. Признаюсь, не всё так плохо, я умолчал о standalone сервере с nvme под сверхнагруженный сервис, но об этом, может, расскажу позже, если статья зайдет.

Итак. Хотелось чего-то современного, быстрого, желательно на nvme дисках и не сильно бьющего по бюджету организации. Предвидя вопрос о том, что есть "сильно" - это если покупать что-то похожее, только современное и с FC, отдельными HBA nvme хранилищами с резервированием. Но зачем усугублять, когда можно обойтись virtual SAN решением с резервированием и масштабируемостью?

В итоге согласовали покупку 4 серверов hp dl360g10 в nvme исполнении backplane, сетевых карт 2*25GbE, пары свитчей mellanox SN2410-CB2FC, nvme дисков с минимум 3 DWPD. Всё оборудование с поддержкой RDMA/RoCE. Решение подразумевало разворачивание vSAN.

О том, как всё это новое добро настраивалось и какие решения были приняты, далее.


Немного про технологии, использованные в решении

QoS обеспечивает возможность классифицировать потоки по приоритетам (или классам) и предоставлять каждому приоритету различные характеристики, такие как распределение буфера, управление потоком, RED/ECN, организация очередей, планирование и т. д.

Про RDMA

RDMA - аппаратное решение для прямого доступа к памяти другого компьютера при помощи высокоскоростной сети. Методом пересылки данных с высокой пропускной способностью и низкой latency позволяет получить доступ к данным, хранящимся в удалённой системе, без привлечения средств операционных систем обоих компьютеров. Исключаются лишние копирования между приложением и буферами операционной системы, снижается объём работы центрального процессора, нагрузка на кэш-память, уменьшается количество переключений контекста, а сами передачи могут производиться одновременно с другой полезной работой. Полезен в больших параллельных вычислительных системах — кластерах.

Про RoCE

RoCE это развитие RDMA от InfiniBand Trade Association. Предшественником RoCE был iWARP, по сравнению с которым RoCE более энергоэффективен и производителен. У RoCE есть две версии, RoCE v1 и v2. Если вкратце, то RoCEv1 оперирует в L2, а RoCEv2 - маршрутизируемый трафик UDP в L4. Далее по тексту пойдет речь как раз о v2.

Итак, железо приехало, распаковано, установлено. Как устанавливать ESXi на сервера или настраивать ilo, писать не буду, подразумеваю, что читающая habr аудитория это умеет. А вот про свитч расскажу.

Как многие знают, компания Mellanox была поглощена компанией NVIDIA, которая, в свою очередь, приостановила свою деятельность на территории РФ. К чему я об этом пишу, спросите Вы? А я отвечу - свитч приехал с ОС Cumulus linux 3.1, в которой напрочь отсутствует DCBX (data center bridging eXchange) и, соответственно, реализовать на данной версии RoCE невозможно. Попытки зарегистрироваться на сайте Nvidia enterprise утыкались в "компания NVIDIA приостановила свою деятельность на вашей территории". Импортер отказался помогать в обновлении свитча. И это всё несмотря на то, что свитч на гарантии и с активной подпиской поддержки NVIDIA.

После изучения вопроса был найден выход - установить ОС NVIDIA Onyx на данный свитч. Я установил версию 3.10.4206 LTS. (Если Вам нужен дистрибутив, пишите в личку, помогу)

Настройка свитча, что относится к QoS, достаточно простая:

configure terminal
roce lossless
lldp
interface ethernet 1/1-1/32 qos trust L3
dcb priority-flow-control enable force
dcb priority-flow-control priority 3 enable
no advanced buffer management force
traffic pool roce-reserved type lossless
traffic pool roce-reserved memory percent 50.00
traffic pool roce-reserved map switch-priority 3
interface ethernet 1/1-1/32 traffic-class 6 dcb ets strict
interface ethernet 1/1-1/32 traffic-class 3 congestion-control ecn minimum-absolute 150 maximum-absolute 1500

В данной конфигурации включаем технологию RoCE в режиме "без потерь", включим ECN, DCB, PFC равным 3. Выделим пул памяти "roce-reserved" в 50% памяти свитча и явно укажем, что этот пул под трафик PFC = 3.

Про ECN

ECN - Explicit Congestion Notification, грубо - это уведомления о перегруженности в сети, оперирующие на L4 уровне. Нужно для того, чтобы пакеты не отбрасывались, а складывались в очередь. RoCEv2 ведь, как никак, lossless, а значит передача без потерь, и помним, что RoCEv2 UDP, соответственно, если мы отбросим пакеты, то они более переданы не будут.

Про PFC

Priority Flow Control (PFC) IEEE 802.1Qbb - это паузы для входящего трафика, чтобы уведомить одноранговый узел о необходимости приостановить передачу, когда канал перегружен. Смысл этой технологии в том, чтобы в моменты затора в сетях центров обработки данных (dcb) пакеты RoCE имели приоритет над трафиком TCP, а следовательно, при больших загрузках каналов не было тротлинга по сети хранения SAN.
Чтобы понять, что перед нами кадр PFC, свитч или конечное устройство может анализировать 3 бита заголовка vlan на уровне L2 - PCP (Priority Code Point), или, если нет vlan, то применяется DSCP (Differentiated Services Code Point), а это уже L3 уровень и производится анализ 6 бит в заголовке IP. Если всё верно настроено, то кадры попадают в нужный буфер и не теряются. В остальных случаях будет происходить drop пакетов. Кстати DSCP как реализация появилась чуть позже, чем PCP и, как следствие, поначалу RoCEv2 работал только в vlan.

С вашего позволения, я не буду упарываться рассказывать о случаях, когда присутствуют несколько свитчей в mlag и в свитчах пакеты PFC без vlan, а mlag соединение в vlan, и требуется пересылка пакетов RoCE через mlag. Т.е. внутри свитча действует DSCP, а между свитчами в соединении mlag уже PCP. Это более сложный вариант, и я его опишу, если вы это потребуете, отдельным постом.

Про PFC Watchdog

При включенном PFC сети гарантируют доставку пакетов в рамках выбранного приоритета. Однако, со всеми преимуществами PFC привносит и очередной сценарий отказа, при котором очередь конечного порта (например, порта хоста, подключенного к сети) может не иметь возможности получать какой-либо трафик из сети и продолжать отправлять кадры паузы в сторону коммутатора. Если очередь конечного порта зависает на долгое время, буферы заполняются не только на одном коммутаторе, но и на всех коммутаторах с проблемными очередями портов на пути пересылки трафика. Это приводит к появлению бесконечных кадров паузы PFC, так же называемых штормом PFC.

Для предотвращения таких штормов реализован PFC Watchdog. Когда коммутаторы обнаруживают эту ситуацию в любой очереди TC, все пакеты в очереди сбрасываются, а новые пакеты, предназначенные для той же очереди, также отбрасываются до тех пор, пока не закончится шторм PFC.

Включать ли PFC Watchdog каждый решает сам. Я не включал, поскольку у меня исключена ситуация пересылки PFC из свитча в свитч.

DCB

Data center bridging - это расширение протокола Ethernet. Для выбранного типа класса трафика устраняет потери, связанные с переполнением очереди. По сути, DCB позволяет в некоторой степени рассматривать разные приоритеты, как если бы это были разные каналы.  DCB различает потоки трафика, помечая трафик определенным значением от 0 до 7.
Обычно потерянные пакеты данных не являются большой проблемой, поскольку они будут повторно переданы по TCP/IP, но с трафиком хранилища потерянные пакеты данных снижают производительность, поскольку они приводят к задержкам ввода-вывода, что неприемлемо. DCB использует значения CoS, чтобы указать, какое значение должно быть передано без потерь через сеть. Обычно сетевые коммутаторы поддерживают до трех значений CoS.
DCBX является расширением протокола DCB, где «X» означает eXchange. Смысл DCBX в автоматической передаче настроенных параметров очередей коммутатора на сетевые карты серверов.

Строчка конфига no advanced buffer management force отвечает за то, что буфером будет управлять свитч автоматически. Можно настроить и самому, но при малейшей ошибке lossless перестанет быть lossless, начнется отсечка трафика, который не влезет в пул, и будут потери пакетов в сети. Настройка объемов пулов и работы с ними в ручном режиме - это тюнинг на грани фола.

По умолчанию, для свитчей NVIDIA:

  • Пулы:

    • iPool0, ePool0 – пулы по умолчанию для всего трафика. Объем устанавливается динамически с ограничением в размер shared buffers для каждого.

    • iPoolCtrl, ePoolCtrl – динамические пулы под типы трафика 0-7 с размером 256KB каждый.

    • ePool15 – multicast пул в статичном режиме с "бесконечным" ограничением.

  • Буферы:

    • Настройки буферов идентичны на всех портах свитча.

    • По умолчанию все приоритеты смотрят в PG0.

    • Каждый приоритет (switch-priority) соответствует типу трафика (TC) буфера (i-to-i).

Терминология, используемая при классификации трафика

Когда пакет поступает на коммутатор, он классифицируется в соответствии с входным портом, выходным портом и полями заголовка уровня L2 и L3. Следующие термины используются для классификации пакетов внутри коммутатора:

Порты:

  • Ingress port (iPort) – порт, на который получен пакет.

  • Egress port (ePort) – порт, который передает пакет.

Пулы:

  • Ingress pool (iPool) – пул памяти для входящего трафика.

  • Egress pool (ePool) — пул памяти для исходящего трафика.

Приоритеты:

  • Switch priority (SP) внутренний идентификатор приоритета пакета, который используется в качестве ключа для некоторых внутренних функций и решений коммутатора, включая буферизацию. SP пакета назначается в соответствии с конфигурацией уровня доверия порта и идентификаторами QoS пакета в заголовке (PCP, DEI, DSCP).

  • Priority group (PG) PG объединяет группу SP. Он используется для группировки пакетов с несколькими приоритетами коммутатора в одном буфере. Диапазон PG — от 0 до 7. PG 9 зарезервирован для управляющего трафика.

  • Traffic class (TC) TC объединяет группу SP. Он используется для группировки пакетов с несколькими приоритетами коммутатора в одну выходную очередь и буферное пространство. Диапазон TC составляет от 0 до 15, при этом TC 8–15 зарезервирован для многоадресного трафика, а TC 16 зарезервирован для управляющего трафика.

Механизм настройки буфера позволяет выделить буферное пространство для определенных типов трафика путем настройки буферов следующих типов:

  • iPort.PG – трафик, который поступает на определенный порт и сопоставляется с определенной PG.

  • iPort (iPort.pool) – трафик, который поступает на определенный порт и учитывается на конкретном iPool. Суммирует все iPort.PG, сопоставленные с указанным iPool.

  • ePort.TC – трафик, который передается на определенный порт и отображается на определенный TC.

  • ePort (ePort.pool) – трафик, который передается на определенный порт и учитывается на конкретном ePool. Он должен суммировать все ePort.TC, сопоставленные с указанным ePool.

Поскольку многоадресные пакеты дублируются между выходными портами, чтобы обеспечить согласованный подсчет пакетов на входящей и исходящей сторонах, используются следующие типы буферов:

  • MC.SP – многоадресный трафик, который классифицируется по определенному приоритету коммутатора. Подсчет происходит на выходной стороне до дублирования пакетов.

  • ePort.mc – многоадресный трафик, который будет передаваться на определенный порт.

Буферы могут делиться на основе резервирования и распределения памяти:

  • Reserved allocation (size) - буфер с гарантированной квотой, которая не используется совместно пулами

  • Shared allocation (shared) - максимально возможная квота буферизации, которую можно использовать совместно с другими буферами и распределять динамически. Использование буфера не может превышать данную квоту. Совместное распределение можно установить с использованием статического или динамического порога распределения.

Буфер iPort.PG можно настроить для работы в одном из двух режимов:

  • Lossy – для трафика с потерями.

  • Lossless – для трафика без потерь. В этом режиме пользователь должен определить пороговые значения управления потоком (Xoff, Xon). Достижение порога Xoff при занятости буфера PG будет генерировать кадры «паузы» для отправителя. Достижение порога Xon прекращает передачу кадров «на паузу». Зарезервированное выделение памяти для этого буфера должно быть не менее значения Xoff, чтобы обеспечить достаточную буферизацию ingress пакетов.

После первоначального допуска в буфер, в котором определены его egress порт, TC и ingress PG, пакет оценивается на предмет его пригодности для хранения в буферном пространстве до тех пор, пока он не будет перенаправлен.

При автоматической конфигурации buffer management интерфейс eth предоставит следующую информацию:
Flags:
  Y: Lossy
  L: Lossless
  S: Static
  D: Dynamic

  Shared size is in percent/Bytes for static pool and in alphas for dynamic pool

Interface Eth1/1:
  ------------------------------------------------------------------------------------------
  Buffer              Resv      Xoff      Xon       Shared        Pool          Description
                      [Byte]    [Byte]    [Byte]    [%/a/Byte]                  
  ------------------------------------------------------------------------------------------
  iPort.iPool0(Y)     10.0K     -         -         alpha 8       iPool0(D)     
  iPort.iPool1(Y)     0         -         -         alpha 1       iPool1(D)     
  iPort.iPool2(Y)     0         -         -         alpha 0       iPool2(D)     
  iPort.iPool3(Y)     0         -         -         alpha 0       iPool3(D)     
  iPort.iPool4(Y)     0         -         -         alpha 0       iPool4(D)     
  iPort.iPool5(Y)     0         -         -         alpha 0       iPool5(D)     
  iPort.iPool6(Y)     0         -         -         alpha 0       iPool6(D)     
  iPort.iPool7(Y)     0         -         -         alpha 0       iPool7(D)     
  iPort.iPoolCtrl(Y)  0         -         -         alpha 8       iPoolCtrl(D)  
  iPort.pg0(Y)        0         -         -         alpha 8       iPool0(D)     
  iPort.pg1(L)        63.4K     19.0K     19.0K     alpha 1       iPool1(D)     
  iPort.pg2(Y)        0         -         -         alpha 0       iPool0(D)     
  iPort.pg3(Y)        0         -         -         alpha 0       iPool0(D)     
  iPort.pg4(Y)        0         -         -         alpha 0       iPool0(D)     
  iPort.pg5(Y)        0         -         -         alpha 0       iPool0(D)     
  iPort.pg6(Y)        0         -         -         alpha 0       iPool0(D)     
  iPort.pg7(Y)        0         -         -         alpha 0       iPool0(D)     
  iPort.pg9(Y)        10.0K     -         -         alpha 8       iPoolCtrl(D)  
  ePort.ePool0        5.0K      -         -         alpha 8       ePool0(D)     
  ePort.ePool1        0         -         -         alpha inf     ePool1(D)     
  ePort.ePool2        0         -         -         alpha 0       ePool2(D)     
  ePort.ePool3        0         -         -         alpha 0       ePool3(D)     
  ePort.ePool4        0         -         -         alpha 0       ePool4(D)     
  ePort.ePool5        0         -         -         alpha 0       ePool5(D)     
  ePort.ePool6        0         -         -         alpha 0       ePool6(D)     
  ePort.ePool7        0         -         -         alpha 0       ePool7(D)     
  ePort.mc            0         -         -         inf           ePool15(S)    
  ePort.ePoolCtrl     0         -         -         alpha 8       ePoolCtrl(D)  
  ePort.tc0           1.0K      -         -         alpha 8       ePool0(D)     
  ePort.tc1           0         -         -         alpha 0       ePool0(D)     
  ePort.tc2           0         -         -         alpha 0       ePool0(D)     
  ePort.tc3           0         -         -         alpha inf     ePool1(D)     
  ePort.tc4           0         -         -         alpha 0       ePool0(D)     
  ePort.tc5           0         -         -         alpha 0       ePool0(D)     
  ePort.tc6           1.0K      -         -         alpha 8       ePool0(D)     
  ePort.tc7           0         -         -         alpha 0       ePool0(D)     
  ePort.tc16          1.0K      -         -         alpha 8       ePoolCtrl(D)  

  switch-priority to Buffers mapping:
    ------------------------------
    Switch-priority    Buffer    
    ------------------------------
    0                  iPort.pg0 
    1                  iPort.pg0 
    2                  iPort.pg0 
    3                  iPort.pg1 
    4                  iPort.pg0 
    5                  iPort.pg0 
    6                  iPort.pg0 
    7                  iPort.pg0 

Здесь видим, что switch-priority 3 смотрит в буфер iPort.pg1, который в свою очередь обозначен (L) lossless и находится в динамическом пуле iPool1. i перед Pool это ingress, т.е. входящий трафик. Аналогично для исходящего трафика egress ePort.tc3 - исходящий трафик с контекстом 3.

Почему же я написал про всякие PFC, DSCP, ECN и DCB? Да всё потому, что при настройке VMware vSAN 8 в новой его версии ESA (Express Storage Architecture), которую решил опробовать автор данной статьи, есть весьма определенные требования к работе RoCEv2. А именно, что PFC должен быть равен 3, DSCP равен 26, должен быть включен DCBX, должно быть выставлено доверие L3 (qos trust L3) для работы того самого DSCP. И более того, со стороны VMware для RoCE определен особый порядок работы портов на сетевой карте, nic teaming работает исключительно в режиме, когда один порт активен, а другой standby и исключительно "use explicit failover order". Lag, nic teaming, не, не слышал. Всё потому, что кадры маршрутизируемы и должны приходить исключительно на предопределенные порты. Если в конфигурации будет что-то не так, то RoCE просто не заработает, хотя в VMware будет показывать в меню, что функция включена:

так покажет даже в том случае, если RDMA не работает
так покажет даже в том случае, если RDMA не работает
Но вы всегда можете посмотреть

/var/log/vmkernel.log на ESXi и убедиться, что у вас-то всё в порядке и всё работает!


Предположим, что кластер vSAN уже создан, vmkernel для сети vSan настроен, в конце концов есть официальная справка, как это делать.

Далее я предложу способ активации RDMA в VMware ESXi для устройств на базе чипов mellanox. В моем случае это сетевые карты HP 640FLR на базе mellanox ConnectX-4 Lx.

Для того, чтобы у нас всё получилось, идем на сайт nvidia и скачиваем последние драйвера и утилиту управления прошивкой. Заодно можно и прошивку на устройстве обновить до последней. После установки, например, через ssh или графическую среду vcenter с использованием "Lifecycle manager", утилиты будут доступны через ssh на ESXi по пути /opt/mellanox/bin.

Для того, чтобы понять, какая у нас версия карты и как называется конфиг, выполним:

/opt/mellanox/bin/mst status -v
PCI devices:
------------
DEVICE_TYPE             MST                           PCI       RDMA            NET                                     NUMA  
ConnectX4LX(rev:0)      mt4117_pciconf0               5d:00.0                                                 

ConnectX4LX(rev:0)      mt4117_pciconf0.1             5d:00.1

Далее изменим флаги конфигурации по умолчанию, включив DCBX в режим IEEE, и выключим CEE:

/opt/mellanox/bin/mlxconfig -d mt4117_pciconf0 set LLDP_NB_DCBX_P1=1 LLDP_NB_RX_MODE_P1=2 LLDP_NB_TX_MODE_P1=2 LLDP_NB_DCBX_P2=1 LLDP_NB_RX_MODE_P2=2 LLDP_NB_TX_MODE_P2=2 DCBX_WILLING_P1=1 DCBX_IEEE_P1=1 DCBX_CEE_P1=0 DCBX_WILLING_P2=1 DCBX_IEEE_P2=1 DCBX_CEE_P2=0

Далее изменим флаги настройки драйверов.

Сначала проверим, какой драйвер используется командами esxcli network nic list и esxcli rdma device list
esxcli network nic list
Name    PCI Device    Driver      Admin Status  Link Status  Speed  Duplex  MAC Address         MTU  Description
------  ------------  ----------  ------------  -----------  -----  ------  -----------------  ----  -----------
...
vmnic4  0000:5d:00.0  nmlx5_core  Up            Up           25000  Full    e0:07:1b:xx:xx:xx  9000  Mellanox Technologies MT27710 Family [ConnectX-4 Lx]
vmnic5  0000:5d:00.1  nmlx5_core  Up            Up           25000  Full    e0:07:1b:xx:xx:xx  9000  Mellanox Technologies MT27710 Family [ConnectX-4 Lx]
esxcli rdma device list
Name     Driver      State    MTU  Speed    Paired Uplink  Description
-------  ----------  ------  ----  -------  -------------  -----------
vmrdma0  nmlx5_rdma  Active  4096  25 Gbps  vmnic4         MT27710 Family  [ConnectX-4 Lx]
vmrdma1  nmlx5_rdma  Active  4096  25 Gbps  vmnic5         MT27710 Family  [ConnectX-4 Lx]

Видим драйвер nmlx5_core, а для RDMA используется nmlx5_rdma. Включим для этих драйверов то, что требует от нас vmWare. DCBX=1, PFC=3, DSCP=26, pfctx=8, pfcrx=8. Заодно можно включить что-то еще, все равно потребуется перезапуск хоста=) Например SR-IOV (max_vfs=4).

esxcli system module parameters set -m nmlx5_core -p dcbx=1
esxcli system module parameters set -m nmlx5_core -p "pfctx=0x08 pfcrx=0x08 trust_state=2 max_vfs=4"
esxcli system module parameters set -m nmlx5_rdma -p "pcp_force=3 dscp_force=26"

После перезапуска хоста потребуется немного подождать, пока сетевая карта применяет новые флаги, отправленные через mlxconfig. В моем случае около 5 минут. Однако даже после 5 минут на одном из хостов на втором порту не применились настройки, и потребовалась еще одна перезагрузка хоста.

Для проверки, что применились флаги mlxconfig
esxcli network nic dcb status get -n vmnic4
   Nic Name: vmnic4
   Mode: 3 - IEEE Mode
   Enabled: true
   Capabilities: 
         Priority Group: true
         Priority Flow Control: true
         PG Traffic Classes: 8
         PFC Traffic Classes: 8
   PFC Enabled: true
   PFC Configuration: 0 0 0 1 0 0 0 0
   IEEE ETS Configuration: 
         Willing Bit In ETS Config TLV: 1
         Supported Capacity: 8
         Credit Based Shaper ETS Algorithm Supported: 0x0
         TX Bandwidth Per TC: 50 0 0 50 0 0 0 0
         RX Bandwidth Per TC: 50 0 0 50 0 0 0 0
         TSA Assignment Table Per TC: 2 2 2 2 2 2 2 2
         Priority Assignment Per TC: 0 0 0 3 0 0 6 0
         Recommended TC Bandwidth Per TC: 50 0 0 50 0 0 0 0
         Recommended TSA Assignment Per TC: 2 2 2 2 2 2 2 2
         Recommended Priority Assignment Per TC: 0 0 0 3 0 0 6 0
   IEEE PFC Configuration: 
         Number Of Traffic Classes: 8
         PFC Configuration: 0 0 0 1 0 0 0 0
         Macsec Bypass Capability Is Enabled: 0
         Round Trip Propagation Delay Of Link: 0
         Sent PFC Frames: 0 0 0 0 0 0 0 0
         Received PFC Frames: 0 0 0 0 0 0 0 0
   DCB Apps: 

Важно, чтобы было написано Mode: 3 - IEEE Mode, если mode unknown, то конфигурация не применилась и нужна еще одна перезагрузка. Это, к сожалению, было выяснено экспериментально спустя множество откатов конфигураций и применений заново. Также необходимо убедиться, что PFC: true, willing bit in ets: 1. Без этого работать тоже не будет.

Если на предыдущем шаге у нас успех и параметры сетевой карты правильные, проверяем параметры драйверов
esxcli system module parameters list -m nmlx5_core | grep 'trust_state\|pfcrx\|pfctx'

Проверяем, что параметры применились

После этого включаем RDMA в кластере vSAN и проверяем на наличие ошибок /var/log/vmkernel.log.

Если вы увидите что-то вроде
2023-11-03T04:01:29.072Z Wa(180) vmkwarning: cpu57:2098375)WARNING: rdmaDriver: RDMAFindTeamDeviceByPortID:3147: Unspported team policy = 8 status = Success                                                                   
2023-11-03T04:01:29.072Z Wa(180) vmkwarning: cpu57:2098375)WARNING: rdmaDriver: RDMACM_BindLegacy:4306: The provided interface (192.168.205.11) does not have a registered rdma device.                                       
2023-11-03T04:01:29.072Z In(182) vmkernel: cpu57:2098375)RDT: RDTCreateRDMAServer:2754: vmk_RDMACMBind() failed for server Bad parameter                                                                                       
2023-11-03T04:01:29.072Z In(182) vmkernel: cpu57:2098375)RDT: RDTCreateRDMAServer:2787: RDTCreateRDMAServer() exiting with failure                                                                                             
2023-11-03T04:01:29.072Z In(182) vmkernel: cpu57:2098375)RDT: RDTEnableRdmaInt:642: Failed to create listener for address 192.168.205.11, protocol 2, status Bad parameter                                                     
2023-11-03T04:01:34.074Z In(182) vmkernel: cpu62:2098375)RDT: RDTDisableRdmaInt:722: SupportedTransportProtocolsMask removes RDMA

то проверьте, как настроены аплинки в вашем виртуальном свитче. LAG не работает, nic teaming работает исключительно в режиме "use explicit failover order".

Интересный факт - в статье NVIDIA говорится, что аплинки должны быть в режиме  "route based on physical nic load". Ну так вот оно так не работает, только режим "explicit failover order" и никак иначе.

После этих действий можно запустить какой-нибудь тест производительности кластера или самому дать нагрузку и посмотреть, появляются ли паузы и пакеты RDMA на свитче.

Hidden text
show interface ethernet 1/1 counters roce

Eth1/1:
  Rx:
    1237468664            RoCE PG packets
    910484091264          RoCE PG bytes
    0                     RoCE no buffer discard
    78086993              CNP PG packets
    165974383879          CNP PG bytes
    0                     CNP no buffer discard
    6                     RoCE PFC pause packets
    391                   RoCE PFC pause duration
    0                     RoCE buffer usage (bytes)
    828288                RoCE buffer max usage (bytes)
    0                     CNP buffer usage (bytes)
    2492448               CNP buffer max usage (bytes)
    0                     RoCE PG usage (bytes)
    828288                RoCE PG max usage (bytes)
    0                     CNP PG usage (bytes)
    2492448               CNP PG max usage (bytes)

  Tx:
    1228356               ECN marked packets
    1488922017            RoCE TC packets
    2063482007374         RoCE TC bytes
    0                     RoCE unicast no buffer discard
    368148                CNP TC packets
    28715544              CNP TC bytes
    0                     CNP unicast no buffer discard
    0                     RoCE PFC pause packets
    0                     RoCE PFC pause duration
    0                     RoCE buffer usage (bytes)
    1120224               RoCE buffer max usage (bytes)
    0                     CNP buffer usage (bytes)
    2746848               CNP buffer max usage (bytes)
    0                     RoCE TC usage (bytes)
    1120224               RoCE TC max usage (bytes)
    0                     CNP TC usage (bytes)
    96                    CNP TC max usage (bytes)

Еще можно посмотреть наличие пауз на интерфейсе ESXi:

Hidden text
vsish -e cat /net/pNics/vmnic4/stats | grep -e "Pause\|PerPrio"
rxPauseCtrlPhy: 0
txPauseCtrlPhy: 6
txPauseStormWarningEvents: 0
txPauseStormErrorEvents: 0

Если после серьезной нагрузки счетчики по нулям, возможно, что у вас что-то не работает, либо же вы не уперлись в производительность сетевых интерфейсов.

На этом у меня всё, надеюсь, данная статья поможет кому-нибудь интегрировать у себя RoCE, т.к. технология весьма интересная, а информации по ее внедрению не так много.

Комментарии (11)


  1. iLexey
    08.11.2023 16:59

    Прикольно все названия, кроме одного написать верно. Название компании VMware пишется так.


  1. Thomas_Hanniball
    08.11.2023 16:59
    +2

    Как-то всё слишком сложно. Хочу просто включать галочку vSAN и чтобы оно само начало работать без лишней магии.


    1. All3 Автор
      08.11.2023 16:59

      Я тоже хотел, но оно так не работает. Когда стал погружаться в эту тему, выяснил, что это нормальная ситуация у мировых вендоров, таких как Nvidia, IBM, Dell, Intel, Broadcom, Lenovo. У всех у них нужно сначала обратиться к вендору, создать тикет и по нему тебе окажут "поддержку". Такова современная реальность.


    1. ildarz
      08.11.2023 16:59

      Включил, прощелкал мастером и просто работает - это к винде (пока ещё, хотя и там свои приколы есть).


  1. ildarz
    08.11.2023 16:59

    А тесты дисковой не гоняли? Были бы интересны iops/latency на 4K random начиная с qd1 и до насыщения.


    1. All3 Автор
      08.11.2023 16:59

      Могу сделать чуть попозже отдельную статью со сравнением как работает vSAN по tcp без RoCE и включенным RoCE. Я делал тест для себя, проверить, что все работает, но особо расширенных тестов не гонял.


  1. Xenos_rus
    08.11.2023 16:59
    +1

    За статью спасибо, но если бы лицензии VMware с vSAN покупались за деньги, то практически уверен, что статьи бы не состоялось :) Покритикую выбор решения: продуктив на проприетарой SDS без техподдержки вендора мне кажется миной замедленного действия. С учётом стоимости лицензии вполне можно рассматривать альтернативы в виде "железной" СХД и FC 16G или iSCSI 10-25G.


    1. All3 Автор
      08.11.2023 16:59

      На самом деле у нас есть лицензии на продукты VMware, но из-за того, что они ушли, нам не удалось продлить подписку. По поводу поддержки согласен.

      А по поводу критики выбора - она уместна. Но посчитав затраты на отдельное hba хранилище с резервированием, а резервное hba для нас существенно, получилось, что это решение вышло дешевле. Свитчи б/у, если что.


  1. NKulikov
    08.11.2023 16:59
    +1

    Я просто оставлю это тут RDG for VMware vSAN ESA over NVIDIA RoCE on VMware vSphere 8.0 Тут и как конфигурировать, и результаты тестов (советую смотреть не на финальные несколько графиков с лучшими сценариями, а на полные результаты)


    1. ildarz
      08.11.2023 16:59

      Там, к сожалению, тесты крайне малопоказательны, разве только как референс для пиковых значений по iops и псп.


      1. All3 Автор
        08.11.2023 16:59

        А еще там ошибка в настройке VDS. По крайней мере в скриптах ESXi 8.0.2 четко прописана проверка на nic teaming.