Я находился у заказчика в Келоуна, Британская Колумбия, Канада, устанавливая новое облако OpenStack. Развертывание было полностью автоматизировано: Cobbler выполнял установку OS на голое железо, осуществлял его начальную загрузку, а после этого принимался за дело Puppet. Я выполнял сценарий развертывания так много раз на практике, что считал само собой разумеющимся, что все успешно работало.
В мой последний день пребывания в Келоуне я был в конференц-связи из своего отеля. В фоновом режиме я дурачился в новом облаке. Я запустил экземпляр и зарегистрировался. Все выглядело великолепно. От скуки я запустил ps aux и внезапно все экземпляры заблокировались.
Полагая,что это разовая проблема, я завершил экземпляр и запустил новый. Затем моя конференц-связь завершилась и я уехал в центр обработки данных.
В центре я довел ряд задач и вспомнил про блокировку. Я вошел в новый экземпляр и снова запустил ps aux. Он работал. Уф. Я решил выполнить его еще раз. Он был заблокирован. Какого черта?
После данной воспроизведения несколько раз, я пришел к неутешительному убеждению, что в этом облаке действительно присутствует проблема. Даже хуже, мое пребывание в Келоуне закончилось, и я должен вернуться назад в Калгари.
Даже не понятно, где начинать поиск неисправности, похожей на эту. Экземпляр просто случайным образом блокируется при выполнении команды. Это какой-то образ? Не-а: это происходит с любыми образами. Это какой-то вычислительный узел? Не-а: это происходит со всеми узлами. Это блокируется какой-то экземпляр? Нет! Новые соединения SSH работают просто отлично!
Мы обратились за помощью. Инженер по сетевому обеспечению предположил, что это была проблема MTU. Великолепно! MTU! Какая- то зацепка! Что такое MTU и почему он может вызвать проблему?
MTU это максимальный размер передаваемого блока данных (maximum transmission unit). Он задает максимальное количество байт, которое интерфейс принимает для всех пакетов. Если два интерфейса имеют два различных MTU, байты могут отсекаться и могут происходить странные вещи — такие, как случайные зависания сессий.
Замечание | |
---|---|
Не все пакеты имеют размер 1500. Выполнение команды ls через SSH может создать только один пакет с размером, меньшим 1500 байт. Однако, выполнение команды с большим выводом результатов, например ps aux требует несколько пакетов по 1500 байт. |
Итак, откуда приходит проблема MTU? Почему мы не сталкивались с ней во всех остальных установках? Что нового в нашей ситуации? Ну, новый центр обработки данных, новая восходящая линия связи, новый коммутатор, новая модель коммутатора, новые серверы, первый случай использования этой модели сервера… так, почти все было в новинку. Мы повсюду игрались с повышением нашего MTU, в разных областях: в наших коммутаторах, в сетевых адаптерах вычислительных узлов, в виртуальных сетевых платах экземпляров, мы даже выполнили увеличение MTU центра обработки данных для восходящего интерфейса. Некоторые изменения работали, некоторые нет. Этот путь поиска неполадок не кажется верной, хотя… Мы не должны вносить изменения MTU в эти области..
В качестве крайнего средства, наш сетевой администратор (Альваро) и я сели с четырьмя терминальными окнами, карандашом и листом бумаги. В первом окне мы запустили ping. Во втором окне мы запустили tcpdump в контроллере облака. В третьем, tcpdump на вычислительном узле. А четвертое имело tcpdump в экземпляре. В качестве подоплеки, данное облако имело установку с большим числом узлов, без множества хостов.
Один контроллер облака работал в качестве шлюза для всех вычислительных узлов. Для настройки сети мы применяли VlanManager. Это означает, что контроллер облака и все вычислительные узлы имели различные VLAN для каждого проекта OpenStack. Мы применяли параметр -s в ping для изменения размера пакета. Мы наблюдали, что иногда пакеты полностью возвращались, иногда они только уходили и никогда не возвращались назад, а иногда пакеты останавливались в случайной точке. Мы изменили tcpdump, чтобы начать отображать шестнадцатеричный дамп пакетов. Мы выполняли ping между всеми комбинациями извне, с контроллера, с вычислительного узла и с экземпляра.
Наконец, Альваро заметил кое-что. Когда пакет извне достигает контроллера облака, он не должен быть настроен на работу с VLAN. Мы проверили, что это так. Когда отклик ping отправлялся из экземпляра, он должен быть в VLAN. Верно. Когда он возвращается в контроллер облака и на своем пути назад в общедоступный интернет он больше не должен иметь VLAN. Неверно. Ой-ой. Это выглядело так, будто не удаляется VLAN часть пакета.
Это не имело никакого смысла.
Пока мы гоняли эту мысль в наших головах туда-сюда, я случайным образом набирал команды на вычислительном узле:
$ ip a 10: vlan100@vlan20: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br100 state UP
"Эй, Альваро, аты можешь запустить VLAN поверх VLAN?"
"Если сделать это, то это добавит дополнительные 4 байта к пакету"
Тогда это все имело смысл…
$ grep vlan_interface /etc/nova/nova.conf vlan_interface=vlan20
В nova.conf
, vlan_interface
предписывает, что интерфейс OpenStack должен присоединять все VLAN.
Правильная установка должна выглядеть так:
vlan_interface=bond0
.
Поскольку это должен быть объединенный сетевой адаптер сервера.
vlan20 является VLAN, которую центр обработки данных предоставляет нам для восходящего доступа к общедоступному интернету. Это правильная VLAN и она также подключена к bond0.
По ошибке я настроил OpenStack подключать все VLAN владельцев на vlan20, вместо bond0, тем самым, упаковывая одну VLAN поверх другой, что добавляет дополнительные 4 байт к каждому пакету и дает в результате 1504 байта, которые должны быть отосланы,создавая проблемы по прибытию на интерфейс, который принимает только 1500!
Как только данный параметр был исправлен, все заработало.