惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
CXSECURITY Database RSS Feed - CXSecurity.com
K
Kaspersky official blog
A
Arctic Wolf
Attack and Defense Labs
Attack and Defense Labs
L
LINUX DO - 热门话题
N
News | PayPal Newsroom
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
L
Lohrmann on Cybersecurity
PCI Perspectives
PCI Perspectives
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
The Last Watchdog
The Last Watchdog
B
Blog RSS Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
W
WeLiveSecurity
Know Your Adversary
Know Your Adversary
博客园 - Franky
T
Tenable Blog
T
Tailwind CSS Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Help Net Security
Help Net Security
WordPress大学
WordPress大学
T
The Exploit Database - CXSecurity.com
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
D
Darknet – Hacking Tools, Hacker News & Cyber Security
H
Heimdal Security Blog
TaoSecurity Blog
TaoSecurity Blog
S
Security Affairs
J
Java Code Geeks
小众软件
小众软件
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Apple Machine Learning Research
Apple Machine Learning Research
NISL@THU
NISL@THU
O
OpenAI News
The Cloudflare Blog
月光博客
月光博客
Google Online Security Blog
Google Online Security Blog
V
V2EX
罗磊的独立博客
美团技术团队
博客园 - 三生石上(FineUI控件)
Security Latest
Security Latest
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
Cyber Attacks, Cyber Crime and Cyber Security
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Cyberwarzone
Cyberwarzone
L
LINUX DO - 最新话题
Hacker News - Newest:
Hacker News - Newest: "LLM"
大猫的无限游戏
大猫的无限游戏

秋实-Allenyou 的小窝

【笔记】人工智能与模式识别 复习笔记 - 秋实-Allenyou 的小窝 【教程】使用 Keyd 将 Copilot 键映射为可用的组合键并修复触摸板防误触失效问题 机械革命无界 15X 的 Arch Linux 开荒指南 我在用什么?(2026 版) - 秋实-Allenyou 的小窝 关于 Next.js SSG 生成 RSS Feed 文件的另一思路 从零开始的 NixOS 体验 - 秋实-Allenyou 的小窝 2025:迷茫中转向 - 秋实-Allenyou 的小窝 我在用什么?(2025 版) - 秋实-Allenyou 的小窝 【杂谈】关于 AIGC 的一些思考 - 秋实-Allenyou 的小窝 【记录】如何在 Next.js 中优雅的调用 Matomo 统计 从信号与系统角度看 OI/XCPC 中的傅里叶变换运用 - 秋实-Allenyou 的小窝 【杂谈】答《博客作者呀,我想采访你这 9 个问题!》 - 秋实-Allenyou 的小窝 使用 Golang 重写 gh-proxy - 秋实-Allenyou 的小窝 FurryCTF 2024 寒假赛 调试窗口 题解 2024:“我”的大学生活 - 秋实-Allenyou 的小窝 【游记】CCPC 2024 重庆站尾杀记 - 秋实-Allenyou 的小窝 【游记】ICPC 2024 亚洲区域赛南京站打铁记 - 秋实-Allenyou 的小窝 【杂谈】这次 Furrygooo 结束后我的一些体验 - 秋实-Allenyou 的小窝 【教程】使用阿里云 OSS + CDN 加速 Gravatar 【记录】 一次罗技鼠标驱动冲突问题的排查经历 - 秋实-Allenyou 的小窝 【记录】我是如何用 Next.js 重构我的博客的 - 秋实-Allenyou 的小窝 【教程】如何用 Git 快速搭建简单的 CI - 秋实-Allenyou 的小窝 我的DN42 Peering信息 - 秋实-Allenyou 的小窝 【进度】博客重构计划 - 秋实-Allenyou 的小窝 这是一个正经的2023总结 - 秋实-Allenyou 的小窝 【题解】Luogu P9769 [HUSTFC 2023] 简单的加法乘法计算题 2023新年谜题总结 - 秋实-Allenyou 的小窝 【教程】浅谈Linux服务器的一些基础安全技巧 - 秋实-Allenyou 的小窝 Goodbye, 2022~ - 秋实-Allenyou 的小窝 【教程】使用 Docker 开服,优雅地隔离不同版本JDK - 秋实-Allenyou 的小窝 【旧文补档】2020年终总结 & 2021新年计划 - 秋实-Allenyou 的小窝 【旧文补档】写个脚本监控你的VPS SolusVM面板适用 - 秋实-Allenyou 的小窝 【旧文补档】建立自己的私人网盘!在CentOS VPS上安装NextCloud - 秋实-Allenyou 的小窝 【旧文补档】2019,再见!2020,你好! - 秋实-Allenyou 的小窝 【旧文补档】新一代USB来袭,一起捋一捋USB的“前世今生” - 秋实-Allenyou 的小窝 【旧文补档】矩阵学习笔记 - 秋实-Allenyou 的小窝
【记录】一种在主机通过 Docker 容器名解析容器 IP 的方法
2025-11-01 · via 秋实-Allenyou 的小窝

众所周知,Docker 内置了一个 DNS 服务器,会通过 iptables 将容器对外的 DNS 请求劫持到 127.0.0.11:53,以此实现同一 network 内的容器之间通过容器名互相访问的功能。也因此,在我的服务器架构中,几乎所有服务都被放进了容器中运行,并通过自定义 network 动态分配 IP。这样,容器之间的网络命名空间不会冲突,在容器之间互相访问时也不需要记忆 IP,只需要使用容器名 + 端口号即可(例如:MySQL:3306 就可以访问到 MySQL 容器)。

