内容简介:
关于dns服务器,有的公司是使用公共的dns,如:222.222.222.222、114.114.114.114等,也有的公司选择搭建自己的dns,能灵活更改配置来满足公司内部的需求;我所在公司是一家做语音呼叫、转发的客服公司,属于中小型企业,客服人数近千人,为了满足不同线路的需求,所以公司选择了自己搭建dns服务器;

通过本场 chat 包含了以下知识技能:
1.DNS服务---dnsmasq的使用和搭建;
2.nginx负载均衡---tcp、udp;
3.keepalived 高可用;
4.简单的iptables转发功能;

目录:
第一章、DNS服务器搭建和使用---dnsmasq
第二章、nginx负载均衡;
第三章、keepalived高可用;
第四章、使用nginx搭建高可用DNS服务器;
说明:一、二、三章之间没有必然的联系,每一章都是独立的知识点,到第四章会整合起来;

第一章---DNS服务器搭建和使用---dnsmasq
介绍:dnsmasq是一个轻便型的dns服务,特别适合局域网使用,搭建方便、配置简单、功能也很齐全;
1.安装dnsmasq: yum install dnsmasq -y
2、Dnsmasq的配置文件为:/etc/dnsmasq.conf
编辑/etc/dnsmasq.conf
找到下列参数修改或添加:
port=53 //服务开启的端口,改成其他端口也无妨,但要注意selinux;
resolv-file=/etc/resolv.dnsmasq.conf //会从这个文件中寻找上游dns服务器
strict-order //去掉前面的#
addn-hosts=/etc/dnsmasq.hosts //在这个目录里面ip和域名dnsmasq
listen-address=127.0.0.1,172.22.10.50 //监听地址,172.22.10.50是本机的ip地址;
3、修改/etc/resolv.conf
/etc/resolv.conf 定义了本机的dns地址(在本身不是dns服务器之前),将该文件内容注释并添加 nameserver 127.0.0.1 ,使用自己作为dns服务器;
4、创建 /etc/resolv.dnsmasq.conf 文件并添加上游dns服务器的地址
默认没有 /etc/resolv.dnsmasq.conf 这个文件的,需要按照dnsmasq配置文件中参数定义的路径创建;
touch /etc/resolv.dnsmasq.conf
echo 'nameserver 114.114.114.114' >> /etc/resolv.dnsmasq.conf

  • 以 114.114.114.114 为上游的dns服务器;
    resolv.dnsmasq.conf 中设置的是真正的nameserver,可以用电信、联通等公共的DNS,有可以多添加几个nameserver;
    5、创建 /etc/dnsmasq.hosts 文件
    touch /etc/dnsmasq.hosts
    vim 编辑 /etc/dnsmasq.hosts 文件,添加ip对应的域名,例如:
    192.168.111.111 xpt.redhat.cn
    这样,当客户端要求解析 xpt.redhat.cn 时,会解析为192.168.111.111 ;
    6.设置Dnsmasq开机启动并启动Dnsmasq服务:
    systemctl start dnsmasq.service
    systemctl enable dnsmasq.service
    7.检查,看53端口是否打开,
    netstat -tunlp | grep 53 查看Dnsmasq是否正常启动:

    netstat -tlunp|grep 53

    tcp 0 0 0.0.0.0:53 0.0.0.0: LISTEN 2491/dnsmasq
    tcp 0 0 :::53 ::: LISTEN 2491/dnsmasq
    udp 0 0 0.0.0.0:53 0.0.0.0: 2491/dnsmasq
    udp 0 0 :::53 :::

到此处,一个简单的dns服务器就搭建成功了,主要是理解配置文件中参数定义的文件路径都是什么作用;

可以使用 自己的windows电脑做测试,将自己windows的dns修改成搭建dns服务器的ip;
运行cmd,使用host 或者nslookup命令都可以:
hsot xpt.redhat.cn
nslookup xpt.redhat.cn
工作流程:
windows向dns服务器发送请求解析 xpt.redhat.cn ,dns服务器接收到之后先去 /etc/dnsmasq.hosts 文件中寻找有误匹配的ip、域名,如果有则返回域名对应的ip,如果没有则向 /etc/resolv.dnsmasq.conf 中定义的上级dns服务器发送请求解析;

