python - Docker:当使用容器名称从一个容器连接到另一个容器时,如何解决“无法将主机名“postgres”转换为地址”?
问题描述
我启动 3 个容器:
docker run -d --rm --name redis --publish 6379:6379 redis
docker run -d --rm --name postgres --publish 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust -e POSTGRES_DB=hi postgres:9.6
docker run -d --rm --name web --publish 8000:8000 python:3.6.8-stretch sleep 1000
然后我执行web
:
docker exec -it web bash
然后我安装psycopg2
:
$ pip install psycopg2
然后我尝试连接到host: postgres
, port:5432
, database:hi
:
我启动python:
$ python
然后我运行这些命令:
import psycopg2
conn = psycopg2.connect(host="postgres", port = 5432, database="hi", user="postgres", password="<passwd>")
我收到以下错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.6/site-packages/psycopg2/__init__.py", line 127, in connect
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not translate host name "postgres" to address: Name or service not known
我认为这可能是一个 docker 网络问题,所以我去检查它,所有主机名都在那里:
{
"Name": "bridge",
"Id": "8e37606d20ae80189da4d7ecdb7673274fa2e0c9dd2b5c2b4c3db4e545c1ef20",
"Created": "2020-05-14T19:10:43.532158344Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"3bb2a6cf4fbb235324d335f238c20fe026e37bccc717d1cd0bd1df43e70dbec6": {
"Name": "redis",
"EndpointID": "f927fc2a199d033bbbc8ecc8ff1bccf508e607384e4820884f3236f11a961c04",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
},
"545065d96fb6f867724ece2cf11881af26be9885f16212bef4260bccba00a2be": {
"Name": "web",
"EndpointID": "750133a6bb72e23929c57f32aa7776bc85d3dd255a16473a4afe230d0c6cb9c2",
"MacAddress": "02:42:ac:11:00:04",
"IPv4Address": "172.17.0.4/16",
"IPv6Address": ""
},
"cfb2e556ca9f26ff8c7063f2347b81b2a90365cfa476cab8611edf1586404a88": {
"Name": "postgres",
"EndpointID": "069411d5c42b3b968ce38b92b7122c608f1dca696517122728f23086fdce53c7",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
似乎主机名postgres
应该解析ip
为172.17.0.3
.
当我在 python 中这样做时,它可以工作:
import psycopg2
conn = psycopg2.connect(host="172.17.0.3", port = 5432, database="hi", user="postgres", password="")
如何连接到postgres
使用其名称作为主机命名的容器?
解决方案
您怀疑这是 docker 网络问题是对的。
正如您所发现的,名称解析不适用于正在使用的默认网络。为了允许名称解析工作,您需要使用单独的网络,如下所示:
docker network create my-network
然后,使用--net
参数运行您的容器:
docker run -d --rm --name postgres --publish 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust -e POSTGRES_DB=hi --net my-network postgres:9.6
docker run -d --rm --name redis --publish 6379:6379 --net my-network redis
docker run -d --rm --name web --publish 8000:8000 --net my-network python:3.6.8-stretch sleep 1000
然后,使用此用户创建的网络将允许您使用容器名称:
>>> import psycopg2
>>> conn = psycopg2.connect(host="postgres", port = 5432, database="hi", user="postgres", password="")
>>> conn.info.user
'postgres'
请注意,对于使用多个容器的设置,我建议使用docker-compose而不仅仅是docker
命令,因为该网络是在后台为您设置的。
推荐阅读
- reactjs - 如何在 Metronic 中使用 thunk 而不是 Redux Saga
- typescript - 在 Jest 中,如何模拟具有依赖项的 TypeScript 类?
- javascript - 如何获取所有元素的数据,而不仅仅是第一个元素
- cassandra - Cassandra 基于轻量级事务的序列生成器一致性失败?
- python - How to add data to nested serializers?
- algorithm - 谷歌 Foobar 游戏
- webpack - 获取 @babel/present-env 的默认实现以与 IE11 一起使用
- android - 具有 StaggeredGridLayoutManager 的 Recyclerview 元素正在反向加载
- php - 执行输入数据时显示的 PHP 代码
- apache-kafka - 文件更改时如何更新 Kafka 文件源连接器?