Descoberta de serviço DNS usando o Consul no Docker Swarm

2

Estou tentando fazer com que a descoberta de serviço funcione usando o DNS consul. Eu configurei um docker swarm com um cluster cônsul funcionando como o backend de par chave / valor requerido pelo swarm, bem como funcionando como o backend de descoberta de serviço para os outros containers.

Eu começo com 3 servidores vazios com o mecanismo docker instalado. Estou provisionando o cluster usando ansible.

O processo para configurar este cluster até agora é:

  • Ao instalar o docker, defina --cluster-store=consul://127.0.0.1:8500 no daemon do estivador opte
  • No nó do cluster "principal", inicie um contêiner de servidor consul em "-bootstrap -experte 3" mode
  • Nos nós de cluster "secundários", inicie um contêiner do servidor consul no modo "-join"
  • Iniciar um container swarm master e swarm agent em cada nó do cluster, apontando para o servidor consul local no mesmo host

Ao iniciar os servidores consul estou mapeando todas as portas consul para o host, assim:

version: '2'

services:
    consul:
        image: progrium/consul
        hostname: "{{ ansible_hostname }}"
        ports:
            # Explanation of ports needed: http://stackoverflow.com/a/30692226/1514089
            - "8300:8300" # This is used by servers to handle incoming requests from other agents
            - "8301:8301/tcp" # This is used to handle gossip in the LAN. Required by all agents
            - "8301:8301/udp" # This is used to handle gossip in the LAN. Required by all agents
            - "8302:8302/tcp" # This is used by servers to gossip over the WAN to other servers
            - "8302:8302/udp" # This is used by servers to gossip over the WAN to other servers
            - "8400:8400" # This is used by all agents to handle RPC from the CLI
            - "8500:8500" # This is used by clients to talk to the HTTP API
            - "8600:8600" # Used to resolve DNS queries
         restart: always
         command: "{{ consul_command }}"

Isso me faz um enxame de janela de trabalho. Eu posso logar em qualquer um dos nós do cluster e usar o docker para compor uma aplicação, o swarm equilibra as coisas nos servidores de forma transparente.

Agora, porém, quero começar a usar os recursos de DNS do consuls para resolver serviços de dentro de cada contêiner do enxame. Quero fazer isso:

$ docker run -it ubuntu dig consul.service.consul

Eu tentei algumas coisas, mas não consegui fazê-lo funcionar, suspeito que tenha algo a ver com as redes docker. Deixe-me explicar ...

Quando inicio os servidores consulares, eles são anexados à sua própria rede docker-compose, já que os inicio com o docker-compose. No entanto, como o enxame ainda não está operacional, obviamente não há redes de sobreposição de vários hosts configuradas. Assim, cada contêiner do consul acaba ficando em sua própria rede de ponte somente de host. Eu apenas criei minhas redes de janelas de encaixe depois que o enxame foi inicializado. Eu não pude adicionar os contêineres do cônsul a uma rede de sobreposição depois que o enxame acabou, eu pego

Error response from daemon: No such container: swarm-node-1/swarmconsul_consul_1

Como posso fazer com que a descoberta de serviço com base em DNS funcione dentro de meus contêineres?

    
por Emmet O'Grady 02.06.2016 / 12:48

1 resposta

0

No final, consegui fazê-lo funcionar. Eu estava fazendo algumas coisas erradas.

O maior erro foi que eu não havia mapeado a porta 53 no host para a porta 53 / udp dentro do contêiner do cônsul. O mapeamento completo de portas agora é assim:

services:
    consul:
        image: progrium/consul
        hostname: "{{ ansible_hostname }}"
        ports:
          # Explanation of ports needed: http://stackoverflow.com/a/30692226/1514089
          - "8300:8300" # This is used by servers to handle incoming requests from other agents
          - "8301:8301/tcp" # This is used to handle gossip in the LAN. Required by all agents
          - "8301:8301/udp" # This is used to handle gossip in the LAN. Required by all agents
          - "8302:8302/tcp" # This is used by servers to gossip over the WAN to other servers
          - "8302:8302/udp" # This is used by servers to gossip over the WAN to other servers
          - "8400:8400" # This is used by all agents to handle RPC from the CLI
          - "8500:8500" # This is used by clients to talk to the HTTP API
          - "8600:8600" # Used to resolve DNS queries
          - "172.17.0.1:53:53/udp"
        restart: always
        command: "{{ consul_command }}"

Aqui estamos vinculando à porta 53 na interface docker0. No entanto, aprendi que o IP da ponte docker0 pode mudar, então codifiquei um pouco e disse ao docker para sempre usar esse IP para a ponte docker0 especificando --bip=172.17.0.1 nas opções do daemon do docker. O próximo passo foi definir o dns padrão do daemon do docker para o mesmo IP. Meu daemon do Docker completo opta assim:

[Service]
ExecStart=
ExecStart=/usr/bin/docker daemon \
    -H tcp://0.0.0.0:2375 \
    -H unix:///var/run/docker.sock \
    --bip=172.17.0.1/16 \
    --dns=172.17.0.1 \
    --dns-search=service.consul \
    --storage-driver=overlay \
    --cluster-store=consul://127.0.0.1:8500

Agora posso fazer isso:

$ sudo docker -H :4000 run -it joffotron/docker-net-tools
/ # dig +short consul.service.consul
10.0.0.93
10.0.0.95
10.0.0.94

Ótimo!

    
por 02.06.2016 / 14:10