来自我的博客: https://blog.51cto.com/13577495/2293863

第二章---nginx负载均衡---tcp、udp
Nginx (engine x) 是一款轻量级的Web 服务器 、反向代理服务器及电子邮件(IMAP/POP3)代理服务器,同时nginx也可以实现简单的负载均衡功能。
nginx官网下载地址:http://nginx.org ,发布版本分为 Linux 和 windows 版本。也可以下载源码,编译后运行。
1.安装
安装nginx所需的依赖包:
yum -y install gcc gcc-c++ autoconf automake
yum -y install zlib zlib-devel openssl openssl-devel pcre-devel
//下载之后解压nginx:
tar xzvf nginx-1.10.3.tar.gz
//进入nginx目录
cd nginx-1.10.3
//预编译,因为要负载udp,所以需要编译进去一个模块;
./configure --with-stream
//make编译、安装
make && makeinstall

此时,nginx就会安装到默认目录: /usr/local/nginx 下了;
/usr/local/nginx/conf/nginx.conf 就是nginx的主配置文件了

如果负载的是tcp,如web服务,配置:
user www www;
worker_processes 4;
error_log logs/error.log info;
pid logs/nginx.pid;
events {
use epoll;
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';
access_log  logs/access.log  main;
sendfile        on;
tcp_nopush     on;
keepalive_timeout  65;
gzip  on;
upstream test1 {
    server 172.22.10.237:80;
    server 172.22.10.50:80;
}
server {
    listen       80;
    server_name  www.xpt.com;
    charset utf-8;
    access_log  logs/host_80.access.log  main;
    location / {
        proxy_next_upstream http_502 http_504 error timeout invalid_header;
        proxy_pass http://test1;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
    }
    location = /50x.html {
        root   html;
    }
}

}
重点在于 upstream test1 和 server ;
server定义了监听本服务器的端口,当客户端请求该端口的时候会将请求分流到 test1 中定义的主机ip或端口;
这是负载web服务的方法,如果负载dns请求是不是修改一下分流的端口就可以了?答案是不行的,因为负载tcp和udp的配置方法是不同的;
***修改配置文件,负载udp;
worker_processes 4;
events {
worker_connections 1024;
}
stream {
upstream dns {
server 172.22.10.237:53 weight=1;
server 172.22.10.50:53 weight=1;
}
server {
listen 53 udp;
proxy_connect_timeout 1s;
proxy_timeout 20s;
proxy_pass dns;
}
}

***这样,客户端的dns请求就会按照nginx的配置被送到172.22.10.237和172.22.10.50上,前提是两服务器上都搭建有dns服务并能正常解析;
nginx搭建双活、高可用DNS服务器
来自我的博客: https://blog.51cto.com/13577495/2334063
三、keepalived高可用;
Keepalived是基于vrrp协议的一款高可用软件;何为高可用?举个例子吧,有两台服务器,一主一备,主服务器负责对外提供服务,备用服务器则以备不测,当主服务器宕机时,备用服务器就顶替主服务器对外提供服务;keepalived就是为两台服务器提供一个共同的虚拟ip---VIP,平时VIP在主服务器上,当主服务宕机,VIP就跑到备用服务器上,引导客户端访问流量到备用服务器,从而实现高可用;

1.安装: yum install keepalived -y
2.主配置文件: /etc/keepalived/keepalived.conf
操作演示:
环境为两台centos7的服务器: 172.22.10.237 和 172.22.10.50 ;两台都安装了keepalived;

