Premissa:
Estou tentando reunir o aprendizado recente sobre interfaces e portas de rede e tentar vincular esse novo aprendizado ao Docker.
Um resumo rápido das coisas que aprendi relevantes para esta pergunta:
- Cada computador pode ter vários endereços IP, um para cada interface de rede.
- Os endereços IP são atribuídos a interfaces, não a computadores, etc.
- Um soquete é uma porta IP+.
- O DHCP é frequentemente/provavelmente o que atribui um endereço IP a uma interface.
Assim como em muitos aspectos do trabalho com software, primeiro faço as coisas de acordo com o "ritual" que aprendo, porque "é assim que se faz". Então, com o tempo e a experiência, começo a ponderar e investigar os porquês. Então, eu gostaria de amarrar esse novo aprendizado com o Docker.
O "ritual" que aprendi é que, se um aplicativo em contêiner estiver ouvindo em um soquete TCP, você precisa "expor" a porta desse soquete para que o tráfego que chega a uma das interfaces do host nessa porta seja "encaminhado" para o recipiente.
Por exemplo docker run -d -p 81:80 httpd
, configura as coisas para que, se eu apontar meu navegador da Web para 127.0.0.81, esse tráfego HTTP/TCP/IP seja "encaminhado" para a porta 80 do contêiner httpd .
Então, quando eu aponto meu navegador da web para 127.0.0.1:81, vejo a mensagem "Funciona!" mensagem.
Mas também: se eu apontar meu navegador para 127.0.0. 2:81 ou 127.0.0 . 16 :81, então também vejo o "Funciona!" mensagem.
Como aprendi com as postagens vinculadas, o DHCP atribuiu à interface da minha NIC o endereço IP 10.0.0.17 e, se eu apontar meu navegador para 10.0.0.17:81, aqui novamente, vejo o "Funciona!" do Apache! mensagem.
Também funciona se eu apontar o navegador da web de outro PC na mesma rede para 10.0.0.17:81.
Pergunta:
Minha pergunta principal é: para qual das interfaces do PC host (endereços IP) as portas são encaminhadas do host para o contêiner quando você faz docker run
com o -p
argumento? Pela observação observada, a resposta parece ser "todas as interfaces" - é esse o caso?
Mais amplamente, porém: qual é a relação entre interfaces e portas entre um PC host e o contêiner Docker?
O que eu tentei
Eu tentei ler o docker run
texto de ajuda, mas seu texto -p
não está em um nível que eu possa relacioná-lo com as perguntas que estou fazendo:
-p, --publish list Publica a(s) porta(s) de um contêiner no host
Eu tentei executar olhando no ifconfig
contexto do meu PC e o contêiner httpd em execução.
ifconfig
no PC host:
$ ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:caff:fe23:f0f4 prefixlen 64 scopeid 0x20<link>
ether 02:42:ca:23:f0:f4 txqueuelen 0 (Ethernet)
RX packets 3079 bytes 322688 (322.6 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 6429 bytes 15942682 (15.9 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 17975 bytes 1557651 (1.5 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 17975 bytes 1557651 (1.5 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
wlp1s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.17 netmask 255.255.255.0 broadcast 10.0.0.255
inet6 fe80::5f8c:c301:a6a3:6e35 prefixlen 64 scopeid 0x20<link>
ether f8:59:71:01:89:cf txqueuelen 1000 (Ethernet)
RX packets 1672559 bytes 2237440808 (2.2 GB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 726083 bytes 113598143 (113.5 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ifconfig
no contêiner httpd em execução (instalei-o com apt-get
):
# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet)
RX packets 1326 bytes 8916833 (8.5 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1134 bytes 76866 (75.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Colocando essa questão no contexto da ifconfig
saída acima, qual é a relação entre essas interfaces no PC host e as interfaces no contêiner docker?
A partir daqui , meu entendimento é que o DHCP atribuiu 10.0.0.17 à NIC no meu PC host. Mas de onde vem o 172.17.0.3?
[NB: Você parece ter três perguntas aqui, pelo menos uma das quais é muito ampla para ter uma resposta clara e aceitável. Geralmente, o SuperUser funciona melhor se você fizer apenas uma pergunta definida por postagem de pergunta.]
Sim.
Isso é um pouco amplo demais para responder bem sem apontar para a documentação de rede do Docker. O Docker contém muitas opções de rede diferentes que alteram as relações entre interfaces e portas entre PCs host e contêineres do Docker. É muito flexível.
O modo de rede padrão do Docker, bridge networking , cria uma ponte de software (como um switch Ethernet virtual) no host e conecta os contêineres a ele por meio de interfaces de rede virtual. Como uma pequena LAN Ethernet virtual, tudo dentro do host. Em seguida, ele usa NAT (como um roteador de gateway doméstico usaria) para permitir que seus contêineres alcancem a rede além do host. O NAT usa a sub-rede 172.17.0.0/16 como sua sub-rede privada.
O Docker usa essa sub-rede porque ela faz parte do espaço de endereço privado RFC 1918, assim como 192.168.0.0/16, 10.0.0.0/8 e o restante de 172. 16 .0.0/ 12 .
Parece que o Docker configura programaticamente os contêineres com endereços estáticos nessa sub-rede (o DHCP complicaria desnecessariamente as coisas).