Flannel+Etcd+Docker – Como criar e configurar uma sub-rede para fazer a comunicação entre containers Docker utilizando o Flannel

O objetivo deste tutorial é criar uma sub-rede utilizando o Flannel para fazer a comunicação entre os containers e consecutivamente entre aplicações, bancos de dados e etc.
E tem mais, se você vai criar um cluster com Kubernetes, CoreOS ou Docker Swarm+Compose é fundamental ter uma sub-rede para comunicação, e o Flannel é uma excelente opção; para não dizer a melhor.

Rede-Flannel

1. Introdução

Flannel é uma rede virtual (overlay network) utilizada para provisionar uma sub-rede para cada host do cluster; no nosso caso são hosts Docker.
Esta sub-rede vai permitir a alocação de ips para os containeres da rede.
O objetivo ao utilizar uma rede com Flannel é fazer a comunicação entre os containeres.

Quando você instala o Docker ele cria uma rede interna isolada, geralmente é uma rede 172.17.X.X. Se você tiver outros hosts Docker na rede os containeres não conseguirão se comunicar, por isto que precisamos do Flannel.

O Flannel utiliza como backend o Etcd para fazer o armazenamento das informações de rede. O Etcd é um sistema distribuído de armazenamento do tipo key=valor.

Então neste tutorial vamos utilizar o Flannel para fazer a comunição entre os containeres e o Etcd para o armazenamento das informações de rede.

2. Infraestrutura e pré-requisitos

Pré-requisitos.
* Docker instalado. Se preferir pode seguir este tutorial de instalação do Docker.
* 1 servidor para o Etcd.
* X servidores rodando o Docker. X são quantos hosts Docker você quiser.
* Sistema Operacional Centos 7 X86_64.

Infraestrutura deste Lab.

Etcd
etcd-01.devopslab.com.br

Hosts Docker
docker-engine-01.devopslab.com.br
docker-engine-02.devopslab.com.br
docker-engine-03.devopslab.com.br

3. Instalação do Etcd e definição de rede

Instalar o Etcd é fácil, você precisa apenas ter o repositório “extras” ativo no seu CentOS 7. O repositório extras já vem configurado mas de qualquer forma segue abaixo.

#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

Instalação do Etcd.

# yum install etcd

Altere o Bind do etcd para 0.0.0.0. Segue meu arquivo de configuração do etcd.

# cat /etc/etcd/etcd.conf |grep -v ^#

ETCD_NAME=default
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379"

Habilite o startup e inicie o Etcd.

systemctl enable etcd.service
systemctl start.service

Libera a porta 2379/tcp no firewall.

# firewall-cmd –add-port=2379/tcp
# firewall-cmd --permanent --add-port=2379/tcp

3.1 – Definição de rede

Crie um arquivo .json em qualquer pasta e defina sua rede.
#vi flannel-config.json

{
    "Network": "10.0.0.0/16",
    "SubnetLen": 24,
    "Backend": {
        "Type": "vxlan",
        "VNI": 1
     }
}

Agora crie uma chave (key=valor) no etcd com as informações da rede.

# etcdctl set /redeinternadevopslab.com.br/network/config < flannel-config.json

Key – /redeinternadevopslab.com.br/network/config
Valor – Conteúdo do arquivo flannel-config.json

Faça um “get” para verificar a criação da key=valor.

# etcdctl get /redeinternadevopslab.com.br/network/config
{
    "Network": "10.0.0.0/16",
    "SubnetLen": 24,
    "Backend": {
        "Type": "vxlan",
        "VNI": 1
     }
}

Seu Etcd já está com a rede definida, o próximo passo é configurar o Flannel nos clientes.

4. Instalação e configuração do Flannel nos hosts Docker

Agora precisamos instalar o agente Flannel em todos os hosts Docker. O repositório é o “extras”, o mesmo utilizado na instalação do Etcd, que provavelmente já exista no seu Centos 7.

# yum install flannel

Configuração do Flannel.
Edite o arquivo “/etc/sysconfig/flanneld” e altere as variáveis
FLANNEL_ETCD = Servidor do Etcd.
FLANNEL_ETCD_KEY = Key definida no Etcd.

Segue meu arquivo.

# cat  /etc/sysconfig/flanneld | grep -v ^#
FLANNEL_ETCD="http://etcd-01.devopslab.com.br:2379"
FLANNEL_ETCD_KEY="/redeinternadevopslab.com.br/network"

Habilite o startup e inicie o Flanneld.

# systemctl enable flanneld
# systemctl start flanneld

Se tudo correu bem, você vai ter uma nova interface de rede no seu host.

# ip addr | grep flannel
4: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN 
    inet 10.0.82.0/16 scope global flannel.1

Verifique se foi criado o arquivo “/run/flannel/subnet.env”, pois nele consta as definições de rede que serão cosultadas pelo Docker.

# cat /run/flannel/subnet.env 
FLANNEL_NETWORK=10.0.0.0/16
FLANNEL_SUBNET=10.0.82.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=false

