drno-reg
@drno-reg
см не кратко

Как решить сетевую проблему приложение из Docker контейнера не видит БД в другом контейнере?

Здравствуйте.

Развернул 2 docker контейнера
- flask_app - web приложение на flask
- postgresql - СУБД Postresql

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
d5c368b82067        flask:0.1        "flask run -p 5000 -…"   12 minutes ago      Up 12 minutes       0.0.0.0:5000->5000/tcp              flask_app
06fbaf3ffe5d        postgres            "docker-entrypoint.s…"   8 days ago          Up 8 days           0.0.0.0:54320->5432/tcp             postgresql


при запуске приложения flask_app возвращается сетевая ошибка

sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 54320?
could not connect to server: Cannot assign requested address
Is the server running on host "localhost" (::1) and accepting
TCP/IP connections on port 54320?


при сборке контейнера доустановил в него telnet и ping
в общем попытки подключиться из контейнера flask к СУБД Connection refused

flask inspect

"NetworkSettings": {
            "Bridge": "",
            "SandboxID": "8d4d3e7707902e1a97e204d405a3815fda2b4fb19676f619defde5d4c801dd0f",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "5000/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "5000"
                    }
                ]
            },
            "SandboxKey": "/var/run/docker/netns/8d4d3e770790",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "167b7f463934cd4c427672df0fefef55772147932b485eed273f70f7b30f703b",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.4",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:04",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "8c8fa606ac1730dd3a2d06e93802ba09f6ceea311f45e02b531c928f9cb4e8e8",
                    "EndpointID": "167b7f463934cd4c427672df0fefef55772147932b485eed273f70f7b30f703b",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.4",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:04",
                    "DriverOpts": null
                }
            }
        }
    }


postgres

"NetworkSettings": {
            "Bridge": "",
            "SandboxID": "340e70753ef7fd6053d3d6f1512e15eff78532d554002dc0664256c1fecb7028",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "5432/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "54320"
                    }
                ]
            },
            "SandboxKey": "/var/run/docker/netns/340e70753ef7",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "77c6bd92da4724341c57d4ab8dbf9d84f43df9a7838c93371fc1ac91d2a9c7fa",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.3",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:03",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "8c8fa606ac1730dd3a2d06e93802ba09f6ceea311f45e02b531c928f9cb4e8e8",
                    "EndpointID": "77c6bd92da4724341c57d4ab8dbf9d84f43df9a7838c93371fc1ac91d2a9c7fa",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.3",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:03",
                    "DriverOpts": null
                }
            }


Как решить сетевую проблему приложение из Docker контейнера не видит БД в другом контейнере?
  • Вопрос задан
  • 4939 просмотров
Решения вопроса 2
@q2digger
никого не трогаю, починяю примус
Так обращаться надо не к локалхосту а к контейнеру.
Узнайте внутрений адрес контейнера и стучитесь в него, а еще лучше - организуйте ваши контейнеры с помощью docker-compose и тогда сможете прям по его имени к нему обращаться.
Ответ написан
@iddqda
network engineer, netdevops
тут нужно понимать, что вот это 0.0.0.0:5000->5000/tcp - к самому контейнеру не относится
это настройка порфорвардинга в сетевом драйвере самого докера
И она нужна для того чтоб к контейнеру обратиться снаружи и не имеет отношения к связи контейнеров друг с другом.
Возможно в вашем случае порт postgres выставлять вообще не стоит из соображений безопасности

между собой контейнеры (внутри одного хоста) обращаются без выхода наружу по своим внутренним адресам
postgres: "IPAddress": "172.17.0.3"
flask: "IPAddress": "172.17.0.4"


адреса контейнерам назначает докер, поэтому именно адреса использовать не стоит, а лучше использовать имена. докер для этого предоставляет параметр --link
он нужен чтобы докер сделал запись (IP адрес -> имя_контейнера_с_которым_нужна_связь) в /etс/hosts контейнера

так же необходимо передать имя_контейнера_с_которым_нужна_связь внутрь приложения
потому что, понятно, что localhost ни разу не годится. он у каждого контейнера свой и не совпадает с localhost хоста
для этого можо использовать переменные окружения и соответственно параметр -e
ну и внутри приложения вот примерно такой строкой делаем приложение docker-ready
PG_HOSTNAME = environ.get("PG_HOSTNAME") if environ.get("PG_HOSTNAME") else "localhost"


контейнеры в итоге запускать примерно так:
docker run -d --name postgress postgress
docker run -d --name flask --link postgress -e PG_HOSTNAME=postgress flask


disclaimer: я за докером давно не слежу. сейчас заметил, что параметр --link отмечен как legacy. Так что, возможно, я предлагаю немодное решение, но оно до сих пор работает
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
drno-reg
@drno-reg Автор вопроса
см не кратко
внутри flask_app

inclouds.config['SQLALCHEMY_DATABASE_URI'] = "postgresql://user:passwd@postgresql:5432/inclouds"


где postgresql - имя docker контейнера, если они располагаются на одном хосте
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы