Proxy transparente de um único contêiner docker para outro contêiner docker

Eu tenho um par de contêineres docker em execução na máquina host, esses contêineres juntos fazem meu aplicativo cumprir. Portanto, para cada iteração/instância do meu aplicativo, é necessário executar um par de contêineres do docker. Até agora, estou usando o parâmetro --link ao executar o segundo contêiner para vincular o primeiro contêiner e obter o IP do primeiro contêiner do arquivo hosts para usá-lo programaticamente.

Agora, preciso configurar um proxy transparente para o segundo contêiner docker. assim, todo o tráfego http (porta 80) do segundo contêiner deve passar pela porta 8080 do primeiro contêiner.

Primeiro recipiente IP: 172.17.0.4 (Tem serviço de proxy em execução na porta 8080).Segundo recipiente IP: 172.17.0.6 (Tem ferramentas de cliente como navegador).Eu queria encaminhar todo o tráfego http (porta 80) do 172.17.0.6 para o porto 8080 do 172.17.0.4.

seja)> Tráfego para 80 de 172.17.0.4 <--- 8080 de 172.17.0.6

Tentei adicionar as regras iptables dentro do segundo contêiner para a configuração acima. Mas nenhum deles funcionou.

~# sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 172.17.0.4:8080

Não funciona.

~# sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 172.17.0.4:8080

Não funciona.

~# sudo iptables -t nat -A POSTROUTING -j MASQUERADE

Portanto, minha pergunta é: Como posso configurar um proxy transparente dentro de um contêiner docker que pode encaminhar todo o tráfego de uma porta especificada para a porta de outro contêiner?

P. S: Se eu adicionar manualmente as configurações de proxy ao navegador no segundo contêiner. Está funcionando bem. Mas eu queria definir o proxy transparente para todo o contêiner, não apenas o navegador. para que qualquer solicitação de rede de qualquer ferramenta dentro do segundo contêiner seja encaminhada para a porta proxy do primeiro contêiner.

Eu li alguns tutoriais sobre a proxy reversa de todos os contêineres em execução juntos usando nginx / HAProxy. Mas eu queria configurar o contêiner individual com seu próprio contêiner proxy como um par.

Obrigado a todos pelo seu tempo para responder. Basicamente, o que estou tentando fazer é proxy do saída / originado tráfego do 2º contêiner (NOTAR: Eu sou NAO tentando proxy do tráfego de entrada, portanto, não é possível usar o Apache mod_proxy ou Nginx proxy_pass. Esses módulos funcionam para o tráfego de entrada). O primeiro contêiner executa um serviço de proxy na porta 8080.

Como Thierno sugeriu, posso usar variáveis http_proxy e https_proxy ENV para proxy do tráfego de saída, mas infelizmente NAO todos os aplicativos/serviços em execução em seu sistema operacional respeitam essas variáveis http_proxy e https_proxy ENV. Existem aplicativos que forçam pular as configurações de proxy. Essa é a razão pela qual eu queria usar iptables para aplicar as regras de trânsito. Assim, nenhum do aplicativo / serviço pode pular o proxy.

O erro que fiz nas configurações anteriores sobre a questão é, eu estava tentando rotear o tráfego de entrada para a porta 80 para 8080 do servidor proxy. Como o primeiro contêiner não tem nenhum tráfego de entrada, ele não funcionará e é logicamente errado para PREROUTE / POSTROUTE o tráfego para conseguir o que eu estava procurando. Para rotear o tráfego originado / de saída, precisamos usar Corrente de saída dos iptables.

Minha Solução:

Eu usei RedSocks com a combinação iptables para impor o proxy para o tráfego de saída completo do servidor. Aqui está a configuração iptables que usei:

# Criar nova cadeia para RedSocks

root# iptables -t nat -N REDSOCKS

# Ignore LANs e alguns outros endereços reservados

root# iptables -t nat -A REDSOCKS -d 0.0.0.0/8 -j RETURNroot# iptables -t nat -A REDSOCKS -d 10.0.0.0/8 -j RETURNroot# iptables -t nat -A REDSOCKS -d 127.0.0.0/8 -j RETURNroot# iptables -t nat -A REDSOCKS -d 169.254.0.0/16 -j RETURNroot# iptables -t nat -A REDSOCKS -d 172.16.0.0/12 -j RETURNroot# iptables -t nat -A REDSOCKS -d 192.168.0.0/16 -j RETURNroot# iptables -t nat -A REDSOCKS -d 224.0.0.0/4 -j RETURNroot# iptables -t nat -A REDSOCKS -d 240.0.0.0/4 -j RETURN

# Redirecionar todo o http para redsocks porta local

root# sudo iptables -t nat -A REDSOCKS -p tcp --dport 80 -j REDIRECT --to-ports 12345

# para tráfego https basta substituir a porta 80 por 443

# Use toda a cadeia REDSOCKS para todo o tráfego de saída no eth0

root# sudo iptables -t nat -A OUTPUT -p tcp -o eth0 -j REDSOCKS

Agora, configure redsocks para ouvir a porta local 12345 para o tráfego de entrada e encaminhá-la para o IP e a porta do servidor proxy. Fazer editar redsocks.conf como assim,

redsocks {local_ip = 127.0.0.1;local_port = 12345;ip = 172.17.0.4;port = 8080;type = http-relay;}

basta salvar o conf e reinicie o serviço redsocks. Agora, todo o tráfego de saída originado do primeiro contêiner será aplicado para usar o proxy. (NOTAR: Eu usei iptables-persistente para persistir as regras sobre reinicializações do servidor) na verdade, implementei o mesmo para o tráfego http e https, adicionando outra linha à configuração iptables. Embora não seja um proxy transparente, ele faz o trabalho para mim.

Se alguém tiver outras soluções alternativas para isso, sugira.

Eu acho que usando o $http_proxy env var deve ajudar.

Você pode definir um ponto de entrada em seu arquivo docker (para o contêiner #2) para exportar o var env quando o contêiner estiver iniciando. Em algum lugar do seu ponto de entrada, você deve ter algo assim:

export http_proxy=http://$CONATAINER1_PORT_8080_TCP_ADDR:$CONATAINER1_PORT_8080_TCP_PORT

Não sei exatamente se o seu cliente (navegador) pode usar o $http_proxy env var, mas deve existir um método semelhante. Por exemplo, para firefox:

user_pref("network.proxy.http", "$CONATAINER1_PORT_8080_TCP_ADDR");user_pref("network.proxy.http_port", $CONATAINER1_PORT_8080_TCP_PORT);user_pref("network.proxy.type", 1);

Dica: usar printenv no segundo contêiner para saber qual nome de variáveis você deve usar em seu ponto de entrada

A vinculação recíproca não é algo que o docker tem, até onde eu sei (informações reveladas em tempo de execução sobre um contêiner de volta portado ou correspondido a um progenitor). É provavelmente por isso que a maioria dos tutoriais tem um terceiro ancestral comum,' proxy ' sendo usado.

Se você estiver disposto a usar frameworks como fig ou weave, que eu acredito ter arquivos de configuração yaml ou json, você provavelmente seria capaz de configurar isso com apenas dois contêineres recíprocos.

Se você estiver disposto a ter um terço, todas as portas e encanamentos podem ser vinculados por meio do ancestral comum para os dois contêineres "irmãos".