Назад | Перейти на главную страницу

Перенаправить подключения к виртуальной машине в контейнере докера

Чего я пытаюсь достичь

На работе мы используем определенную операционную систему, которую мы (разработчики) запускаем в виртуальном боксе. Виртуализированная ОС работает под управлением сервера Samba и rsh, который мы используем для доступа к ОС. Кроме того, виртуализированной ОС требуется доступ к нескольким серверам в нашей сети.

Я хотел бы получить способ быстро запускать виртуальные машины как часть установки Docker. Идея состоит в том, чтобы иметь контейнер докеров, который будет предоставлять доступ к виртуальной машине, контейнер, который запускает тесты на виртуальной машине, и в будущем некоторые другие контейнеры, которые будут предоставлять, например. анализ системы.

В чем проблема

У меня есть контейнер докеров, который настраивает машину VirtualBox с мостовой сетью. Я могу без проблем получить доступ к виртуальной машине с помощью rsh из контейнера, который ее запустил. Однако я не могу получить доступ к виртуальной машине с помощью rsh из других контейнеров (ну, я нашел решение, которое опишу ниже, но я не думаю, что оно хорошее). Что интересно, ping работает нормально.

Сейчас настройка выглядит так:

Виртуальный контейнер

VirtualBox машина

Рабочий контейнер

Пока что я нашел только одно решение о том, как подключиться с помощью rsh к машине VirtualBox, и это добавить маршрут:

ip route add 172.18.1.5 via 172.18.0.5

И затем rsh на 172.18.1.5. Однако здесь есть одна серьезная проблема. Поскольку мне нужно знать адрес, назначенный виртуальной машине, я должен установить адрес виртуального ящика на адрес, который можно легко угадать по адресу контейнера, в котором он работает. Изменение маршрута в контейнере также означает, что контейнер должен быть привилегированный, и я хотел бы свести количество привилегированных контейнеров к минимуму.

Чего бы я хотел больше, так это иметь возможность rsh в Виртуальный контейнер (172.18.0.5) напрямую. Таким образом, мне не пришлось бы угадывать IP-адрес виртуальной машины, но я мог бы использовать имя хоста Виртуальный благодаря docker-compose.

Я думал, что могу использовать NAT для этого. Я сделал следующее:

iptables -t nat -A PREROUTING --destination 172.18.0.5 -j DNAT --to-destination 172.18.1.5
iptables -t nat -A POSTROUTING --source 172.18.1.5 -j SNAT --to-source 172.18.0.5

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

Есть идеи, что я делаю неправильно или как еще я могу достичь своей цели?

Обновить

Содержимое таблицы iptables nat:

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       all  --  anywhere             4f04152f8562         to:172.18.1.5

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DOCKER_OUTPUT  all  --  anywhere             127.0.0.11          

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
DOCKER_POSTROUTING  all  --  anywhere             127.0.0.11          
SNAT       all  --  anywhere             anywhere             to:172.18.0.5

Chain DOCKER_OUTPUT (1 references)
target     prot opt source               destination         
DNAT       tcp  --  anywhere             127.0.0.11           tcp dpt:domain to:127.0.0.11:43467
DNAT       udp  --  anywhere             127.0.0.11           udp dpt:domain to:127.0.0.11:39285

Chain DOCKER_POSTROUTING (1 references)
target     prot opt source               destination         
SNAT       tcp  --  127.0.0.11           anywhere             tcp spt:43467 to::53
SNAT       udp  --  127.0.0.11           anywhere             udp spt:39285 to::53A

Кроме того, я установил в контейнер wirehark и думаю, проблема в том, что существует цикл, вызванный правилами iptables.

Я вижу, что пакеты с 172.18.0.6 по 172.18.0.5 отправляются на 172.18.1.5, так что это правильно. Кроме того, в ответах от 172.18.1.5 адрес источника переведен на 172.18.0.5, а затем они отправляются на 172.18.0.6, что тоже правильно. Однако тогда есть соединение с 172.18.1.5 на 172.18.0.5. Думаю, в этом проблема, так как подключение должно быть на 172.18.0.6. Однако я не знаю, как убедиться, что виртуальный компьютер знает правильный адрес для подключения.

Обновление 2

Теперь, когда я думаю об этом - разве DNAT не должен оставлять исходный адрес неизменным? Согласно wirehark он изменен на адрес Виртуальный. Поэтому неудивительно, что виртуальная машина подключается к Виртуальный вместо того Рабочий.

Итак, решение невероятно простое:

Переместите Виртуальный в другую подсеть и установите его шлюз на IP-адрес Контейнер

Вот и все. Правила NAT, упомянутые в вопросе, верны.

Поскольку Рабочий и Виртуальный находились в одной подсети, Виртуальный подключен к Рабочий непосредственно при создании подключения к Рабочий который использует RSH, таким образом обходя NAT.


К сожалению, при отладке этой проблемы с помощью wirehark я сделал еще одну ошибку. Будучи настолько безнадежным, я изменил правила iptables на:

-t nat -A PREROUTING -j DNAT --to-destination 172.18.1.5
-t nat -A POSTROUTING -j SNAT --to-source 172.18.0.5

С такими правилами вроде бы частично работало, потому что внезапно Контейнер стал источником, благодаря которому начальное рукопожатие сработало. Однако он прервал соединение RSH с Виртуальный поскольку информация о том, что исходное соединение исходило от Рабочий было уже потеряно.