当 docker 脚本中的 Python 连接到堆栈中的 SQL 服务器时出现问题
Issue when a Python in a docker script connects to a SQL server in a stack
我在 swarm 中有一个堆栈,它自己运行良好(至少我认为它......)。它有一个工作在5432端口的postgresql和一个工作在80端口的web服务器。可以从外部正常访问web服务器。
对于单元测试,我运行只有数据库端,在堆栈模式下:
version: "3"
services:
sql:
image: sql
networks:
- service_network
ports:
- 5432:5432
deploy:
replicas: 1
restart_policy:
condition: on-failure
volumes:
- ./local_storage_sql:/var/lib/postgresql/data
environment:
# provide your credentials here
- POSTGRES_USER=xxxx
- POSTGRES_PASSWORD=xxxx
networks:
service_network:
然后,单元测试通过连接到另一个简单 python 容器中的数据库开始:
FROM python:latest
LABEL version="0.1.0"
LABEL org.sgnn7.name="unittest"
# Make sure we are fully up to date
RUN apt-get update -q && \
apt-get dist-upgrade -y && \
apt-get clean && \
apt-get autoclean
RUN python -m pip install psycopg2-binary
RUN mkdir /testing
COPY ./*.py /testing/
连接时测试脚本失败:
conn = connect(dbname=database, user=user, host=host, password=password)
与:
File "/usr/local/lib/python3.7/site-packages/psycopg2/__init__.py", line 130, in connect
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
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 5432?
could not connect to server: Cannot assign requested address
Is the server running on host "localhost" (::1) and accepting
TCP/IP connections on port 5432?
但是只有当我 运行 它在容器中时它才会失败。从外面看,它就像一个魅力。我还尝试设置外部网络并使用它(相同的 docker 节点):
docker run --rm --net service_network -t UnitTest-image py.test /testing
显然,我预计从网络外部访问数据库比从内部访问数据库更困难,所以很明显,我在这里错过了一些东西,但我不知道是什么...
当您使用 Compose 文件部署堆栈时,网络的全名是通过将堆栈名称与基本网络名称组合在一起创建的。因此,假设您像这样部署了名为 foo
的堆栈。
docker stack deploy -c compose-file.yml foo
那么,完整的网络名称将是 foo_service_network
。
当您 运行 您的 Python 容器时,您需要将其连接到 foo_service_network
,而不是 service_network
。
docker container run --rm --net foo_service_network -t UnitTest-image py.test /testing
您还可以通过在 Compose 文件(3.5 及更高版本)中指定 name 属性 来自定义网络名称。
networks:
service_network:
name: service_network
在这种情况下,您可以使用该自定义名称将您的容器连接到网络。
docker container run --rm --net service_network -t UnitTest-image py.test /testing
编辑 1/28:添加了 Compose 文件示例。
version: "3.7"
services:
sql:
image: sql
networks:
- service_network
ports:
- 5432:5432
deploy:
replicas: 1
restart_policy:
condition: on-failure
volumes:
- ./local_storage_sql:/var/lib/postgresql/data
environment:
# provide your credentials here
- POSTGRES_USER=xxxx
- POSTGRES_PASSWORD=xxxx
networks:
service_network:
name: service_network
attachable: true
我在 swarm 中有一个堆栈,它自己运行良好(至少我认为它......)。它有一个工作在5432端口的postgresql和一个工作在80端口的web服务器。可以从外部正常访问web服务器。
对于单元测试,我运行只有数据库端,在堆栈模式下:
version: "3"
services:
sql:
image: sql
networks:
- service_network
ports:
- 5432:5432
deploy:
replicas: 1
restart_policy:
condition: on-failure
volumes:
- ./local_storage_sql:/var/lib/postgresql/data
environment:
# provide your credentials here
- POSTGRES_USER=xxxx
- POSTGRES_PASSWORD=xxxx
networks:
service_network:
然后,单元测试通过连接到另一个简单 python 容器中的数据库开始:
FROM python:latest
LABEL version="0.1.0"
LABEL org.sgnn7.name="unittest"
# Make sure we are fully up to date
RUN apt-get update -q && \
apt-get dist-upgrade -y && \
apt-get clean && \
apt-get autoclean
RUN python -m pip install psycopg2-binary
RUN mkdir /testing
COPY ./*.py /testing/
连接时测试脚本失败:
conn = connect(dbname=database, user=user, host=host, password=password)
与:
File "/usr/local/lib/python3.7/site-packages/psycopg2/__init__.py", line 130, in connect
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
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 5432?
could not connect to server: Cannot assign requested address
Is the server running on host "localhost" (::1) and accepting
TCP/IP connections on port 5432?
但是只有当我 运行 它在容器中时它才会失败。从外面看,它就像一个魅力。我还尝试设置外部网络并使用它(相同的 docker 节点):
docker run --rm --net service_network -t UnitTest-image py.test /testing
显然,我预计从网络外部访问数据库比从内部访问数据库更困难,所以很明显,我在这里错过了一些东西,但我不知道是什么...
当您使用 Compose 文件部署堆栈时,网络的全名是通过将堆栈名称与基本网络名称组合在一起创建的。因此,假设您像这样部署了名为 foo
的堆栈。
docker stack deploy -c compose-file.yml foo
那么,完整的网络名称将是 foo_service_network
。
当您 运行 您的 Python 容器时,您需要将其连接到 foo_service_network
,而不是 service_network
。
docker container run --rm --net foo_service_network -t UnitTest-image py.test /testing
您还可以通过在 Compose 文件(3.5 及更高版本)中指定 name 属性 来自定义网络名称。
networks:
service_network:
name: service_network
在这种情况下,您可以使用该自定义名称将您的容器连接到网络。
docker container run --rm --net service_network -t UnitTest-image py.test /testing
编辑 1/28:添加了 Compose 文件示例。
version: "3.7"
services:
sql:
image: sql
networks:
- service_network
ports:
- 5432:5432
deploy:
replicas: 1
restart_policy:
condition: on-failure
volumes:
- ./local_storage_sql:/var/lib/postgresql/data
environment:
# provide your credentials here
- POSTGRES_USER=xxxx
- POSTGRES_PASSWORD=xxxx
networks:
service_network:
name: service_network
attachable: true