172.22.10.237:/etc/keepalived/keepalived.conf 配置:
! Configuration File for keepalived
global_defs {
router_id ld444 //定义路由标识信息,相同局域网唯一
}
vrrp_instance VI_1 {
state MASTER //状态参数,master/backup,只是说明
interface ens192 //虚IP地址放置的网卡位置
virtual_router_id 88 //同一家族要一致,同一个集群id一致
priority 150 //优先级决定是主还是备,越大越优先
unicast_src_ip 172.22.10.237 //填写自己的ip
unicast_peer {
172.22.10.50 //同组中其他服务器ip
}
advert_int 1 //主备通讯时间间隔
authentication {
auth_type PASS
auth_pass 8888 //基于密码认证;
}
virtual_ipaddress {
172.22.10.210/24 dev ens192 label ens192:0 //设备之间使用的虚拟ip地址
}
}

172.22.10.237:/etc/keepalived/keepalived.conf 配置:
! Configuration File for keepalived
global_defs {
router_id ld555
}
vrrp_instance VI_1 {
state BACKUP
interface enp4s0
virtual_router_id 88
priority 100
unicast_src_ip 172.22.10.50
unicast_peer {
172.22.10.237
}
advert_int 1
authentication {
auth_type PASS
auth_pass 8888
}
virtual_ipaddress {
172.22.10.210/24 dev enp4s0 label enp4s0:0
}
}

***如果两台服务器之间的交换机开启了组播功能的话就不需要 unicast_src_ip 和 unicast_peer 的配置了,
这个配置是为了防止交换机没有开启组播功能而无法将vrrp协议发送到指定的备用服务器上;
在两条服务器上启动服务并加入开机启动:
systemctl start keepalived //启动服务;
systemctl enable keepalived //加入开机启动;

这个时候172.22.10.237就会每隔一秒往172.22.10.50发送vrrp包:
nginx搭建双活、高可用DNS服务器
172.22.10.50就会以有没有收到主服务器发来的vrrp包来确认主服务器是否存活;
如果能收到,证明主服务器存活,不作出任何动作;
如果收不到vrrp包,就会认为主服务器宕机,这时就会启动VIP来接管服务,顶替主服务器业务;
nginx搭建双活、高可用DNS服务器
我们再看看两边的ip:
nginx搭建双活、高可用DNS服务器
nginx搭建双活、高可用DNS服务器
大家会看到172.22.10.237上会有一个辅助ip ens192:0,这个ip就是VIP了;而172.22.10.50上没有(enp8s0是另一个网卡)
这时,我把172.22.10.237关机来模拟宕机,再看172.22.10.50的网卡:
nginx搭建双活、高可用DNS服务器
这个VIP会跑到enp4s0:0上;
注意,当172.22.10.237恢复之后就会继续向172.22.10.50发送vrrp包,172.22.10.50收到vrrp包后就知道主服务器恢复了,
就会关掉VIP,让主服务器继续接管;
keepalived最初是为lvs负载均衡设计的,但并不是一定要和lvs在一起才能使用,keepalived还有其他更进一步的功能,
比如:邮件报警、健康检查、配合lvs做负载均衡、主备双活高了用......等;

四、使用nginx搭建高可用DNS服务器;
到这里就是最后的架构、搭建了;如何做一个高可用的dns服务器呢?
学过上面的知识后,首先可能想到的就是这样:
nginx搭建双活、高可用DNS服务器
让nginx负载dns的解析请求,这样对外提供一个172.22.10.156这个ip就可以了;
但是......如果nginx这台服务器出了问题呢?想这种单点故障在企业中都是严禁出现的,各种服务都是有备用方案以备不测的;
既然这样那就换个架构,网上最常见的lvs高可用负载均衡:
nginx搭建双活、高可用DNS服务器
对,这样的话就需要4台服务器了,且占用了很多资源;
那如果把nginx负载的功能塞进两台服务器本身呢?
nginx搭建双活、高可用DNS服务器
对,这也是公司搭建dns服务的最终架构方案了;两台服务器一主(172.22.10.237)一备(172.22.10.50),实现高可用也实现了负载均衡;客户端只需要向172.22.10.210这个ip请求就可以了;其中还有端口和防火墙转发的知识,后面会一一讲明;
大致的工作流程:
1.客户端向172.22.10.210发送解析请求;
2.172.22.10.210将请求因导至主服务器(172.22.10.237);
3.主服务器(172.22.10.237)的接收请求,通过nginx进行负载均衡,将请求根据配置规则分发到自己的dns服务和备用服务器的dns服务

