Tenho lido sobre redes esta semana, mas ainda tenho uma lacuna aparentemente significativa no meu entendimento, relacionada a quais endereços IP são acessíveis a partir da minha máquina host e como.
Especificamente, ip -br addr
mostra:
lo UNKNOWN 127.0.0.1/8 ::1/128
tunl0@NONE DOWN
sit0@NONE DOWN
ip6tnl0@NONE DOWN
eth0@if15 UP 198.19.249.109/24 metric 1024 fd07:b51a:cc66:0:439:fcff:fe3f:27d6/64 fe80::439:fcff:fe3f:27d6/64
docker0 DOWN 172.17.0.1/16 fe80::acc7:7cff:fe73:5421/64
br-140e1fbca70a UP 172.18.0.1/16 fe80::34c3:10ff:fe55:2464/64
vethbf1bfcc@if5 UP fe80::38fd:c6ff:fe37:f54/64
veth7e8fb76@if5 UP fe80::689e:8bff:fe81:d8c3/64
E ip route
mostra:
default via 198.19.249.1 dev eth0 proto dhcp src 198.19.249.109 metric 1024
0.250.250.200 via 198.19.249.1 dev eth0 proto dhcp src 198.19.249.109 metric 1024
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
172.18.0.0/16 dev br-140e1fbca70a proto kernel scope link src 172.18.0.1
198.19.249.0/24 dev eth0 proto kernel scope link src 198.19.249.109 metric 1024
198.19.249.1 dev eth0 proto dhcp scope link src 198.19.249.109 metric 1024
E ip neigh
mostra:
198.19.249.1 dev eth0 lladdr da:9b:d0:54:e0:02 STALE
172.18.0.3 dev br-140e1fbca70a lladdr fe:50:d0:de:5a:ce STALE
fe80::d84c:3aff:fef1:e382 dev eth0 lladdr da:9b:d0:54:e0:02 router STALE
Além disso, docker network inspect ..._..._default
diz que a rede possui Gateway 172.18.0.1
, com dois contêineres conectados a ela, incluindo 172.18.0.3
.
iptables
contém apenas as regras padrão do Docker .
Pergunta :
Corri ip route del 172.18.0.0/16
e excluí essa entrada da tabela de roteamento.
Por que não consigo mais acessar o contêiner do Docker agora?
O 172.18.0.3
contêiner roda localmente na minha máquina, então eu esperava poder acessá-lo, se eu ajustasse as iptable
regras de alguma forma. Não é isso?
O contêiner roda como um "namespace de rede" separado. Embora esteja fisicamente na sua máquina, ele tem sua própria pilha de rede isolada – suas próprias interfaces, suas próprias rotas, seus próprios iptables, até mesmo seu próprio conceito de 'localhost' – para todos os efeitos, ele se comporta como se fosse uma máquina completamente separada do host.
(O kernel do host rastreia quais processos estão em qual namespace; ferramentas como
lsns
,unshare
ensenter
podem ser usadas para bisbilhotar.)A única interconexão entre esses dois namespaces é o par de interfaces 'veth', que atuam como duas extremidades de um cabo Ethernet virtual (elas são sempre criadas em pares e, então, uma é reatribuída ao namespace do contêiner, enquanto a outra permanece no lado do host).
O veth no lado do host pode ser conectado em ponte, ou não, da forma que você preferir – a ponte é para conveniência, é como conectar máquinas por meio de um switch em vez de conectá-las usando muitos cabos um para um – mas, de qualquer forma, endereços IP, máscaras de sub-rede e rotas devem ser configurados como se você estivesse de fato conectando máquinas separadas.
Então não, você não pode acessar esse endereço apenas ajustando as regras do iptables. Ele não tem nenhum caminho de atalho especial que teria efeito antes da tabela de roteamento (na verdade, o ponto inteiro dos namespaces de rede é que não haveria tal coisa), então se você não tiver uma rota para ele, você não pode enviar pacotes para ele.
No entanto, nem todos os contêineres têm namespaces assim; o Docker tem o modo "rede de host", que não usa um namespace de rede e o contêiner apenas compartilha o endereço IP do host.