4.1 – Configuração do Docker para a utilização do Flannel

Vamos editar o arquivo de definição do serviço Docker e informar para utilizar a rede Flannel.
Você pode consultar o arquivo docker.service com o comando “systemctl status docker”.
O que precisa ser alterado são estes 2 campos:
EnvironmentFile=-/run/flannel/subnet.env

ExecStart=/usr/bin/docker daemon -H fd:// $OPTIONS $DOCKER_STORAGE_OPTIONS –bip=${FLANNEL_SUBNET} –mtu=${FLANNEL_MTU}

Segue meu arquivo “/usr/lib/systemd/system/docker.service”.
# cat /usr/lib/systemd/system/docker.service

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network.target docker.socket
Requires=docker.socket

[Service]
Type=notify
EnvironmentFile=-/run/flannel/subnet.env
ExecStart=/usr/bin/docker daemon -H fd:// $OPTIONS $DOCKER_STORAGE_OPTIONS --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU}
MountFlags=slave
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target

Agora reinicie o Docker para ele pegar a nova rede.

# systemctl restart docker

Eu tive que reiniciar o Docker umas 3 ou 4 vezes para ele assumir a nova rede.
Ou se você preferir reinicie todo o host Docker.

# ip addr | grep docker
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN 
    inet 10.0.82.1/24 scope global docker0

Veja que agora existe a internface “docker0“.

5. Teste de comunicação entre containeres

Com o Flannel configurado, crie alguns containeres em hosts diferentes e faça teste de ping e telnet.
Cuidado com Firewall ativo nos hosts Docker pois pode bloquear sua comunicação. Crie as regras de Firewall ou simplesmente desative.

Teste 1.
Origem
Host Docker 1: 10.0.2.201
Container 1: 10.0.82.2

Destino:
Host Docker 2: 10.0.2.202
Container 2: 10.0.24.3

root@31bf8abfa529:/# ip a l eth0| grep inet' '
    inet 10.0.82.2/24 scope global eth0

root@31bf8abfa529:/# ping 10.0.24.3
PING 10.0.24.3 (10.0.24.3) 56(84) bytes of data.
64 bytes from 10.0.24.3: icmp_seq=1 ttl=62 time=6.25 ms
64 bytes from 10.0.24.3: icmp_seq=2 ttl=62 time=0.810 ms
64 bytes from 10.0.24.3: icmp_seq=3 ttl=62 time=1.72 ms

Teste 2.
Origem
Host Docker 2: 10.0.2.202
Container 2: 10.0.24.3

Destino:
Host Docker 1: 10.0.2.201
Container 1: 10.0.82.2

root@8b43f759f5d2:/# ip a l eth0| grep inet' '
    inet 10.0.24.3/24 scope global eth0

root@8b43f759f5d2:/# ping 10.0.82.2
PING 10.0.82.2 (10.0.82.2) 56(84) bytes of data.
64 bytes from 10.0.82.2: icmp_seq=1 ttl=62 time=4.77 ms
64 bytes from 10.0.82.2: icmp_seq=2 ttl=62 time=1.11 ms
64 bytes from 10.0.82.2: icmp_seq=3 ttl=62 time=1.18 ms

Teste 3.
Origem:
Host Docker 3: 10.0.2.203
Container 3: 10.0.81.3

Destino:
Host Docker 1: 10.0.2.201
Container 1: 10.0.82.2

root@c9c0a823ddf0:/# ip a l eth0| grep inet' '
    inet 10.0.81.3/24 scope global eth0

root@c9c0a823ddf0:/# ping 10.0.82.2
PING 10.0.82.2 (10.0.82.2) 56(84) bytes of data.
64 bytes from 10.0.82.2: icmp_seq=1 ttl=62 time=1.79 ms
64 bytes from 10.0.82.2: icmp_seq=2 ttl=62 time=1.15 ms
64 bytes from 10.0.82.2: icmp_seq=3 ttl=62 time=1.17 ms

Pronto! A comunicação entre seus containeres está funcionando, as aplicações vão alcançar umas às outras e sucesso.

Qualquer coisa estamos aí.

Leonardo Macedo Cerqueira

2 comentários sobre “Flannel+Etcd+Docker – Como criar e configurar uma sub-rede para fazer a comunicação entre containers Docker utilizando o Flannel

  1. Ótimo post. Você sabe como fazer o mesmo procedimento no Debian? Estou precisando com urgencia fazer conteiners docker se comunicarem em rede. Estou utilizando Docker 1.7 (estou rodando os conteineres Docker em dispositivos ARM BPI M2, por isso nao consigo utilizar um docker mais atual).

  2. David,

    Basta você ver como instalar o etcd e flannel no Debian, o restante são apenas linhas de comandos e arquivos de configurações.
    Até o Systemd tem no Debian 8, o que deixa o Debian ainda mais parecido com um Red-Hat/Centos ou vice e versa.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *