El DNS de la red superpuesta de Docker Swarm resuelve constantemente los nombres de host en una dirección IP un número menor que la IP real de un contenedor.

El DNS de la red superpuesta de Docker Swarm resuelve constantemente los nombres de host en una dirección IP un número menor que la IP real de un contenedor.

Tengo un problema reproducible muy extraño con Docker Swarm. Estoy intentando implementar un clúster de servidores Dgraph a través de Docker Swarm en cuatro contenedores LXD. Para el contexto, Dgraph Zero es el servidor de control y cada servidor Dgraph Alpha hace el trabajo y debe conectarse a un servidor Zero en el momento del lanzamiento. Ratel es solo un servidor de interfaz de usuario web para consultas y mutaciones de bases de datos. La topografía se ve así:

  • Anfitrión: estación de trabajo KDE Neon
    • Contenedor LXD: cero
      • Nodo Docker: dg-zero
        • Contenedor Docker: dgraph_zero
        • Contenedor Docker: dgraph_ratel
    • Contenedor LXD: alfa1
      • Nodo acoplable: dg-alpha1
        • Contenedor Docker: dgraph_alpha1
    • Contenedor LXD: alfa2
      • Nodo acoplable: dg-alpha2
        • Contenedor Docker: dgraph_alpha2
    • Contenedor LXD: alfa3
      • Nodo acoplable: dg-alpha3
        • Contenedor Docker: dgraph_alpha3

Todos estos se implementan como un enjambre mediante docker stack deployla siguiente configuración de 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 los servicios se están implementando correctamente y ejecutándose. El problema es que no pueden comunicarse entre sí porque los nombres de host no se resuelven en la IP correcta.

Actualmente tengo un enjambre ejecutándose y cuando lo ejecuto docker container inspecten mi contenedor Zero en ejecución obtengo el siguiente resultado para la configuración de red:

"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 puede verse, la dirección IP de mi contenedor Zero es 10.0.9.3. Sin embargo, si inicio sesión en el shell de cualquiera de mis contenedores Alpha y ping zerolo ejecuto, intento hacer ping a 10.0.9.2. Esto se puede reproducir de forma consistente destruyendo y volviendo a implementar la pila. El último octeto en la dirección IP de mi contenedor Zero siempre será uno mayor que la dirección IP zeroa la que se resuelve el nombre de host en los otros tres contenedores. Puedo hacer ping a todos mis contenedores entre sí usando las direcciones IP correctas, pero debo usar nombres de host porque no sé cuáles serán las direcciones del otro contenedor antes de la creación del enjambre y necesito configurar el clúster de servidores para hablar con entre sí.

No existen reglas de firewall implementadas. Todos mis contenedores LXD pueden comunicarse. Todas las direcciones IP del contenedor LXD aparecen como pares en la configuración de red de Docker. No sé si está relacionado o no, pero no puedo acceder a mis servicios desde los contenedores host a pesar de que he publicado los puertos. Si es posible que esté relacionado, puedo proporcionar más información que encontré, pero por ahora lo dejaré de lado.

¿Cómo puedo saber por qué mi enjambre no resuelve los nombres de host correctos en los contenedores correctos?

La versión de Docker es 19.03.5 del repositorio oficial. Los contenedores LXD son contenedores oficiales en la nube 18.04 del servidor de imágenes LXD de Ubuntu. El host es KDE Neon basado en Ubuntu 18.04.

información relacionada