Encaminhar conexões para uma máquina virtual em um contêiner docker

1

O que estou tentando alcançar

No trabalho, usamos um sistema operacional específico, que nós (os desenvolvedores) executamos no VirtualBox. O sistema operacional virtualizado está executando o servidor Samba e o rsh que usamos para acessar o sistema operacional. Além disso, o sistema operacional virtualizado precisa de acesso a vários servidores em nossa rede.

O que eu gostaria de alcançar é ter uma maneira de iniciar rapidamente as máquinas virtuais como parte da configuração do Docker. A idéia é ter um contêiner docker que forneça acesso à máquina virtual, um contêiner que executa testes na máquina virtual e, no futuro, alguns outros contêineres que fornecem, por exemplo. análise do sistema.

Qual é o problema

Eu tenho um contêiner docker que configura uma máquina VirtualBox com rede em ponte. Eu posso acessar a máquina virtual usando rsh do contêiner que a iniciou sem problemas. No entanto, não consigo acessar a máquina virtual usando o rsh de outros containers (bem, eu encontrei uma solução que descreverei abaixo, mas eu não acho que seja uma boa). Curiosamente, o ping funciona bem.

Neste momento, a configuração é assim:

Contêiner virtual

  • o contêiner do Docker que contém a máquina virtual
  • endereço IP: 172.18.0.5
  • Gateway: 172.18.0.1
  • Netmask: 255.255.0.0

Máquina VirtualBox

  • em execução dentro do Virtual container
  • endereço IP: 172.18.1.5
  • Gateway: 172.18.0.1
  • Netmask: 255.255.0.0

Contêiner de trabalho

  • um container que gostaria de conectar à máquina do VirtualBox
  • endereço IP: 172.18.0.6
  • Gateway: 172.18.0.1
  • Netmask: 255.255.0.0

Até agora eu encontrei apenas uma solução sobre como conectar usando o rsh à máquina do VirtualBox, e isso é adicionar uma rota:

ip route add 172.18.1.5 via 172.18.0.5

E depois rsh para 172.18.1.5. No entanto, isso tem um problema sério. Como preciso saber o endereço atribuído à máquina virtual, devo definir o endereço da caixa virtual como um endereço que possa ser facilmente adivinhado a partir do endereço do contêiner em que ele está sendo executado. Alterar a rota dentro do contêiner também significa que o contêiner precisa estar privilegiado, e gostaria de manter o número de contentores privilegiados ao mínimo.

O que eu gostaria muito mais é poder rsh para o contêiner Virtual (172.18.0.5) diretamente. Dessa forma eu não teria que adivinhar o IP da máquina virtual, mas eu poderia usar o hostname de Virtual graças ao docker-compose.

Eu achei que poderia usar NAT para conseguir isso. O que eu fiz foi:

  • altere o gateway da máquina virtualbox para o endereço IP Virtual
  • expor todas as portas de Virtual
  • adicione as duas regras a seguir ao contêiner Virtual :
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

No entanto, parece não funcionar de todo. Nota: Eu não me importo se todas as portas são encaminhador ou não. Obviamente, seria melhor ou encaminhar apenas o rsh e o Samba, mas o rsh é problemático devido ao servidor selecionar a porta para comunicação semelhante ao FTP passivo.

Alguma idéia do que estou fazendo de errado ou de que outra forma eu posso alcançar meu objetivo?

Atualizar

O conteúdo da tabela nat do iptables:

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

Além disso, instalei o wireshark no container e acho que o problema é que existe um ciclo causado pelas regras do iptables.

Posso ver que os pacotes de 172.18.0.6 a 172.18.0.5 são enviados para 172.18.1.5, o que está correto. Além disso, as respostas de 172.18.1.5 têm o endereço de origem traduzido para 172.18.0.5 e, em seguida, são enviadas para 172.18.0.6, o que também é correto. No entanto, há uma conexão de 172.18.1.5 a 172.18.0.5. Acho que aí está o problema, já que a conexão deveria ser para 172.18.0.6. No entanto, não sei como garantir que o virtual saiba o endereço correto para se conectar.

Atualização 2

Agora que estou pensando nisso, a DNAT não deve deixar o endereço de origem inalterado? De acordo com o wireshark, ele é alterado para o endereço Virtual . Por isso, não é de admirar que a máquina virtual crie uma conexão com Virtual em vez de Worker .

    
por stativ 23.09.2017 / 21:19

1 resposta

0

Portanto, a solução é incrivelmente simples:

Mova o Virtual para outra sub-rede e defina seu gateway para o IP do Container

É isso. As regras de NAT mencionadas na pergunta estão corretas.

Como o Trabalhador e o Virtual estavam na mesma sub-rede, o Virtual conectou diretamente ao Trabalhador ao criar a conexão com Trabalhador que o RSH usa, ignorando, assim, o NAT.

Infelizmente, cometi mais um erro ao depurar este problema usando o wireshark. Sendo tão sem esperança, mudei as regras do iptables para:

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

Com essas regras, pareceu funcionar parcialmente, porque de repente o Container se tornou a fonte que fez o handshake inicial funcionar. No entanto, ele quebrou a conexão RSH de Virtual , já que as informações de que a conexão original estava vindo de Worker já estavam perdidas.

    
por 27.09.2017 / 09:40