容器化dns服务

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 容器化dns服务 之前将一个小应用使用docker compose部署之后,遇到一个问题,修改域名解析的IP。之前在虚拟机上可以直接修改hosts文件, 在docker容器中修改就比较麻烦,修改主机hosts文件也没有效果。 为了解决这个问题,引入了dnsmasq作为dns服务器。由于主机上本

容器化dns服务

之前将一个小应用使用docker compose部署之后,遇到一个问题,修改域名解析的IP。之前在虚拟机上可以直接修改hosts文件,
在docker容器中修改就比较麻烦,修改主机hosts文件也没有效果。

为了解决这个问题,引入了dnsmasq作为dns服务器。由于主机上本身已经有docker环境,因此也打算把dnsmasq放到容器中去运行。
首先是选择容器,在docker hub上下载量最多的是 andyshinn/dnsmasq 镜像。这个镜像的最大优势就是简单,整个镜像只有6M多。
对于无法访问外网的docker主机来说,部署比较方便。当然,这个镜像最大的劣势也是简单,没有提供配置文件,也无法可视化配置,使用时需要对dnsmasq有一定的了解。本文后面会介绍到刚开始使用遇到的不方便的地方。

安装

由于真正部署这个镜像的服务器无法访问外网,因此不能直接拉去docker镜像,暂时在一台可以访问外网的机器上拉取,然后导出,最后在机器上重新加载的方式来进行安装。也就是

  1. docker pull andyshinn/dnsmasq
  2. docker save andyshinn/dnsmasq > dnsmasq.tar
  3. scp dnsmasq.tar admin@xxx:.
  4. docker load < dnsmasq.tar

这样镜像就算是安装完成了。

启动

启动镜像前,参考了该镜像文档中的启动命令:


docker run -p 53:53/tcp -p 53:53/udp --cap-add=NET_ADMIN andyshinn/dnsmasq -S /consul/10.17.0.2

同时,看了下这个镜像的Dockerfile:


FROM alpine:3.2
RUN apk -U add dnsmasq
EXPOSE 53 53/udp
ENTRYPOINT ["dnsmasq", "-k"]

可以发现,这个镜像真是简单至极。默认就是运行了dnsmasq -k,即强制让dnsmasq运行在前端。然后dnsmasq没有任何特殊的配置,都需要启动过的时候手工指定。

而示例中的启动命令,有这几个含义:

  • 将容器的53端口(TCP和UDP)映射到主机上,这是dns的标准端口
  • 增加NET_ADMIN参数,使得容器中的进程可以修改网络配置
  • 给dnsmasq传递参数,针对.consul后缀的域名,使用10.17.0.2这个上游dns服务器进行解析

这样的启动方式,当然是无法满足需求的。dnsmasq命令的参数,可以在这个文档中进行查询。如果仅仅是解析一个域名,可以通过–address参数指定,域名和IP格式和上面类似:


docker run -p 53:53/tcp -p 53:53/udp --cap-add=NET_ADMIN andyshinn/dnsmasq --address /api.test.com/127.0.0.1

这样容器启动之后,就可以解析api.test.com这个域名到127.0.0.1。

应用

启动容器还是比较方便,然后就是将这个dns服务提供给其他docker容器使用。docker在启动参数中支持通过–dns指定dns服务器地址(指定后,会修改启动容器的/etc/resolv.conf文件)。如果在docker-compose中使用,可以在yml文件中增加dns项。

这样,容器启动之后,就可以使用自己搭建的dns服务了。然而,并没有~

NAT模式下dns服务的失效

首先遇到的问题,是容器中的服务仍然无法解析域名。使用docker exec命令进入容器,ping了域名还是提示无法解析。排查dnsmasq的日志没有输出。

由于dnsmasq解析日志不太好排查,查询了手册之后发现,可以通过–log-facility参数指定日志输出,将容器启动参数改成:


docker run -p 53:53/tcp -p 53:53/udp --cap-add=NET_ADMIN andyshinn/dnsmasq --address /api.test.com/127.0.0.1 -q --log-facility=-

这样可以将dnsmasq的日志输出到标准错误,也就能够在当前命令行中查看到。(如果在docker run的时候使用了-d参数放到了后台执行,可以直接通过docker logs来查看输出)

再次到应用容器中ping域名,会发现dnsmasq实际上已经完成了域名解析,但是域名解析的来源IP都是docker0设备的IP。如果将应用容器的dns服务器地址,修改成dnsmasq容器的内网地址,则解析正常。因此判断这个解析错误,可能和两个容器都运行在NAT模式中有关。

