返回
创建于
状态公开

docker compose 中定义了一个容器,名字叫 us4ever.com,而你在真实世界(比如 DNS 中)也有一个域名叫 us4ever.com。这就涉及到了 Docker 内部 DNS 和外部 DNS 的解析优先级问题。

下面我来分段说明容器内访问 us4ever.com 时会发生什么情况:


一、Docker Compose 的服务名会自动注册为内部 DNS 名

docker-compose.yml 中定义了如下服务:

yaml
1services:
2  us4ever.com:
3    image: some-image

Docker 会把这个服务名 us4ever.com 注册到 Docker 的内部 DNS 中。这样,同一网络下的其他容器访问 us4ever.com,默认会解析成这个服务对应的容器的 IP 地址。


二、容器内访问 us4ever.com 的优先级是内部 DNS 优先

在容器内执行:

bash
1ping us4ever.com

或者程序代码中访问 http://us4ever.com,Docker 默认会先查自己的内部 DNS,看有没有名为 us4ever.com 的容器或服务。

由于你的容器名就是 us4ever.com,所以会解析到容器内部网络中的地址,比如 172.18.0.2

这意味着:容器内访问 us4ever.com 实际上访问的是容器自己或是 Docker 网络中的服务,而不是公网的 us4ever.com 域名。


三、如果你想在容器中访问公网的 us4ever.com 怎么办?

你有以下几种方案:

方法一:修改服务名,避免和公网域名冲突

最简单直接的方法是避免使用和公网域名一样的服务名。比如你可以改成:

yaml
1services:
2  us4ever-app:
3    image: some-image

这样容器内部访问 us4ever.com 就会走公网 DNS,不会被 Docker 截获。

方法二:容器内通过公网 IP 或 hosts 文件强制指定

如果你确实需要服务名是 us4ever.com,但还想在容器内访问真实公网的 us4ever.com,可以:

  • 使用公网 IP:

    bash
    1curl http://<真实公网IP>
  • 修改 /etc/hosts

    在容器内运行(或者 Dockerfile 中添加):

    bash
    1echo "1.2.3.4 us4ever.com" >> /etc/hosts

    这会让容器内的 us4ever.com 指向你指定的 IP,而不是 Docker DNS。

方法三:使用 extra_hosts 显式绑定

你也可以在 docker-compose.yml 中添加:

yaml
1services:
2  us4ever.com:
3    image: some-image
4    extra_hosts:
5      - "us4ever.com:1.2.3.4"  # 指定公网 IP

这样容器内访问 us4ever.com 时,就会直接跳过 Docker 的 DNS,解析到 1.2.3.4。


总结:

  • Docker Compose 会把服务名注册到内部 DNS,容器内优先解析内部 DNS。
  • 如果服务名和公网域名一样,容器内访问会“被劫持”,指向内部网络。
  • 要想访问真实公网域名,可以改服务名、使用 extra_hosts 或修改容器内 /etc/hosts