使用 docker 搭建小型的 DNS 服务器
需求背景
使用 docker-compose
以 bridge
模式启动多个 docker
服务,每个 docker-compose
启动一个服务,在宿主机的 ip
地址有可能变动的情况下,如何实现不同服务之间的通信?
- 大型项目: 直接上
k8s
,使用k8s
中成熟的service
和ingress
插件,直接一步搞定 - 很小型的项目: 把多个服务,写到同一个
docker-compose
中,然后使用服务名称,进行直接通信 - 中性项目: 一般就十几个服务的项目,写同一个 docker-compose中太臃肿,上
k8s
又有点大材小用了,此时可以考虑,自己搭建一个dns
服务器
搭建本地的DNS服务器
使用 host 模式,启动一个 dns 服务器
version: '3'
services:
dnsmasq:
image: 4km3/dnsmasq:2.85-r2
network_mode: host
cap_add:
- NET_ADMIN
此处建议使用host
模式启动dns
服务器。经过笔者测试,如果使用 bridge
启动,那么其他的 docker 容器,想要使用本机的dns 服务器,必须在 /etc/docker/daemon.json
文件中,明确指定本机的 ip
地址作为dns
解析服务器,才能在容器内解析到。而使用 host
模式则无需指定
修改本机 dns 服务器地址
修改 /etc/resolv.conf
文件,将本机的 ip 地址放在第一位
nameserver 10.0.70.210 # 把本机的 ip 放在第一个位
nameserver 10.0.92.1 # 这个是局域网默认分配的,不要动
nameserver 114.114.114.114 # 常用的 114
一般装好系统以后,网关会自动分配一个内网的 dns
服务器,这个由于在内网,所有速度要比直接去访问 114.114.114.114
要快,因此第二个和第三个,这两个都不建议动
添加域名解析配置
直接修改输注机的 /etc/hosts
文件,然后映射到容器内。同理,由于局域网的网关会分配一个dns
服务器的地址,这个内网服务器的地址,在一台新机上部署的时候,其实也并不是提前知道的。因为直接将本机的 /etc/resolv.conf
映射到容器内
此外,还有一些其他配置,
cat /etc/dnsmasq.conf
cache-size=1024 # 本地记录的缓存数量
all-servers # 强制向所有的 dns 服务器发送解析请求,哪个回复的最早用哪个
完善docker-compose文件
version: '3'
services:
dnsmasq:
image: 4km3/dnsmasq:2.85-r2
network_mode: host
volumes:
- /etc/hosts:/etc/hosts:ro
- /etc/resolv.conf:/etc/resolv.conf:ro
- /etc/dnsmasq.conf:/etc/dnsmasq.conf:ro
cap_add:
- NET_ADMIN
说明
使用 docker
启动容器,其实他的 /etc/resolv.conf
文件,是直接从主机复制过来的,所以只有当输注机的 /etc/resolv.conf
中添加上自己本身的 ip
时,才会使用本机的 dns
服务器进行解析。
参考文献
https://hub.docker.com/r/4km3/dnsmasq
https://www.cnblogs.com/pyyu/p/10318334.html
https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html