欢迎光临
我们一直在努力

Docker容器访问宿主机怎么配置?地址设置与连接排查

在服务器上部署 Docker 应用时,经常会遇到一种情况:宿主机上的接口可以正常访问,但把同一个地址填进容器里的应用后,却提示连接被拒绝。

例如,某个接口运行在宿主机的 8080 端口。在服务器终端访问正常,容器中的应用连接下面这个地址却失败:

http://127.0.0.1:8080

问题往往出在地址指向上。

在常规 bridge 网络模式下,容器里的 127.0.0.1 指向当前容器自己。要连接宿主机,需要使用容器能够访问的宿主机地址,同时确认目标服务的监听设置正确。

本文以 Linux 服务器上的 Docker Engine 为例,介绍单容器和 Docker Compose 的配置方法。

1. 先分清:你要访问的是谁?

Docker bridge网络中容器访问自身与宿主机的区别

配置连接地址之前,先确认目标服务运行在哪里。

目标服务的位置通常使用的地址
当前容器内部127.0.0.1:服务端口
宿主机上的服务配置映射后的 host.docker.internal:服务端口
同一 Compose 网络中的其他容器服务名:容器端口
另一台服务器对方可达的 IP 或域名,加对应端口

例如,应用与数据库都通过同一个 Compose 项目部署,并且连接到同一个网络,数据库服务名是 db,那么应用通常应连接:

db:3306

这里使用的是数据库容器内部的端口,不需要绕到宿主机的公网 IP。

Docker 的用户自定义网络支持通过容器名称进行通信;常规容器网络则具有自己的网络接口、地址和路由。把这两种场景分清,能减少很多无效排查。

2. 操作前需要准备什么?

本文适用于 Debian、Ubuntu 等 Linux 系统上的常规 Docker Engine 环境,使用 bridge 网络,并通过 docker compose 管理项目。

先在服务器终端确认 Docker 和 Compose 可以使用:

docker version
docker compose version

尚未安装 Docker,可以先参考本站:

服务器上安装Docker和Docker Compose教程

注意,本站这篇早期文章中的 Compose 安装部分使用了旧版 docker-compose。本文使用的是插件形式的 docker compose 命令。

如果已经配置 Docker 官方软件源,在 Debian 或 Ubuntu 上可以安装 Compose 插件:

sudo apt-get update
sudo apt-get install -y docker-compose-plugin
docker compose version

如果尚未配置官方软件源,可按 Docker 官方 Compose 插件安装说明处理。

需要准备测试环境,也可以使用莱卡云 Linux 云服务器。应用资源配置应根据实际项目选择,本次连接排查本身不需要额外部署数据库。

查看官网购买链接: https://www.lcayun.com

9折优惠码:bloglcayun

下面的示例假设:宿主机上已经有一个 HTTP 服务,使用 8080 端口。 请按实际情况替换端口及接口路径。

3. 先检查宿主机服务的监听地址

在服务器终端执行:

sudo ss -lntp '( sport = :8080 )'

重点看监听地址。

只监听127.0.0.1:8080

这表示服务只接受宿主机自身回环地址上的连接。

普通 bridge 容器访问宿主机的网桥地址时,无法直接连接这个只监听 127.0.0.1 的服务。

即使已经添加 host.docker.internal 映射,这个问题也不会自动解决。

需要根据目标应用的配置方式,调整它的监听地址,使其监听容器能够到达的宿主机接口。

监听0.0.0.0:8080

这表示服务监听所有 IPv4 接口,通常具备从容器访问的监听条件,但最终是否能够连接,还取决于路由和防火墙。

0.0.0.0 也可能让服务在公网接口上接受连接。因此,如果服务只供本机容器使用,应优先绑定合适的内部接口,并限制允许访问的来源。

客户端连接地址不要填写 0.0.0.0,它在这里表示服务端的监听范围。

如果命令没有显示监听记录,先确认服务已经启动,以及实际使用的端口是否正确。

4. 使用docker run测试宿主机连接

Linux Docker Engine 可以通过 --add-host 增加地址映射:

docker run --rm \
  --add-host host.docker.internal:host-gateway \
  curlimages/curl:latest \
  --verbose \
  --noproxy '*' \
  --connect-timeout 5 \
  --max-time 10 \
  http://host.docker.internal:8080/

这条命令会启动一个临时 curl 容器,向宿主机的 8080 端口发送 HTTP 请求,执行结束后自动删除该测试容器。

其中:

  • host.docker.internal:供容器使用的宿主机名称。
  • host-gateway:由 Docker 解析为宿主机侧地址的特殊值。
  • --noproxy '*':让这次测试直接连接目标,避免绕经 HTTP 代理。
  • --connect-timeout 5:连接建立阶段最多等待 5 秒。
  • --max-time 10:整个请求最多等待 10 秒。

Docker 官方文档提供了相同的宿主机地址映射方式。Docker Desktop 通常已提供 host.docker.internal 解析,Linux Docker Engine 则可以显式添加上述映射。

