bigywater.tech
Docker · 60

--add-host 与 /etc/hosts:谁在写这个文件

--add-host 到底写进了哪里?它和 DNS 谁优先?在容器里直接改 /etc/hosts 能保存吗?这篇逐项实测,包括同名多条记录和 ping 与 nslookup 的差别。

10.9.9.11
--add-host github.com:10.9.9.11 之后 ping github.com 解析到的地址(真实地址是 20.205.243.166)
第一条
同名两条 --add-host 时 ping 取的是第一条
restart 后丢失
容器里手工追加到 /etc/hosts 的内容,docker restart 之后不在了

默认内容

实测 · 本机执行输出
  127.0.0.1	localhost
  ::1	localhost ip6-localhost ip6-loopback
  fe00::	ip6-localnet
  ff00::	ip6-mcastprefix
  ff02::1	ip6-allnodes
  ff02::2	ip6-allrouters
  <容器IP>	<容器ID前12位>
  hostname 命令:<容器ID前12位>

/etc/hosts 固定有 6 行本地和 IPv6 条目,最后一行是容器自己的 IP 和主机名(默认是容器 ID 前 12 位)。

--add-host 与主机名

实测 · 本机执行输出
  127.0.0.1	localhost
  ::1	localhost ip6-localhost ip6-loopback
  fe00::	ip6-localnet
  ff00::	ip6-mcastprefix
  ff02::1	ip6-allnodes
  ff02::2	ip6-allrouters
  10.9.9.9	db.internal
  10.9.9.10	cache
  <容器IP>	web01.corp.test web01
  hostname = web01;hostname -f = web01.corp.test
  docker inspect HostConfig.ExtraHosts = ["db.internal:10.9.9.9","cache:10.9.9.10"]

--add-host 名字:IP 追加在固定行之后;--hostname 与 --domainname 改的是最后一行,以及 hostname -f 的结果。

优先级

实测 · 本机执行输出
  ping db.internal(只在 /etc/hosts 里):PING db.internal (10.9.9.9): 56 data bytes
  --add-host github.com:10.9.9.11 之后,ping github.com:PING github.com (10.9.9.11): 56 data bytes
  同一个容器 nslookup github.com(busybox nslookup 直接问 DNS):Address: 20.205.243.166
  对比:没加 --add-host 的容器 ping github.com:PING github.com (20.205.243.166): 56 data bytes

解析器(ping 用的 getaddrinfo)先查 /etc/hosts,所以可以用 --add-host 覆盖一个真实域名;但 busybox 的 nslookup 直接问 DNS,看不到 /etc/hosts 里的条目,排查解析问题时别被它误导。

重复与持久

实测 · 本机执行输出
  --add-host multi:10.9.9.20 --add-host multi:10.9.9.21 → /etc/hosts 里 multi 的行:10.9.9.20	multi ; 10.9.9.21	multi
  ping multi 解析到:PING multi (10.9.9.20): 56 data bytes
  容器里追加 10.9.9.99 edited.local 后,docker exec cat 能看到吗?能
  docker restart 之后 edited.local 还在吗?不在;--add-host 的 multi 还在吗?在

同名多条,ping 取第一条。容器里手改的 /etc/hosts 在 docker restart 后丢失,而 --add-host 的条目会重新写入,所以要持久地加条目用 --add-host。

分步演示

--add-host 与 /etc/hosts
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Docker Desktop(Engine 29.8.2,容器跑在 Docker Desktop 自带的 Linux 虚拟机里,内核与宿主机的 macOS 不同);镜像为 linux/arm64;需要看虚拟机内部时用特权容器 + nsenter;计时用 time / date +%s%N,数字每次运行会有小幅抖动。内容取自 docker exec cat /etc/hosts(容器 IP 和容器 ID 在输出中替换成了占位符);解析用 busybox 的 ping 与 nslookup;github.com 的真实地址取自一次 DNS 查询;每种情形运行一次;实验后已删除容器
    • 没有验证:host-gateway 的值(见 c51)、自定义网络里 --add-host 与内置 DNS 的优先级、IPv6 条目的 --add-host、Compose 的 extra_hosts、glibc 与 musl 解析器的差别
    京ICP备2026067502号-1京公网安备11010502063487号