docker container DNS配置介绍和源码分析
来源:互联网 发布:it专业 编辑:程序博客网 时间:2024/06/04 18:54
本文主要介绍了docker容器的DNS配置及其注意点,重点对docker 1.10发布的embedded DNS server进行了源码分析,看看embedded DNS server到底是个啥,它是如何工作的。
Configure container DNS
DNS in default bridge network
nameserver IP_ADDRESS
添加到容器内的/etc/resolv.conf中。可以配置多个。–dns-search=DOMAIN…在该容器启动时,将DOMAIN添加到容器内/etc/resolv.conf的dns search列表中。可以配置多个。–dns-opt=OPTION…在该容器启动时,将OPTION添加到容器内/etc/resolv.conf中的options选项中,可以配置多个。说明:
如果docker run时不含
--dns=IP_ADDRESS..., --dns-search=DOMAIN..., or --dns-opt=OPTION...
参数,docker daemon会将copy本主机的/etc/resolv.conf,然后对该copy进行处理(将那些/etc/resolv.conf中ping不通的nameserver项给抛弃),处理完成后留下的部分就作为该容器内部的/etc/resolv.conf。因此,如果你想利用宿主机中的/etc/resolv.conf配置的nameserver进行域名解析,那么你需要宿主机中该dns service配置一个宿主机内容器能ping通的IP。如果宿主机的/etc/resolv.conf内容发生改变,docker daemon有一个对应的file change notifier会watch到这一变化,然后根据容器状态采取对应的措施:
- 如果容器状态为stopped,则立刻根据宿主机的/etc/resolv.conf内容更新容器内的/etc/resolv.conf.
- 如果容器状态为running,则容器内的/etc/resolv.conf将不会改变,直到该容器状态变为stopped.
- 如果容器启动后修改过容器内的/etc/resolv.conf,则不会对该容器进行处理,否则可能会丢失已经完成的修改,无论该容器为什么状态。
- 如果容器启动时,用了–dns, –dns-search, or –dns-opt选项,其启动时已经修改了宿主机的/etc/resolv.conf过滤后的内容,因此docker daemon永远不会更新这种容器的/etc/resolv.conf。
- 注意: docker daemon监控宿主机/etc/resolv.conf的这个file change notifier的实现是依赖linux内核的inotify特性,而inotfy特性不兼容overlay fs,因此使用overlay fs driver的docker deamon将无法使用该/etc/resolv.conf自动更新的功能。、
Embedded DNS in user-defined networks
在docker 1.10版本中,docker daemon实现了一个叫做embedded DNS server
的东西,用来当你创建的容器满足以下条件时:
- 使用自定义网络;
- 容器创建时候通过
--name
,--network-alias
or--link
提供了一个name;
docker daemon就会利用embedded DNS server对整个自定义网络中所有容器进行名字解析(你可以理解为一个网络中的一种服务发现)。
因此当你启动容器时候满足以上条件时,该容器的域名解析就不应该去考虑容器内的/etc/hosts, /etc/resolv.conf,应该保持其不变,甚至为空,将需要解析的域名都配置到对应embedded DNS server中。具体配置参数及说明如下:
nameserver IP_ADDRESS
全部由对应的embedded DNS server管理,并不会更新到容器内的/etc/resolv.conf.–dns-search=DOMAIN…在该容器启动时,会将–dns-search配置的DOMAIN们配置到the embedded DNS server,并不会更新到容器内的/etc/resolv.conf。–dns-opt=OPTION…在该容器启动时,会将–dns-opt配置的OPTION们配置到the embedded DNS server,并不会更新到容器内的/etc/resolv.conf。说明:
- 如果docker run时不含
--dns=IP_ADDRESS..., --dns-search=DOMAIN..., or --dns-opt=OPTION...
参数,docker daemon会将copy本主机的/etc/resolv.conf,然后对该copy进行处理(将那些/etc/resolv.conf中ping不通的nameserver项给抛弃),处理完成后留下的部分就作为该容器内部的/etc/resolv.conf。因此,如果你想利用宿主机中的/etc/resolv.conf配置的nameserver进行域名解析,那么你需要宿主机中该dns service配置一个宿主机内容器能ping通的IP。- 注意容器内/etc/resolv.conf中配置的DNS server,只有当the embedded DNS server无法解析某个name时,才会用到。
embedded DNS server源码分析
所有embedded DNS server相关的代码都在libcontainer项目中,几个最主要的文件分别是/libnetwork/resolver.go
,/libnetwork/resolver_unix.go
,sandbox_dns_unix.go
。
OK, 先来看看embedded DNS server对象在docker中的定义:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
可见,resolver就是embedded DNS server,每个resolver都bind一个sandbox,并定义了一个对应的dns.Server,还定义了外部DNS对象列表,但embedded DNS server无法解析某个name时,就会forward到那些外部DNS。
Resolver Interface定义了embedded DNS server必须实现的接口,这里会重点关注SetupFunc()和Start(),见下文分析。
dns.Server的实现,全部交给github.com/miekg/dns,限于篇幅,这里我将不会跟进去分析。
从整个container create的流程上来看,docker daemon对embedded DNS server的处理是从endpoint Join a sandbox开始的:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
sandbox join a sandbox的流程中,会调用sandbox. populateNetworkResources做网络资源的设置,这其中就包括了embedded DNS server的启动。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
sandbox.startResolver是流程关键:
- 通过sanbdox.rebuildDNS生成了container内的/etc/resolv.conf
- 通过resolver.SetExtServers(sb.extDNS)设置embedded DNS server的forward DNS list
- 通过resolver.SetupFunc()启动两个随机可用端口作为embedded DNS server(127.0.0.11)的TCP和UDP Linstener
- 通过resolver.Start()对容器内的iptable进行设置(见下),并通过miekg/dns启动一个nameserver在53端口提供服务。
下面我将逐一介绍上面的各个步骤。
sanbdox.rebuildDNS
sanbdox.rebuildDNS负责构建容器内的resolv.conf,构建规则就是第一节江参数配置时候提到的:
- Save the external name servers in resolv.conf in the sandbox
- Add only the embedded server’s IP to container’s resolv.conf
- If the embedded server needs any resolv.conf options add it to the current list
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
resolver.SetExtServers
设置embedded DNS server的forward DNS list, 当embedded DNS server不能解析某name时,就会将请求forward到ExtServers。代码很简单,不多废话。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
resolver.SetupFunc
启动两个随机可用端口作为embedded DNS server(127.0.0.11)的TCP和UDP Linstener。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
resolver.Start
resolver.Start中两个重要步骤,分别是:
- setupIPTable设置容器内的iptables
- 启动dns nameserver在53端口开始提供域名解析服务
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
先来看看怎么设置容器内的iptables的:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
在reexecSetupResolver()中清楚的定义了iptables添加outputChain 和postroutingchain,将到容器内的dns query请求重定向到embedded DNS server(127.0.0.11)上的udp/tcp两个随机可用端口,embedded DNS server(127.0.0.11)的返回数据则重定向到容器内的53端口,这样完成了整个dns query请求。
模型图如下:
贴一张实例图:
到这里,关于embedded DNS server的源码分析就结束了。当然,其中还有很多细节,就留给读者自己走读代码了。
福利
另外,借用同事wuke之前画的一个时序图,看看embedded DNS server的操作在整个容器create流程中的位置,我就不重复造轮子了。
- docker container DNS配置介绍和源码分析
- docker container DNS配置介绍和源码分析
- Docker源码分析(七):Docker Container网络 (上)
- Docker源码分析(七):Docker Container网络 (上)
- Docker源码分析(七):Docker Container网络 (上)
- Docker源码分析(八):Docker Container网络(下)
- [docker 1.13 源码分析]第二章 Docker container创建
- Docker源码分析(七):Docker Container网络 (上)
- Docker源码分析(八):Docker Container网络(下)
- 【docker 17 源码分析】 docker run container 源码分析二 docker start
- Docker container 容器介绍
- 用白话的方式介绍Docker和Container技术
- docker技术和container技术
- Docker中的image和container
- 【Tomcat9源码分析】Container、Pipeline和Vavle设计
- docker containerd 架构和源码简单分析
- Docker存储驱动devicemapper介绍和配置
- Docker源码分析:Docker架构
- C++动态内存管理(比较C动态内存管理)
- android下载解析xml
- GPIO口超强总结
- [bzoj4356][ceoi2014] wall
- PS之卡通徽章制作
- docker container DNS配置介绍和源码分析
- 链表倒序
- shell局部变量和全局变量
- js基本操作2
- Unable to find setter method for attribute: [commandName]
- Unity3D热更新之网页运行工具
- 你充满电了吗?——序(笔记)
- 【VS开发】vector<ImageFeatures> features(num_images)析构报错
- Hibernate 工具类(个人编写,初次了解,还未完善)