前言

在创建docker容器时,有时候我们想自定义docker容器的DNS和主机名,那么docker实现的秘诀就是利用虚拟文件在挂载容器的三个相关文件。

进入容器后使用mount命令即可看到三个相关etc文件。

/dev/vda1 on /etc/resolv.conf type ext4 (rw,noatime,data=ordered)/dev/vda1 on /etc/hostname type ext4 (rw,noatime,data=ordered)/dev/vda1 on /etc/hosts type ext4 (rw,noatime,data=ordered)

打开网易新闻 查看精彩图片

这么一来,当宿主机的dns信息发生更改后,所有docker容器的dns会通过/etc/resolv.conf文件得到及时更新。
默认bridge网络中配置DNS

如果要配置全部容器的DNS,可以在 /etc/docker/daemon.json 文件中增加以下内容来设置

{"dns" : ["114.114.114.114","8.8.8.8"]}//这样每次启动的容器 DNS 自动配置为 114.114.114.114 和 8.8.8.8。

如果需要手动的给指定容器设置,则通过如下参数在docker run时设置即可。

-h HOSTNAME 或者 --hostname=HOSTNAME //设定容器的主机名,它会被写到容器内的 /etc/hostname 和 /etc/hosts。但它在容器外部看不到,既不会在 docker container ls 中显示,也不会在其他的容器的 /etc/hosts 看到 --dns-opt=OPTION //通过将options 行写入容器的/etc/resolv.conf 设置DNS解析器使用的选项。有关有效选项的列表,请参阅resolv.conf文档--link=CONTAINER_NAMEor ID:ALIAS//在run 容器时使用此选项为新容器的/etc/hosts 添加了一个名为ALIAS的额外条目,指向由CONTAINER_NAME_or_ID标识的CONTAINER_NAME_or_ID的IP地址。这使得新容器内的进程可以连接到主机名ALIAS 而不必知道其IP --dns=IP_ADDRESS //添加 DNS 服务器到容器的 /etc/resolv.conf 中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名 --dns-search=DOMAIN //设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的主机时,DNS 不仅搜索 host,还会搜索 host.example.com

注意:如果在容器启动时没有指定最后两个参数,Docker 会默认用主机上的 /etc/resolv.conf 来配置容器。

打开网易新闻 查看精彩图片

用户自定义网络内嵌DNS

用户自定义网络中的内嵌dns和默认bridge网络dns工作机制有所不同,然而从docker1.10开始,docker实现了一个内嵌的dns服务器。它为任何使用有效name 、net-alias 或使用link 别名所创建的容器提供内置的服务发现能力。

当然你不应该自己去管理容器内的/etc/hosts 、/etc/resolv.conf 等文件,而是使用以下的Docker选项。

--name=CONTAINER-NAME//使用--name配置的容器名称用于发现用户自定义网络中的容器。 //内嵌DNS服务器维护容器名称及其IP地址(在容器连接的网络上)之间的映射--network-alias=ALIAS//除如上所述的--name 以外,容器可使用用户自定义网络中的一个或多个--network-alias (或docker network connect 命令中的--alias 选项)发现。//内嵌DNS服务器维护特定用户自定义网络中所有容器别名及IP之间的映射。 通过在 docker network connect 命令中使用--alias 选项.//容器可在不同的网络中具有不同的别名--link=CONTAINER_NAME:ALIA//在run 容器时使用此选项为嵌入式DNS提供了一个名为ALIAS 的额外条目,指向由CONTAINER_NAME 标识的IP地址。 //当使用--link 时,嵌入式DNS将确保只在使用了--link 选项的容器上进行本地化查找。//这允许新容器内的进程连接到容器,而不必知道其名称或IP--dns=[IP_ADDRESS...]//如果嵌入式DNS服务器无法从容器中解析名称、解析请求,嵌入式DNS服务器将使用--dns 选项传递的IP地址转发DNS查询。 //这些--dns IP地址由嵌入式DNS服务器管理,不会在容器的/etc/resolv.conf 文件中更新--dns-search=DOMAIN...//当容器内使用主机名不合格时所设置的域名。这些--dns-search 选项由嵌入式DNS服务器管理,不会在容器的/etc/resolv.conf 文件中更新。//当容器进程尝试访问host 并且搜索域 example.com被设置时,//例如,DNS逻辑不仅将查找host ,还将查找host.example.com--dns-opt=OPTION... //设置DNS解析器使用的选项。 这些选项由嵌入式DNS服务器管理,不会在容器的/etc/resolv.conf 文件中更新。//有关有效选项的列表,请参阅resolv.conf文档

在没有--dns=IP_ADDRESS... ,--dns-search=DOMAIN... 或--dns-opt=OPTION... 选项的情况下,Docker使用宿主机的/etc/resolv.conf ( docker daemon 运行的地方)。 在执行此操作时,damon会从宿主机的原始文件中过滤出所有localhost IP地址nameserver 条目。

过滤是必要的,因为宿主机上的所有localhost地址都不可从容器的网络中访问。过滤之后,如果容器的/etc/resolv.conf 文件中没有更多的nameserver 条目,daemon会将公共Google DNS名称服务器(8.8.8.8和8.8.4.4)添加到容器的DNS配置中。 如果daemon启用了IPv6,则也会添加公共IPv6 Google DNS名称服务器(2001:4860:4860::8888 以及 2001:4860:4860::8844)

注意 :如果您需要访问宿主机的localhost解析器,则必须修改宿主机上的DNS服务,以便侦听从容器内可访问的non-localhost地址。
注意 :DNS服务器始终为127.0.0.11 。