O DNS da rede de sobreposição do Docker Swarm resolve consistentemente nomes de host para um endereço IP um número menor que o IP real de um contêiner

O DNS da rede de sobreposição do Docker Swarm resolve consistentemente nomes de host para um endereço IP um número menor que o IP real de um contêiner

Estou tendo um problema reproduzível muito estranho com o Docker Swarm. Estou tentando implantar um cluster de servidor Dgraph via Docker Swarm em quatro contêineres LXD. Para fins de contexto, Dgraph Zero é o servidor de controle e cada servidor Dgraph Alpha faz o levantamento e deve se conectar a um servidor Zero na inicialização. Ratel é apenas um servidor de UI web para consultas e mutações de banco de dados. A topografia fica assim:

  • Anfitrião: estação de trabalho KDE Neon
    • Contêiner LXD: zero
      • Nó Docker: dg-zero
        • Contêiner Docker: dgraph_zero
        • Contêiner Docker: dgraph_ratel
    • Contêiner LXD: alfa1
      • Nó Docker: dg-alpha1
        • Contêiner Docker: dgraph_alpha1
    • Contêiner LXD: alfa2
      • Nó Docker: dg-alpha2
        • Contêiner Docker: dgraph_alpha2
    • Contêiner LXD: alfa3
      • Nó Docker: dg-alpha3
        • Contêiner Docker: dgraph_alpha3

Todos eles são implantados como um enxame docker stack deployusando a seguinte configuração docker-compose.yml:

version: "3"
networks:
  dgraph:
services:
  zero:
    image: dgraph/dgraph:latest
    hostname: "zero"
    volumes:
      - data-volume:/dgraph
    ports:
      - "5080:5080"
      - "6080:6080"
    networks:
      - dgraph
    deploy:
      placement:
        constraints:
          - node.hostname == dg-zero
    command: dgraph zero --my=zero:5080 --replicas 3 --bindall=true
  alpha1:
    image: dgraph/dgraph:latest
    hostname: "alpha1"
    volumes:
      - data-volume:/dgraph
    ports:
      - "8080:8080"
      - "9080:9080"
    networks:
      - dgraph
    deploy:
      placement:
        constraints:
          - node.hostname == dg-alpha1
    command: dgraph alpha --my=alpha1:7080 --lru_mb=1024 --zero=zero:5080 --bindall=true
  alpha2:
    image: dgraph/dgraph:latest
    hostname: "alpha2"
    volumes:
      - data-volume:/dgraph
    ports:
      - "8081:8081"
      - "9081:9081"
    networks:
      - dgraph
    deploy:
      placement:
        constraints:
          - node.hostname == dg-alpha2
    command: dgraph alpha --my=alpha2:7081 --lru_mb=1024 --zero=zero:5080 -o 1 --bindall=true
  alpha3:
    image: dgraph/dgraph:latest
    hostname: "alpha3"
    volumes:
      - data-volume:/dgraph
    ports:
      - "8082:8082"
      - "9082:9082"
    networks:
      - dgraph
    deploy:
      placement:
        constraints:
          - node.hostname == dg-alpha3
    command: dgraph alpha --my=alpha3:7082 --lru_mb=1024 --zero=zero:5080 -o 2 --bindall=true
  ratel:
    image: dgraph/dgraph:latest
    hostname: "ratel"
    ports:
      - "8000:8000"
    networks:
      - dgraph
    command: dgraph-ratel
volumes:
  data-volume:

Todos os serviços estão sendo implantados corretamente e em execução. O problema é que eles não conseguem se comunicar entre si porque os nomes de host não estão resolvendo para o IP correto.

Eu tenho um enxame em execução no momento e quando executo docker container inspectmeu contêiner Zero em execução, obtenho a seguinte saída para a configuração da rede:

"NetworkSettings": {
            "Bridge": "",
            "SandboxID": "4548013a15833d086b281a8c2dd61ced6ea5c92f815a305f7337effe9b04a13a",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "8080/tcp": null,
                "9080/tcp": null
            },
            "SandboxKey": "/var/run/docker/netns/4548013a1583",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "dgraph_dgraph": {
                    "IPAMConfig": {
                        "IPv4Address": "10.0.9.3"
                    },
                    "Links": null,
                    "Aliases": [
                        "8b48711ab0cd"
                    ],
                    "NetworkID": "lve3kr9vm42rwu1nci897zey7",
                    "EndpointID": "056ae62475da805ec212d9ec2b2e4a5c9e09e2405c15ad6e8b298e90669b512d",
                    "Gateway": "",
                    "IPAddress": "10.0.9.3",
                    "IPPrefixLen": 24,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:0a:00:09:03",
                    "DriverOpts": null
                },
                "ingress": {
                    "IPAMConfig": {
                        "IPv4Address": "10.0.0.157"
                    },
                    "Links": null,
                    "Aliases": [
                        "8b48711ab0cd"
                    ],
                    "NetworkID": "vjhpbsc1766lbvtu169fmh81l",
                    "EndpointID": "29bbc4de97e98b2e05a46dd42020dd1fbb75ff07d8c08a00b8ba6f2f4e00ec2a",
                    "Gateway": "",
                    "IPAddress": "10.0.0.157",
                    "IPPrefixLen": 24,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:0a:00:00:9d",
                    "DriverOpts": null
                }
            }
        }

Como pode ser visto, o endereço IP do meu contêiner Zero é 10.0.9.3. No entanto, se eu fizer login no shell de qualquer um dos meus contêineres Alpha e executá-lo, ping zeroele tentará executar ping em 10.0.9.2. Isso é reproduzível de forma consistente, destruindo e reimplantando a pilha. O octeto final no endereço IP do meu contêiner Zero será sempre um maior que o endereço IP zeropara o qual o nome do host resolve nos outros três contêineres. Posso executar ping em todos os meus contêineres uns dos outros usando os endereços IP corretos, mas devo usar nomes de host porque não sei quais serão os endereços dos outros contêineres antes da criação do enxame e preciso configurar o cluster de servidores para falar com uns aos outros.

Não existem regras de firewall em vigor. Todos os meus contêineres LXD podem se comunicar. Todos os endereços IP do contêiner LXD são listados como pares na configuração da rede Docker. Não sei se está relacionado ou não, mas não consigo acessar meus serviços a partir dos contêineres host, embora tenha publicado portas. Se for possível que isso esteja relacionado, posso fornecer mais informações que encontrei, mas por enquanto deixarei isso de fora.

Como descubro por que meu enxame não está resolvendo os nomes de host corretos para os contêineres corretos?

A versão do Docker é 19.03.5 do repositório oficial. Os contêineres LXD são contêineres de nuvem oficiais 18.04 do servidor de imagem LXD do Ubuntu. O host é o KDE Neon baseado no Ubuntu 18.04.

informação relacionada