В настоящее время у меня Docker работает на нескольких виртуальных машинах, размещенных в OpenStack.
При попытке выполнить HTTP-запросы из контейнеров на этих машинах, запрос почти всегда зависает в ожидании ответа. При выполнении запросов HTTPS время ожидания запроса неизменно истекает, поскольку не удается завершить рукопожатие TLS. В любом случае кажется, что запросы завершаются ошибкой после получения пары сотен байтов данных ответа (если есть). Те же запросы выполняются без каких-либо проблем с хост-машины (т.е. проблема не в брандмауэре уровня хоста).
Я наткнулся на этот (и некоторые связанные сообщения в блоге), которые предполагают, что это может быть связано с тем, что сетевой мост Docker имеет другой MTU по сравнению с сетевым интерфейсом хоста, но я проверил, что оба MTU одинаковы (1500 байт в каждом случае). Я также пробовал поиграть с --mtu
переключиться на демон Docker, чтобы посмотреть, смогу ли я заставить его работать, но безуспешно.
Я также встречал несколько похожих случаев, которые предполагают, что это может быть связано с разгрузкой контрольной суммы TCP и / или сегментации (например, Вот), но никаких возиться с ethtool -K {interface} tx off rx off
или аналогичный дают любой положительный результат.
Поведение кажется специфичным для сетевого моста - использование --net=host
когда запуск контейнеров действительно решает проблему. Однако по соображениям безопасности я не хочу использовать этот обходной путь в нашей производственной системе.
Также обратите внимание, что та же самая настройка (та же версия Docker, те же параметры конфигурации) отлично работает на моей машине разработки или при запуске на экземпляре, размещенном в AWS - в чем бы ни заключалась проблема, похоже, она проявляется только при работе под OpenStack.
Для справки я использую следующую команду для тестирования:
docker run -it alpine:3.3 wget http://ipv4.download.thinkbroadband.com/5MB.zip
Это должно (теоретически) загрузить тестовый файл размером 5 МБ при запуске. Однако wget
команда просто зависает. Также, вероятно, стоит отметить, что проблема не в гостевой ОС - использование образа Ubuntu (например) по-прежнему демонстрирует такое же поведение.
Мы с коллегой также провели несколько тестов по передаче файлов с помощью netcat. В этих тестах мы смогли успешно передать файлы из контейнера на наш тестовый сервер, но попытка передачи в обратном направлении не удалась. Мы также использовали tcpdump
для регистрации сетевой активности во время этих тестов - во время неудачных тестов в журналах было показано, что некоторые пакеты были получены, но значительно меньше, чем ожидалось.
Также, если это актуально, вот вывод docker version
в рассматриваемой системе:
Client:
Version: 1.12.1
API version: 1.24
Go version: go1.6.3
Git commit: 23cf638
Built: Thu Aug 18 05:22:43 2016
OS/Arch: linux/amd64
Server:
Version: 1.12.1
API version: 1.24
Go version: go1.6.3
Git commit: 23cf638
Built: Thu Aug 18 05:22:43 2016
OS/Arch: linux/amd64
Выход uname -a
на хосте выглядит следующим образом:
Linux docker-builder-1 4.4.0-38-generic #57~14.04.1-Ubuntu SMP Tue Sep 6 17:20:43 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
ОБНОВИТЬ
Оказывается, все работает, как ожидалось, если Docker размещен в образе Ubuntu 16.04.
На этом этапе я могу двигаться дальше, перестроив все свои виртуальные машины для использования образа Ubuntu 16.04, но я все еще не знаю, в чем заключалась исходная проблема. Мне все еще интересно услышать какие-либо предложения относительно того, в чем была причина исходной проблемы и как ее исправить.
Адаптируйте флаг MTU dockerd к MTU вашей виртуальной машины.
Одна из ОС моего экземпляра OpenStack - ubuntu16.04.
ifconfig
(1450 в моем случае)cp /lib/systemd/system/docker.service /etc/systemd/system/docker.service
vi /etc/systemd/system/docker.service
ExecStart=/usr/bin/docker daemon -H fd:// --mtu 1450
systemctl daemon-reload
service docker restart