测试时需要区分两件事:

收到 HTTP 响应,说明请求已到达某个 HTTP 服务;业务是否正常,还要看状态码和响应内容。

例如,返回 401 可能是缺少登录凭据,返回 404 可能是请求路径不正确,都不能直接判断为网络不通。

这里的 curl 命令用于测试 HTTP 服务。数据库、Redis 等其他协议,应使用对应客户端验证。

5. Docker Compose怎么配置?

使用 Compose 时,在发起请求的服务下面添加 extra_hosts:

extra_hosts:
  host.docker.internal: "host-gateway"

这项配置会为容器增加主机名映射。它不会自动修改应用原来填写的接口地址。

如果应用原来的地址是:

http://127.0.0.1:8080

还需要在应用配置中改成:

http://host.docker.internal:8080

独立测试示例

下面提供一个完整的 Compose 检测配置。建议放在单独的测试目录中,不要覆盖现有业务项目的配置文件。

在服务器终端执行:

mkdir -p ~/docker-host-check
cd ~/docker-host-check

cat > compose.yaml <<'EOF'
services:
  host-check:
    image: curlimages/curl:latest
    extra_hosts:
      host.docker.internal: "host-gateway"
    command:
      - "--verbose"
      - "--noproxy"
      - "*"
      - "--connect-timeout"
      - "5"
      - "--max-time"
      - "10"
      - "http://host.docker.internal:8080/"
EOF

检查配置并运行:

docker compose config --quiet
docker compose run --rm host-check

检测容器执行完成后退出是正常现象,因为它只负责发送一次请求。

这个示例可以帮助验证 Compose 环境下的访问情况。实际业务容器仍需配置自己的 extra_hosts,并使用正确的接口地址;独立测试成功不代表业务容器的网络与配置一定相同。

修改业务配置后怎么生效?

把 extra_hosts 加入实际业务服务,并修改接口地址后,在该业务项目目录执行:

docker compose up -d

Compose 会根据配置变化更新相关容器,发生重建时可能短暂中断服务。

不要只执行 docker compose restart。官方文档明确说明,单纯重启不会应用 Compose 文件中的配置变更。

6. 配置后仍然连不上,怎么判断原因?

可以先根据错误类型缩小范围。

现象优先检查
Could not resolve host当前容器是否添加了映射,主机名是否拼写正确
Connection refused目标地址和端口是否正确,服务是否监听该地址,防火墙是否主动拒绝连接
连接阶段超时路由是否可达,防火墙是否丢弃连接,服务所在主机是否正常
已连接但等待响应超时接口处理是否阻塞,后端依赖是否异常
返回 401 或 403认证信息、访问权限或应用访问规则
返回 404接口路径、反向代理路由或 Host 匹配
宿主机能访问,容器不能访问宿主机测试是否用了回环地址,以及容器网络与防火墙规则

排查时建议按下面的顺序进行:

  1. 确认目标服务运行在宿主机,还是另一个容器。
  2. 确认宿主机的目标端口确实存在监听。
  3. 确认服务监听的地址包含容器实际访问的宿主机地址。
  4. 确认映射已经应用到发起请求的容器。
  5. 检查防火墙、认证信息和接口路径。

如果容器连外部网站、公共域名也失败,可以继续参考本站:

Docker容器无法访问外网怎么办?DNS与网络排查教程

外网 DNS 故障与宿主机服务只监听回环地址,属于不同问题,处理方式也不同。

7. 两个容易踩坑的地方

不要把宿主机地址固定理解为172.17.0.1

不少示例会直接使用:

172.17.0.1

这个地址在部分默认环境中成立,但 Docker 的地址段和网桥配置可能发生变化。

host-gateway 默认使用默认网桥的宿主机侧地址,也可以由 Docker 守护进程配置覆盖。它不一定是当前 Compose 网络的网关,更不能保证始终是 172.17.0.1。

因此,使用明确的主机名映射通常更便于维护。

不要把host网络当成通用修复方法

Linux 下使用 network_mode: host 时,容器共享宿主机网络空间,此时回环地址的含义与普通 bridge 容器不同。

但这会改变网络隔离方式,端口也直接占用宿主机端口,原有的端口映射不再起作用。应在理解这些变化后再使用。

本文的配置方法针对常规 bridge 网络。Rootless Docker、Docker Desktop 和特殊网络驱动的访问行为,应结合各自环境判断。

8. 结语

Docker 容器访问宿主机时,最关键的是同时确认三个条件:地址指向正确、服务监听正确、网络允许连接。

host.docker.internal 配合 host-gateway 可以解决宿主机地址映射问题;服务的监听地址和防火墙规则,则决定请求能否真正到达目标。

如果目标其实是同一 Compose 网络中的其他容器,优先使用服务名和容器端口。先分清服务的位置,再按错误类型排查,配置会清楚得多。

赞(0)
未经允许不得转载:莱卡云 » Docker容器访问宿主机怎么配置?地址设置与连接排查