Postgres容器用--network host时127.0.0.1连接失败,localhost可行
Postgres容器host网络模式下127.0.0.1连接失败问题分析
问题现象
使用postgres:14.1-alpine镜像运行Postgres容器,两种网络模式下出现连接差异:
- A)
--network host模式:PGPASSWORD=postgres psql -d db -U postgres -h localhost # 连接成功 PGPASSWORD=postgres psql -d db -U postgres -h 127.0.0.1 # 连接失败,报错密码认证失败 - B) 默认桥接模式:上述两种连接方式均可正常访问。
连接失败的错误信息:
psql: error: connection to server at "127.0.0.1", port 5432 failed: FATAL: password authentication failed for user "postgres"
复现步骤
运行两个对比容器pgA(host模式)和pgB(桥接模式):
# 启动host模式容器pgA docker run -d --rm -it --network host \ -e POSTGRES_PASSWORD=postgres -e POSTGRES_USER=postgres -e POSTGRES_DB=db \ --name pgA \ postgres:14.1-alpine # 启动桥接模式容器pgB docker run -d --rm -it \ -e POSTGRES_PASSWORD=postgres -e POSTGRES_USER=postgres -e POSTGRES_DB=db \ --name pgB \ postgres:14.1-alpine
分别尝试用-h 127.0.0.1连接:
# 连接pgA,失败 docker exec -it \ pgA \ bash -c 'PGPASSWORD=postgres psql -h 127.0.0.1 -d db -U postgres' # 连接pgB,成功 docker exec -it \ pgB \ bash -c 'PGPASSWORD=postgres psql -h 127.0.0.1 -d db -U postgres'
环境信息
docker --version # Docker version 20.10.11, build dea9396 uname -a # Darwin foo.local 20.6.0 Darwin Kernel Version 20.6.0: # Mon Aug 30 06:12:20 PDT 2021; root:xnu-7195.141.6~3/RELEASE_ARM64_T8101 arm64
容器对比排查
对pgA和pgB的关键配置与状态进行对比:
- 数据目录配置:
/var/lib/postgresql/data/下一级文件一致(仅postmaster.pid的PID不同),其中:postgresql.conf均设置listen_addresses = '*'pg_hba.conf规则完全相同,包含host all all 127.0.0.1/32 trust
- 网络监听:
netstat -anpt | grep 5432结果一致,均监听0.0.0.0和:::的5432端口 - hosts文件:仅桥接模式的pgB多一行容器IP与ID的映射,其余内容一致
原因推测与后续排查方向
核心推测
host模式下容器共享宿主机网络栈,当宿主机本身运行有Postgres服务并占用5432端口时:
psql -h localhost默认优先使用Unix套接字连接,因此访问的是容器内的Postgres服务psql -h 127.0.0.1强制使用TCP连接,此时会连接到宿主机上的Postgres服务,而宿主机的Postgres密码与容器不一致,导致认证失败
后续排查点
- 检查宿主机端口占用:在宿主机执行
lsof -i :5432或netstat -anpt | grep 5432,确认是否有其他进程(如宿主机本地的Postgres)占用5432端口 - 验证连接方式:在pgA容器内执行
psql -h localhost -d db -U postgres -c '\conninfo',查看输出是否显示为Unix套接字连接 - 查看Postgres日志:执行
docker logs pgA,查找认证失败的日志条目,确认请求的来源IP、用户信息等细节 - 端口隔离测试:修改pgA的启动命令,指定非默认端口(如5433):
再用docker run -d --rm -it --network host \ -e POSTGRES_PASSWORD=postgres -e POSTGRES_USER=postgres -e POSTGRES_DB=db \ --name pgA \ postgres:14.1-alpine -p 5433PGPASSWORD=postgres psql -d db -U postgres -h 127.0.0.1 -p 5433连接,验证是否成功
内容的提问来源于stack exchange,提问作者VanillaDonuts
相关产品推荐
相关产品推荐