然而,除了容器之间互相访问,主机和容器之间的互相访问也是非常常见的。容器访问主机可以使用 host.docker.internal,而主机访问容器则必须使用 IP。这非常不方便,尤其是需要通过 SSH 隧道访问一些没有通过 Nginx 放通对外服务端口的容器时,我不得不先打开 Portainer 面板 / 使用 SSH 连接服务器,查询到对应容器分配的 IP 后再进行连接。

这显然很不优雅。在此之前,我的解决方法是调整 Docker network 的 DHCP 规则,自动分配仅使用 172.18.0.128/25 段,而将前 127 个地址保留下来(网关占用 172.18.0.1),然后手动将一些经常需要访问的容器 IP 静态分配到这个保留范围内。这样,我就可以通过固定的 IP 访问容器,而不需要每次查询了。

然而,这个实现也不怎么优雅。一方面,这个分配关系完全由人工维护,随着分配到固定 IP 的容器数量增加难免会出现分配重复的问题;另一方面,这个保留段的大小也不好把握,保留多了会造成 IP 浪费(虽然有些杞人忧天,如果一台服务器上真的跑了 128+ 个容器那应该加服务器罢),少了则会不够用。同时,IP 相对而言还是不如语义化的容器名容易记忆,使用时也容易忘记对应关系。

因此,我决定探索一种能在主机通过容器名获取容器对应 IP,从而访问对应容器的方案。显然,这需要我们给主机提供一个能解析容器名的 DNS 服务器。

约定

为了与网络内其他主机相区分,我们约定在主机解析 Docker 容器时,一律通过 容器名.docker 解析。

通过 Docker API 自行实现

确定需求之后,我们很快就能自然而然想到一种解决方案:在本地部署一个 DNS 服务器,当查询的域名为 *.docker 时,就调用 Docker 提供的 RESTful API,查询容器列表,找到对应的容器,然后返回其 NetworkSettings/Networks/network名称/IPAMConfig/IPv4Address 作为 A 记录的值即可。

然而,查询之后,我没有发现写好的开源项目。于是我懒了,决定放弃这种解决方案。

通过 CoreDNS 进行 DNS 请求重写 + 转发

实际上,我们已经有了一种通过 DNS 查询容器名的实现了:Docker 的内置 DNS 127.0.0.11:53。然而,这个 DNS 服务器仅在容器内可用,并且不支持添加自定义后缀进行分流。

因此,我们的需求便转换为了以下几点:

  1. 运行一个 DNS 服务器,监听主机的 DNS 请求。
  2. 对于非 .docker 结尾的查询,直接转发给常规 DNS 或返回失败(利用系统 DNS 的主备机制,排序靠前的 DNS 查询失败时会继续查询靠后的)。
  3. 对于 容器名.docker 格式的查询,将查询请求重写为 容器名 形式。
  4. 容器名 形式查询请求转发给 Docker 内置 DNS 127.0.0.11:53,并返回结果。

既然请求要转发给 Docker 内置的 DNS,那么这个 DNS 服务器显然必须要运行在容器里。考虑到这个功能并不复杂,我们需要一个轻量、支持按规则转发/重写的 DNS 服务器。

这里我选择了 CoreDNS,一个基于 Golang 的轻量 DNS 服务器。它是基于配置文件的,且拥有丰富的内置插件,其中 forward 插件提供了 DNS 转发功能,rewrite 提供了请求重写功能,而且也足够轻量。

首先,我们阅读官方文档后,写出如下配置文件:

docker.:53 {
    log
    rewrite name regex (.*)\.docker {1}
    forward . 127.0.0.11:53
}

首先,我们通过 docker.:53 {} 块定义了一个在 53 端口监听,且只处理 docker. 一级域名下解析的 DNS 服务器。随后,通过 log 插件开启日志,通过 rewrite name 语句调用 rewrite 模块,将查询目标满足 (.*)\.docker 正则表达式的请求重写,去掉后面的 .docker 部分,保留前面的主机名。最后,通过 forward . 127.0.0.11:53 将重写后的请求全部转发给 Docker 内置 DNS 处理。

随后,我们部署一个运行在容器中的 CoreDNS 服务,将其加入我们的 network,为其手动指定一个 IP,并让其加载这个配置文件。

假设容器 IP 为 172.18.0.11,我们只要将 172.18.0.11:53 加入主机系统的备选 DNS 即可。

由于我不使用 NetworkManager 和 systemd-resolved,因此只要直接在 /etc/resolv.conf 中加入一行 nameserver 172.18.0.11:53 即可。

保存之后尝试 ping 一个 容器名.docker 的域名,发现能正确 ping 通。

附:关于域名的解释

上文 docker. 形式的域名在日常生活中使用频率不算特别高,因此在此解释一下:

一般来说,完整的域名末尾以 . 开始,一个 . 表示的是顶级域名,处理 . 域名解析的权威 DNS 服务器也就是著名的 13 台根服务器。

随后的 com. / net. 等为一级域名,但是命名上也称为顶级域名 Top Level Domain(TLD),由对应的注册商进行管理解析。

在此基础上,我们注册的 allenyou.wang. 这种则是二级域名,以此类推还有三级四级域名。

总之,在权威 DNS 中,真正的域名一定是以 . 结尾的。

附:一个可用的 Dockerfile

FROM coredns/coredns:latest

RUN cat << EOF > /Corefile \
docker.:53 { \
    log \
    rewrite name regex (.*)\.docker {1} \
    forward . 127.0.0.11:53 \
} \
EOF

ENTRYPOINT ["/coredns"]

CMD ["-c", "/Corefile"]