El contenedor Docker no se puede conectar a otro usando una red Docker

El contenedor Docker no se puede conectar a otro usando una red Docker

Utilizo Docker-Compose para configurar una API con algunas bases de datos y una sembradora. Todo funcionó a las mil maravillas hasta hace unos días pero ahora ya no puedo sembrar la base de datos.
He aquí un ejemplo de midocker-compose.ymlarchivo:

version: '3'

services:
    api:
      image: <API image>
      ports: {API_PORT}:5000 //Flask's default port
      depends_on:
        - db

    db:
      image: <DB image>
      ports: {DB_PORT}:27017 //MongoDB Default port

    db-seed:
      image: <seeder image>

// pretty classic docker-compose file, nothing fancy

La sembradora utiliza elred acoplablepara acceder al contenedor API (http://api:80/) y sembrarlo. Sin embargo, el script del seeder (escrito en Python) ahora devuelve un error al intentar conectarse al contenedor API:

$> docker-compose up db-seed
<LOT OF ERRORS>...
requests.exceptions.ConnectionError: HTTPConnectionPool(host='api', port=80): Max retries exceeded with url: /ping (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f65e78a4310>: Failed to establish a new connection: [Errno 111] Connection refused'))

Parece que el contenedor de siembra no puede acceder al contenedor de base de datos. ¿Cuál podría ser la causa de este error? ¿Cómo podría solucionarlo?

Aquí esta lainspeccionar la red acoplablede mi red:

[{                                                                                                                                                                                                                            "Name": "staging-sensei-api_default",                                                                                                                                                                                    "Id": "b5bd162d27f9a1addaacf1b0f2c09ad799d3ae195cc6e8c9cbb54bfffc27651c",                                                                                                                                                "Created": "2019-07-22T14:18:05.080114521Z",                                                                                                                                                                             "Scope": "local",                                                                                                                                                                                                        "Driver": "bridge",                                                                                                                                                                                                      "EnableIPv6": false,                                                                                                                                                                                                     "IPAM": {                                                                                                                                                                                                                    "Driver": "default",                                                                                                                                                                                                     "Options": null,                                                                                                                                                                                                         "Config": [                                                                                                                                                                                                                  {                                                                                                                                                                                                                            "Subnet": "172.26.0.0/16",                                                                                                                                                                                               "Gateway": "172.26.0.1"                                                                                                                                                                                              }                                                                                                                                                                                                                    ]                                                                                                                                                                                                                    },                                                                                                                                                                                                                       "Internal": false,                                                                                                                                                                                                       "Attachable": true,                                                                                                                                                                                                      "Ingress": false,                                                                                                                                                                                                        "ConfigFrom": {                                                                                                                                                                                                              "Network": ""                                                                                                                                                                                                        },                                                                                                                                                                                                                       "ConfigOnly": false,                                                                                                                                                                                                     "Containers": {                                                                                                                                                                                                              "08672fe92d72b111f1a006a2ff20e885ef395a420525953b696672753cb73ff7": {
                "Name": "com.frcyber.sensei.elasticsearch",
                "EndpointID": "7ba9a1af1af5635d22c9cbd38fad8be222f351e5c0013f0280e2879cdd6e9e40",
                "MacAddress": "02:42:ac:1a:00:03",
                "IPv4Address": "172.26.0.3/16",
                "IPv6Address": ""
            },
            "364f873d069e4ecd371cdd99ca952d1469ee875aacbf9ee2227bbf25ab65d841": {
                "Name": "com.frcyber.sensei.api",
                "EndpointID": "e5a3f4cd2099aff2a04efdeb7a5c5d0a8ade4248b76df048f20a8a75bf85ddba",
                "MacAddress": "02:42:ac:1a:00:04",
                "IPv4Address": "172.26.0.4/16",
                "IPv6Address": ""
            },
            "f4bfaf323a8c8c6300156d3091ec70f091fc3492175bfa00faa1717e4f83d2a2": {
                "Name": "com.frcyber.sensei.mongodb",
                "EndpointID": "b5df4e0d3721ffe5cd28ce55f642e6a0bc7f5be1a12cc49bb2eb12a58eb82e7a",
                "MacAddress": "02:42:ac:1a:00:02",
                "IPv4Address": "172.26.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "default",
            "com.docker.compose.project": "staging-sensei-api",
            "com.docker.compose.version": "1.24.0"
        }
    }
]

Además, descubrí que funciona cuandoAPI_PORTse establece en 5000:

api:
  ports: 5000:5000

Respuesta1

Considerando que funciona en un caso específico, es decir:

Además, descubrí que funciona cuando API_PORT está configurado en 5000

api:
  ports: 5000:5000

Sugeriría que el problema no está en el lado de Docker, sino en cómo configura su proyecto. Esta sugerencia se basa en una suposición de mi parte: su contenedor db-seeder usa el valor API_PORTcomo puerto para conectarse al contenedor api (no está claramente definido en su publicación, asumiré que así es para lo siguiente).

Dado que su error de Python se muestra "api"como el host al que está intentando conectarse, en cuanto a DNS, esto sería equivalente a IP 172.26.0.4, según su docker network inspectresultado. En esta IP, el contenedor escucha en el puerto 5000, independientemente del API_PORTvalor de (según su docker-compose, ya que siempre vincula API_PORTel puerto de su host al 5000 del contenedor).

Lo extraño es que dijiste que funcionó antes, lo cual no debería haber sido el caso, excepto si tuvieras API_PORT5000.

Si desea conectarse dentro de la red acoplable en otro puerto, deberá cambiar algo en el contenedor, ya sea durante la compilación o en tiempo de ejecución, no solo el puerto del host al que se vincula.

Adición: ejemplo de "configurabilidad"

De tudocker-compose

version: '3'

services:
    api:
      image: <API image>
      ports: "80:${API_PORT:-5000}" //Flask's default port
      depends_on:
        - db
      environment:
        - DB_PORT=${DB_PORT:-27017}
        - API_PORT=${API_PORT:-5000}

    db:
      image: mongo:latest
      command: --port ${DB_PORT:-27017}

    db-seed:
      image: <seeder image>
      environment:
        - API_PORT=${API_PORT:5000}

Esto no expone su puerto db al exterior de su host. Necesitará recuperar los valores API_PORT y DB_PORT del entorno de su shell (o archivo .env) y usarlos de la siguiente manera:

  • conectarse a la API usandohttp(s)://api:$API_PORT
  • conectarse al mongo usandodb:$DB_PORT
  • Inicie el servidor cgi que usa para su API en producción (ejemplo para uwsgi) usando API_PORT, por ejemplo al final del ENTRYPOINTscript de su contenedor de API:
# Some other config / checks / setup at runtime
exec uwsgi --port "$API_PORT" [ OTHER_OPTIONS ... ] path/to/your/application.py

información relacionada