吕木云
在日常使用Docker构建微服务架构的过程中,我们经常会遇到一个问题:多个容器之间是如何通过名字互相访问的?DNS是怎么做到的?
从底层机制讲清楚Docker的DNS系统
1.容器间通信的前提:同一个网络
Docker默认会创建一个叫bridge的网桥网络。所有未指定网络的容器,都会被分配到这个bridge网络中。
在这个默认网络中,虽然每个容器都有一个独立的IP地址,但要实现通过容器名访问其他容器,就必须依赖Docker提供的DNS服务。
⚠️注意:只有在用户自定义的bridge网络中,容器名解析才默认开启!默认的bridge网络不支持容器名解析!
2.Docker的内置DNS是如何工作的?
Docker在每个容器启动时,会将容器的/etc/resolv.conf文件指向一个特殊的DNS地址:127.0.0.11
这个地址并不是真的公网DNS,而是DockerDaemon内置的DNS服务器。
这个DNS有以下作用:
解析外部域名(比如访问百度、Google)
解析容器内部服务名(比如web,db等容器名)
它的背后是Docker的embeddedDNSserver,工作机制大概如下:
1️⃣容器发出DNS查询请求(查某个服务名)
2️⃣请求发到127.0.0.11(docker的内部DNS)
3️⃣DockerDNS根据网络配置,找到对应容器的IP地址
4️⃣将结果返回给发起请求的容器
3.实验验证:容器名访问是否生效?
我们创建一个自定义网络,并启动两个容器测试下
#创建一个自定义bridge网络dockernetworkcreatemynet#启动容器A,名字叫webdockerrun-it--rm--nameweb--networkmynetbusyboxsh#启动容器B,在这个网络中尝试pingwebdockerrun-it--rm--networkmynetbusyboxsh
在B容器中输入:
pingweb
你会发现,DNS能自动解析出web的IP,这就说明Docker的内置DNS正常工作啦
4.自定义服务名(别名)怎么设置?
有时候我们希望容器访问的名字不是容器名,而是我们指定的服务名。Docker也支持这一点:
dockerrun-it--rm\--networkmynet\--namemydb\--network-aliasdatabase\busyboxsh
然后在其他容器中,就可以通过database这个名字访问它
5.与外部DNS的协同
Docker的embeddedDNS并不是万能的,它在无法解析服务名时,会把请求转发给/etc/resolv.conf中指定的上游DNS。
这意味着:
外部网络访问正常(比如你容器内pingwww.baidu.com)
内部容器名也能解析
DockerDNS是中间层代理
这个设计非常巧妙!兼顾了内外网的域名解析。
6.容器DNS失效的常见问题
❌没有使用自定义网络,导致DNS解析失败
❌使用了host网络,容器直接共享宿主机网络,无法使用Docker的DNS
❌被resolv.conf修改或者挂载了宿主机DNS文件
❌某些VPN环境导致容器DNS路由异常
解决方法建议:
尽量使用自定义bridge网络
检查/etc/resolv.conf是否被覆盖
检查Docker网络配置dockernetworkinspect
总结
Docker容器之间的DNS解析,其实是靠DockerDaemon内置的DNS服务(监听在127.0.0.11)来实现的,它能让容器通过服务名互相访问,还支持alias、自定义网络、多级域名等能力。
一是湖北枝江酒业股份有限公司被要求补税8500万元,因这笔税款被追溯至1994年,使得税务“倒查30年”成为舆论焦点。二是宁波博汇化工科技股份有限公司3月份收到当地税务要求补税5亿元的通知,最近企业宣布停产。来源:红网
作者:生卓
编辑:杜家瑜
本文为红辣椒评论 原创文章,仅系作者个人观点,不代表红网立场。转载请附原文出处链接和本声明。