Eae Galera!
Os comandos para definir o IP fixo no Docker só funcionam a partir da versão 1.10 do docker-engine
Esse post tem como objetivo mostrar os comandos necessários para administrar redes no Docker e como criar os seus containers com IP Fixo.
Bom, o Docker por padrão vem com uma bridge default em uma interface chamada docker0 que possui o range 172.17.0.0/16, quando são criados containers nessa rede, eles pegam o próximo endereço de IP que estiver disponível, porém quando o container é desligado e ligado, é realizado o mesmo processo, então os seus containers ficam com IPs dinâmicos impossibilitando configurações com IP Fixo, como por exemplo fazer o redirecionamento de um proxy reverso como no caso do Nginx para um container. Uma alternativa a isso seria o redirecionamento de portas, ou criar uma rede onde você possa definir o IP fixo para o container.
Para ver essa interface padrão do Docker, é só digitar a seguinte instrução:
ip a show dev docker0
4: docker0: mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:95:f1:d1:ef brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
Para fazer o redirecionamento de portas no Docker, você pode utilizar a instrução abaixo:
docker run -ti -p 1234:80 ubuntu /bin/bash
Com essa instrução foi criado um novo container e a porta 1234 do host foi redirecionada para a porta 80 do container, então quando acessarmos http://localhost:1234 você na verdade vai acessar o seu container na porta 80.
Parece ser uma coisa de outro mundo, mas na verdade isso nada mais é do que uma regra de iptables.
Para provar isso você pode executar a seguinte instrução:
iptables -t nat -L -n
E a saída será parecida com essa:
Chain DOCKER (2 references)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:1234 to:172.17.0.2:80
Na saída do comando é possível ver que existe uma regra de DNAT que faz o redirect da porta 1234 para a porta 80 do ip 172.17.0.2 do container.
Uma vez que o container estiver sendo executado você pode ir criado novas regras de iptables e ir direcionando as portas.
Para criar um novo redirecionamento você pode criar uma regra da seguinte maneira:
iptables -t nat -A DOCKER -s 0.0.0.0/0 -d 0.0.0.0/0 -p tcp --dport 6543 -j DNAT --to 172.17.0.2:6543
Assim foi redirecionada a porta 6543 do host para a porta 6543 do container cujo o ip é igual a 172.17.0.2.
Então se eu listar as regras novamente é possível ver que a nova regra foi adicionada:
iptables -t nat -L -n
Chain DOCKER (2 references)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:1234 to:172.17.0.2:1234
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:6543 to:172.17.0.2:6543
Bom, agora indo para a parte de gerenciamento de redes no Docker.
Para visualizar as redes existentes no Docker é necessário executar a seguinte instrução:
docker network ls
NETWORK ID NAME DRIVER
557d5241a110 bridge bridge
44426ff59dfd none null
1deb1bfeca8e host host
A saída do comando será parecida com a saída acima.
Para ver informações sobre uma rede em específico, você pode executar a instrução abaixo:
docker network inspect bridge
O retorno será um json parecido com esse:
[
{
"Name": "bridge",
"Id": "557d5241a110cc126b6974776036f45fc13a7bbbd471c57e3bd88a53227c596e",
"Scope": "local",
"Driver": "bridge",
"IPAM": {
"Driver": "default",
"Config": [
{
"Subnet": "172.17.0.0/16"
}
]
},
"Containers": {
"8ec3bd237a51362c34e932036f0f84144cc495f3e620164168d088150a26347c": {
"EndpointID": "dd129bd3e4cb30d5ad275b57d60b851817c09b573460351a2ff61e8de527aefb",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
}
}
]
Para criar a sua própria rede você precisa de dois parâmetros, o primeiro é o nome da rede o segundo é a rede em notação CIDR para que o Docker saiba o tamanho da rede.
Assim você pode executar a seguinte instrução:
docker network create --subnet 172.18.0.0/16 rede_teste
Após executado o comando será retornado o ID da rede, agora você pode criar nessa rede os containers com IP fixo.
A instrução abaixo vai criar um container nessa rede e definir o ip 172.18.0.43 para o container, vou passar também um parâmetro --always=True, assim quando o Docker for reiniciado o container sempre será iniciado junto com o Docker.
docker run -ti --net rede_teste --ip 172.18.0.43 --always=true ubuntu /bin/bash
Agora você tem um container sendo executado com IP fixo.
Caso você não precise mais da rede é só deletada com a instrução abaixo:
docker network rm rede_teste
Valeu!