使用 docker 搭建小型的 DNS 服务器

需求背景

使用 docker-composebridge 模式启动多个 docker服务,每个 docker-compose 启动一个服务,在宿主机的 ip 地址有可能变动的情况下,如何实现不同服务之间的通信?

  • 大型项目: 直接上 k8s,使用 k8s中成熟的 serviceingress 插件,直接一步搞定
  • 很小型的项目: 把多个服务,写到同一个 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

posted @ 2023-12-09 00:07  沧海一声笑rush  阅读(96)  评论(0编辑  收藏  举报