准备环境:
一、将172.22.10.237和172.22.10.50上搭建dns服务器,我这里使用的dnsmasq,你也可以换成别的;
搭建流程就按照第一章的搭建即可,不过要将dns开启的端口换成别的!!! 我把dns的端口换成了 5454,你也可以换成其他端口,
但是不要占用53端口!因为后面nginx要使用53端口来接收客户端的请求;
然后开启dns服务,设置开机启动;

二、搭建nginx服务;
由于是分发udp数据,所以编译的时候需要 --with-stream 模块;直接上我的配置了
172.22.10.237和172.22.10.50上 nginx.conf 的配置相同:
#user nobody;
worker_processes 4;
events {
worker_connections 1024;
}
stream {
upstream dns {
server 172.22.10.237:5353 weight=1;
server 172.22.10.50:5354 weight=1;
}
server {
listen 53 udp;
proxy_connect_timeout 1s;
proxy_timeout 20s;
proxy_pass dns;
}
}
然后启动nginx,这样nginx就占用了53端口,客户端请求的时候就可以代理接收;

三、172.22.10.237和172.22.10.50搭建keepalived;
上面已经说过如何搭建了,这里就不再啰嗦,直接上我的配置了;
172.22.10.237的/etc/keepalived/keepalived.conf :
! Configuration File for keepalived
global_defs {
router_id ld444
}
vrrp_instance VI_1 {
state MASTER
interface ens192
virtual_router_id 88
priority 150
unicast_src_ip 172.22.10.237
unicast_peer {
172.22.10.50
}
advert_int 1
authentication {
auth_type PASS
auth_pass 8888
}
virtual_ipaddress {
172.22.10.210/24 dev ens192 label ens192:0
}
}

172.22.10.50的/etc/keepalived/keepalived.conf :
! Configuration File for keepalived
global_defs {
router_id ld555
}
vrrp_instance VI_1 {
state BACKUP
interface enp4s0
virtual_router_id 88
priority 100
unicast_src_ip 172.22.10.50
unicast_peer {
172.22.10.237
}
advert_int 1
authentication {
auth_type PASS
auth_pass 8888
}
virtual_ipaddress {
172.22.10.210/24 dev enp4s0 label enp4s0:0
}
}

两服务器都启动keepalived并设置加入开机自启;
这时172.22.10.210这个ip就会挂在主服务器172.22.10.237的网卡上;
nginx搭建双活、高可用DNS服务器
并且在172.22.1050上能接收到vrrp的数据包:
nginx搭建双活、高可用DNS服务器
四、配置防火墙转发;
最后一步! 配置防火墙转发,
PREROUTING 表示数据包进入服务器的第一道“大门”,需要在这里做一个nat转发;
在172.22.10.237上执行:
iptables -t nat -A PREROUTING -d 172.22.10.210 -p udp --dport 53 -j DNAT --to 172.22.10.237:53
在172.22.10.50上执行:
iptables -t nat -A PREROUTING -d 172.22.10.210 -p udp --dport 53 -j DNAT --to 172.22.10.50:53

-d : 目标主机
-p : 协议
--dport : 目标端口
-j DNAT : 转发
--to : 转发到
上面执行后效果就是:将客户端访问我172.22.10.210的53端口的udp协议转发给自己172.22.10.XXX的53端口;
明白了吧,再说一遍流程,客户端请求 172.22.10.210 ,dns解析会找53端口,刚到服务器就被防火墙拦下了,并且转发到了主ip的53端口,
53端口的请求被nginx接收,nginx按照配置规则进行负载分发到172.22.10.237:5454 和 172.22.10.50:5454,这样dnsmasq就接收到了,继而进行解析、反馈;