内容简介: 关于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服务并能正常解析; 来自我的博客: 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包: 172.22.10.50就会以有没有收到主服务器发来的vrrp包来确认主服务器是否存活; 如果能收到,证明主服务器存活,不作出任何动作; 如果收不到vrrp包,就会认为主服务器宕机,这时就会启动VIP来接管服务,顶替主服务器业务; 我们再看看两边的ip: 大家会看到172.22.10.237上会有一个辅助ip ens192:0,这个ip就是VIP了;而172.22.10.50上没有(enp8s0是另一个网卡) 这时,我把172.22.10.237关机来模拟宕机,再看172.22.10.50的网卡: 这个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的解析请求,这样对外提供一个172.22.10.156这个ip就可以了; 但是......如果nginx这台服务器出了问题呢?想这种单点故障在企业中都是严禁出现的,各种服务都是有备用方案以备不测的; 既然这样那就换个架构,网上最常见的lvs高可用负载均衡: 对,这样的话就需要4台服务器了,且占用了很多资源; 那如果把nginx负载的功能塞进两台服务器本身呢? 对,这也是公司搭建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的网卡上; 并且在172.22.1050上能接收到vrrp的数据包: 四、配置防火墙转发; 最后一步! 配置防火墙转发, 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就接收到了,继而进行解析、反馈;