把bind运行在docker中
伴随着应用微服务化,大量应用跑在了容器之中,为了让容器的管理更可靠、可控并为上层应用提供更好的体验,更快的发布,更灵活的调度,容器云应运而生。
当各种上层应用跑在了容器之中,大家开始希望各种基础设施也能容器化,借助容器的特性和优势提供更好的服务,于是将DNS服务容器化成为了一个关注的话题。本文介绍一个最简单的bind容器化落地方案,基于ISC官方发布的docker镜像快速构建一个基于docker的DNS系统。
在docker hub中找到ISC官方bind镜像
ISC官方的docker镜像在hub中的链接:docker hub bind9
我们可以在docker hub的官网中搜索internetsystemsconsortium/bind9
即可看到ISC官方的bind9镜像。
下载bind镜像并启动容器实现一个简单的递归DNS
首先,我们要准备好一个已经安装了docker的环境,本文的实验环境是centos7.8。
使用docker search命令先看看是否能找到这个镜像,如下所示成功找到了Official ISC BING 9 Docker,而且是基于Ubuntu。
[root@localhost ~]# docker search bind9
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
resystit/bind9 Bind9 running on Alpine. 9Mo 47 [OK]
internetsystemsconsortium/bind9 Official ISC BIND 9 Docker, based on Ubuntu … 44
ubuntu/bind9 BIND 9 is a very flexible, full-featured DNS… 31
fike/bind9 Bind9 running on Debian Wheezy. Enjoy it and… 8 [OK]
conceptant/bind9-namedmanager This docker image implements BIND DNS server… 6 [OK]
emsi/bind9 Clean bind9 docker. Config in volume. 5 [OK]
mjkaye/bind9-alpine Bind9 running on Alpine Linux [amd64/armhf/a… 3
pwa666/bind9 Lightweight container with bind9 and webmin … 3
mbentley/bind9 2 [OK]
vinyldns/bind9 **DEPRECATED** BIND9 DNS Docker image for Vi… 1
zhusj/bind9 Bind 9.16 with Alpine Linux 1 [OK]
bantolph/bind9 arm64 build of the internetsystemsconsortium… 1
emsi/bind9-data emsi/bind9 data-only container. Please refer… 1 [OK]
prehley/bind9 Docker image for bind 1 [OK]
vandalirice/bind9 Bind9 docker image 0 [OK]
labradorcode/bind9 bind9 based on alpine 0
bratkartoffel/bind9 https://github.com/bratkartoffel/bind9-docker 0
yangzhaofengsteven/bind9 0
459below/bind9 A Docker image for bind9 0 [OK]
diverdane/bind9 0
mlinarik/bind9 0
gmelillo/bind9 0
sutaxyz/bind9 0
jchonig/bind9 Run ISC nameserver (bind9) in a container 0
neomediatech/bind9 Dockerized bind9 daemon, based on Ubuntu 0
[root@localhost ~]#
使用docker pull拉取镜像,本文测试时使用的是bind9.16版本
[root@localhost ~]# docker pull internetsystemsconsortium/bind9:9.16
9.16: Pulling from internetsystemsconsortium/bind9
Digest: sha256:52ea8c50223d031ce5b8fc60c4e465ff4897a9cfed227e21f5b00a77dcd23e64
Status: Image is up to date for internetsystemsconsortium/bind9:9.16
docker.io/internetsystemsconsortium/bind9:9.16
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
internetsystemsconsortium/bind9 9.16 748e4b634100 12 months ago 253MB
执行docker run启动容器
[root@localhost ~]# docker run -d --restart=always --publish 53:53/udp --publish 53:53/tcp --publish 127.0.0.1:953:953/tcp internetsystemsconsortium/bind9:9.16
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6e19e494742a internetsystemsconsortium/bind9:9.16 "/usr/sbin/named -g …" About a minute ago Up About a minute 0.0.0.0:53->53/tcp, 0.0.0.0:53->53/udp, 127.0.0.1:953->953/tcp serene_goldstine
容器启动后可以查看本机的53端口监听情况,然后可用dig命令测试一下运行的bind容器是否能做域名解析。
[root@localhost ~]# netstat -anp|grep 53
tcp 0 0 0.0.0.0:53 0.0.0.0:* LISTEN 3019/docker-proxy
tcp 0 0 127.0.0.1:953 0.0.0.0:* LISTEN 3007/docker-proxy
udp 0 0 0.0.0.0:53 0.0.0.0:* 3031/docker-proxy
unix 2 [ ACC ] STREAM LISTENING 27353 1048/master private/lmtp
[root@localhost ~]#
[root@localhost ~]# dig @127.0.0.1 www.baidu.com
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-16.P2.el7_8.6 <<>> @127.0.0.1 www.baidu.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6667
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;www.baidu.com. IN A
;; ANSWER SECTION:
www.baidu.com. 1200 IN CNAME www.a.shifen.com.
www.a.shifen.com. 300 IN A 110.242.68.4
www.a.shifen.com. 300 IN A 110.242.68.3
;; Query time: 4162 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Nov 12 17:05:03 CST 2022
;; MSG SIZE rcvd: 104
如果在启动容器过程中报错Docker之WARNING: IPv4 forwarding is disabled. Networking will not work
那么可按照如下方法解决。
vim /etc/sysctl.conf
#配置转发
net.ipv4.ip_forward=1
#重启服务,让配置生效
systemctl restart network
进入正在运行的bind容器中查看相关信息。
[root@localhost ~]# docker exec -ti 6e19e494742a /bin/sh
#
# ps -ef|grep named
bind 1 0 0 09:01 ? 00:00:00 /usr/sbin/named -g -c /etc/bind/named.conf -u bind
root 22 15 0 09:06 pts/0 00:00:00 grep named
#
# ls /etc/bind
bind.keys db.0 db.127 db.255 db.empty db.local named.conf named.conf.default-zones named.conf.local named.conf.options rndc.key zones.rfc1918
# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.3 LTS
Release: 20.04
Codename: focal
创建权威区搭建权威DNS
上面的小实验实现了一个基于bind容器的递归DNS,因为递归DNS如果没有特别特殊的需求,不涉及本地域名配置数据的持久化,那么基于此方式可以。而一旦要搭建权威DNS,涉及DNS记录数据的持久化,那么在启动容器时要考虑区数据的持久化以及一致性问题。
通过docker的volume可将宿主机的某个目录挂到容器中,还可以实现多个容器共用相同的一个目录下的数据文件。
执行docker run命令启动bind容器,此时主要volume参数的使用。
[root@localhost ~]# docker run -d --restart=always --publish 53:53/udp --publish 53:53/tcp --publish 127.0.0.1:953:953/tcp --volume /etc/bind --volume /var/cache/bind --volume /var/lib/bind --volume /var/log internetsystemsconsortium/bind9:9.16
5058038eb073ce71ca4656e94dec1a8b35538a8a09aa44cdc68fa2b7d02ed45a
[root@localhost ~]#
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5058038eb073 internetsystemsconsortium/bind9:9.16 "/usr/sbin/named -g …" 41 seconds ago Up 40 seconds 0.0.0.0:53->53/tcp, 0.0.0.0:53->53/udp, 127.0.0.1:953->953/tcp unruffled_noyce
进入到bind容器中创建test.com权威区和相关记录
# cat /etc/bind/named.conf.options
options {
directory "/var/cache/bind";
// forwarders {
// 0.0.0.0;
// };
dnssec-validation auto;
listen-on-v6 { any; };
};
zone "test.com." {
type primary;
file "/var/lib/bind/test.com.zone";
notify explicit;
};
# cat /var/lib/bind/test.com.zone
;
;
$ORIGIN .
$TTL 3600
test.com IN SOA ns1.test.com. mail.test.com. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
NS ns1.test.com.
$ORIGIN test.com.
ns1 IN A 172.16.29.170
www IN A 10.10.10.100
www IN AAAA 2000::1
执行rndc reload
命令
# rndc reload
server reload successful
测试此时可以正常解析到test.com权威区中的资源记录
(base) user1@bogon ~ % dig @172.16.29.170 www.test.com
; <<>> DiG 9.10.6 <<>> @172.16.29.170 www.test.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19041
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;www.test.com. IN A
;; ANSWER SECTION:
www.test.com. 3600 IN A 10.10.10.100
;; Query time: 0 msec
;; SERVER: 172.16.29.170#53(172.16.29.170)
;; WHEN: Sat Nov 12 17:51:25 CST 2022
;; MSG SIZE rcvd: 57
至此,一个简单的基于ISC官方docker bind镜像的实验就做完了。
而在实际的投产过程中,要考虑的细节比较多。例如:bind集群的技术架构,因为如果基于容器的动态扩缩容的方式,那么数据的一致性如何解决?此时建议可以考虑采用“多主”的方式,所有bind共享一份数据,或者采用“隐主”的方式。另外,bind运行在容器中的解析性能相比直接运行在宿主机上会有一定的下降。
总结
DNS属于重要的网络基础服务,是业务访问的入口,随着近年来微服务的演进,服务发现和注册的全新应用,DNS曝光度越来越高,也出现了不同形态的DNS。
在企业实际生产环境中,要注意在合适的场景下选择合适的技术方案。假如我们的DNS系统定位就是一套高可用的,面向所有租户提供跨集群服务的高性能、高可靠DNS服务。那么在多地部署高性能服务器并采用Anycast方式构建DNS系统或许比docker的方式更加可靠,毕竟DNS服务和上层应用不一样,它不一定需要那么灵活,但前提一定要可靠和可控。