将dns容器改成host模式:


docker run --net=host --cap-add=NET_ADMIN andyshinn/dnsmasq --address /api.test.com/127.0.0.1 -q --log-facility=-

在将应用容器的dns服务器地址修改成主机的IP,可以发现能够正常解析域名。

dns解析自动更新

按照上面方式启动dns容器,可以正常工作。但是如果要增加解析记录,需要重新启动这个容器。文档里面有提到dnsmasq可以通过向进程发送SIGHUP信号,重新加载文件:

When it receives a SIGHUP, dnsmasq clears its cache and then re-loads /etc/hosts and /etc/ethers and any file given by –dhcp-hostsfile, –dhcp-hostsdir, –dhcp-optsfile, –dhcp-optsdir, –addn-hosts or –hostsdir. The dhcp lease change script is called for all existing DHCP leases. If –no-poll is set SIGHUP also re-reads /etc/resolv.conf. SIGHUP does NOT re-read the configuration file.

也就是说,如果通过–addn-hosts或者–hostsdir参数指定的文件(夹),可以通过信号来触发dnsmasq重新加载。为了方便区分,最终采用了后者,既–hostsdir指定hosts文件夹。

首先,在主机上创建一个文件夹和一个文件,写入需要解析的域名:


mkdir hosts
echo '127.0.0.1 a.test.com' > hosts/common

然后启动容器的时候,设置挂载卷,将这个目录共享给容器,同时指定这个目录未hostsdir:


docker run --net=host --cap-add=NET_ADMIN -v /home/admin/hosts:/media andyshinn/dnsmasq --addn-hosts=/media/common -q --log-facility=-

这样,如果需要新增解析记录,需要两步:

  1. 在主机hosts目录中,新增一条记录:echo 'b.test.com' >> hosts/common
  2. 向dns容器发送信号,使其重新加载文件:docker kill -s HUP 2beb1d9f3554

这样虽然还需要手工操作,但是无须再重新运行dns容器。


转载自:https://coolex.info/blog/511.html

目录
相关文章
|
7天前
|
监控 负载均衡 Cloud Native
ZooKeeper分布式协调服务详解:面试经验与必备知识点解析
【4月更文挑战第9天】本文深入剖析ZooKeeper分布式协调服务原理,涵盖核心概念如Server、Client、ZNode、ACL、Watcher,以及ZAB协议在一致性、会话管理、Leader选举中的作用。讨论ZooKeeper数据模型、操作、会话管理、集群部署与管理、性能调优和监控。同时,文章探讨了ZooKeeper在分布式锁、队列、服务注册与发现等场景的应用,并在面试方面分析了与其它服务的区别、实战挑战及解决方案。附带Java客户端实现分布式锁的代码示例,助力提升面试表现。
28 2
|
1月前
|
网络协议 Linux
Linux DNS服务详解——DNS主从架构配置
Linux DNS服务详解——DNS主从架构配置
407 4
|
1月前
|
域名解析 缓存 网络协议
Linux DNS服务详解——DNS基础知识
Linux DNS服务详解——DNS基础知识
72 1
|
2月前
|
SQL 监控 数据库连接
数字安全网:深入解析服务容错的三大绝招“
数字安全网:深入解析服务容错的三大绝招“
22 1
|
3月前
|
域名解析 网络协议
IP协议, TCP协议 和DNS 服务分别是干什么的?
IP协议, TCP协议 和DNS 服务分别是干什么的?
233 0
|
18天前
|
Kubernetes 网络协议 Docker
Docker 容器的DNS
Docker 容器的DNS
23 1
|
21天前
|
关系型数据库 MySQL Nacos
【深入浅出Nacos原理及调优】「实战开发专题」采用Docker容器进行部署和搭建Nacos服务以及“坑点”
【深入浅出Nacos原理及调优】「实战开发专题」采用Docker容器进行部署和搭建Nacos服务以及“坑点”
45 1
|
25天前
|
存储 安全 编译器
【C++ 17 泛型容器对比】C++ 深度解析:std::any 与 std::variant 的细微差别
【C++ 17 泛型容器对比】C++ 深度解析:std::any 与 std::variant 的细微差别
47 1
|
1月前
|
域名解析 缓存 网络协议
探索Qt 网络编程:网络地址与服务类全解析
探索Qt 网络编程:网络地址与服务类全解析
54 0
|
1月前
|
存储 缓存 调度
C++关联容器深度解析:提升数据结构操作的艺术
C++关联容器深度解析:提升数据结构操作的艺术
74 0

推荐镜像

更多