为什么要对dns做负载呢?
答案不是因为请求压力过大,而是将CDN业务按一定比例分流.例如我有几家cdn合作的公司,我可以通过权重比达到我期望的流量分摊值。
架构图:
服务器ip列表:
1.1 Master-DR1安装与配置
yum install keepalived ipvsadm
[root@localhost ~]# more/etc/keepalived/keepalived.conf
Keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
}
#smtp_server 127.0.0.1
#smtp_connect_timeout 30
#router_id LVS_MH_1
lvs_id LVS_DNS_01
}
vrrp_sync_group VG1 {
group {
VI_1
VI_GATEWAY
}
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 60
priority 150
advert_int 1
lvs_sync_daemon_inteface eth0
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.214.85
}
}
vrrp_instance VI_GATEWAY {
state MASTER
interface eth1
lvs_sync_daemon_inteface eth1
virtual_router_id 61
priority 150
advert_int 1
authentication{
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.211.85
}
}
virtual_server 192.168.214.85 53 {
delay_loop 60
lb_algo wlc
lb_kind NAT
#nat_mask 255.255.255.0
persistence_timeout 10
protocol UDP
real_server 192.168.211.79 53 {
weight 5
MISC_CHECK {
connect_timeout 5
misc_path "/scripts/dnscheck 192.168.211.79"
}
}
real_server 192.168.211.83 53 {
weight 3
MISC_CHECK {
connect_timeout 5
misc_path "/scripts/dnscheck 192.168.211.83"
}
}
real_server 192.168.211.84 53 {
weight 2
MISC_CHECK {
connect_timeout 5
misc_path "/scripts/dnscheck 192.168.211.84"
}
}
}
1.2Slave-DR2安装与配置
yum install keepalived ipvsadm
[root@localhost ~]# more/etc/keepalived/keepalived.conf
Keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
}
#smtp_server 127.0.0.1
#smtp_connect_timeout 30
#router_id LVS_MH_1
lvs_id LVS_DNS_01
}
vrrp_sync_group VG1 {
group {
VI_1
VI_GATEWAY
}
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 60
priority 100
advert_int 1
lvs_sync_daemon_inteface eth0
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.214.85
}
}
vrrp_instance VI_GATEWAY {
state BACKUP
interface eth1
lvs_sync_daemon_inteface eth1
virtual_router_id 61
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.211.85
}
}
virtual_server 192.168.214.85 53 {
delay_loop 60
lb_algo wlc
lb_kind NAT
#nat_mask 255.255.255.0
persistence_timeout 10
protocol UDP
real_server 192.168.211.79 53 {
weight 5
MISC_CHECK {
connect_timeout 5
misc_path "/scripts/dnscheck 192.168.211.79"
}
}
real_server 192.168.211.83 53 {
weight 3
MISC_CHECK {
connect_timeout 5
misc_path "/scripts/dnscheck 192.168.211.83"
}
}
real_server 192.168.211.84 53 {
weight 2
MISC_CHECK {
connect_timeout 5
misc_path "/scripts/dnscheck 192.168.211.84"
}
}
}
**通过以上配置,理论上来说dns请求会以50%请求进入DR1,30%请求进入DR2,20%的请求进入DR1.后面将会用脚本模拟用户请求来验证.**
1.3后端dns健康检查脚本
[root@localhost ~]# more /scripts/dnscheck
#!/usr/bin/env python
#opdevos.com Dns Healthy Check!
#Auth:jacky
import sys, DNS
query = "opdevos.com"
dns_server=sys.argv[1]
match_key="monitor"
#match_key="ok"
#DNS.DiscoverNameServers()
DNS.defaults['server']=[dns_server]
reqobj = DNS.Request()
try:
answerobj = reqobj.req(name = query, qtype = DNS.Type.TXT)
except:
print "Connection refused"
sys.exit(1)
if not len(answerobj.answers):
print "Not found."
sys.exit(1)
for item in answerobj.answers:
#print "%-5s %s" % (item['typename'], item['data'])
if match_key in item['data']:
#print "sucess!"
sys.exit(0)
else:
#print "match_key Error!"
sys.exit(1)
RS1与RS2,RS3安装与配置
yum install bind bind-utils -y
$TTL 3600
@ IN SOA ns1.opdevos.com support(
2018072301 ; serial
3600 ; refresh
900 ; retry
3600000; expire
1800) ; minimum
IN NS ns1.opdevos.com.
IN TXT "monitor"
ns1 IN A 192.168.214.85
www IN A 192.168.211.111
手动测试:
脚本测试:
dns_query.py
#!/usr/bin/env python
#coding=utf8
#Auth:Jacky
fromscapy.all import *
defDnsQuery(sip):
ip_header=IP(src=sip,dst="192.168.214.85")
udp_header=UDP(dport=53)
dns_header=DNS(id=1,qr=0,opcode=0,tc=0,rd=1,qdcount=1,ancount=0,nscount=0,arcount=0)#构造标准的DNS数据包
packet=ip_header/udp_header/dns_header
ans,unans=sr(packet,timeout=1,verbose=0)
type_dict=
#print ans[0]
for s,r in ans:
print "Received_IP:%s"%(r[IP].dst)
print "Query Domain:%s"%(r[DNS].qd.qname)
print "%s\t%s"%("Type","IP(Domain)")
print "-"*30
for i in xrange(15):
try:
print "%s\t%s"%(type_dict[r[DNS].an[i].type],r[DNS].an[i].rdata)
except:
pass
print "*"*30
for xin xrange(1,255):
ip="192.168.214."+str(x)
#print ip
DnsQuery(ip)
脚本执行结果:
[root@zabbix-agent tmp]# python dns_query.py
WARNING: No route found for IPv6 destination :: (no default route?)
Received_IP:192.168.214.12
Type IP(Domain)
------------------------------
A 192.168.211.111
分析RS1日志(从ip结尾1到10,落到这台的请求有5个):
分析RS2日志(从ip结尾1到10,落到这台的请求有3个):
分析RS3日志(从ip结尾1到10,落到这台的请求有2个):
总结如下:
lvs采用LVS的WLC算法,针对每台服务器指定不同的权重
如第1台:5,第2台:3,第3台:2,那么请求比率为:50%,30%,20%。
下一篇将提供zabbix对dns的监控.
领取专属 10元无门槛券
私享最新 技术干货