一、简介
企业中常用的web架构主要的目的是实现高可用及其容灾备份,说白了就是让用户有更好的用提体验,一个架构的可用性只有在经历过上线后接受用户的使用才能体现出其稳定性及其不足之处。利用周末的时间出于无聊,所以想总结以前所学的知识,本文主要介绍lvs,keepalived,nginx-proxy,等常用服务的搭建及其原理。
二、lvs概述及NAT、DR原理
专题一:
lvs-nat(Linux virtual system)是根据请求报文的目标ip和目标端口进行调度转发至后端某主机。在实际生产中常用的模型有NAT(Network Address Translation)和DR(Direct Routing),下面我们从这两开始展开叙述。
NAT模型拓扑图:
<a href="http://s5.51cto.com/wyfs02/M01/89/D7/wKiom1gfHYDioZKxAAHmvS2vKsI619.png" target="_blank"></a>
原理:客服端发起请求,请求到达lvs前端调度器,通过将请求报文中的目标IP地址和目标端口修改为后端真实服务器的IP地址和端口实现转发,后端真实主机处理请求后又将响应报文以相同的原理经过调度器响应给用户。如图所示,开始时源地址为CIP目标地址为VIP,经过LVS发生目标地址转换,将VIP转换为RIP,则源地址为CIP目标地址为RIP,real server发现目标地址为自己地址时开始拆报文并给出响应。
实战部署:
VIP1:10.1.10.65
DIP1:192.168.184.128
RIP1:192.168.184.129
RIP2:192.168.184.130
要求:两台real server网关要指向DIP.VIP和DIP需在同一个网段,且为内网地址
1
2
3
4
5
6
7
8
9
<code>Real server1:</code>
<code> </code><code>route add default gw 192.168.184.128 </code>
<code>Real server2:</code>
<code>Virutal server:</code>
<code>ipvsadm -A -t 10.1.10.65:80 -s rr </code>
<code>ipvsadm -a -t 10.1.10.65:80 -r 192.168.184.129 -m -w 1 </code>
<code>ipvsadm -a -t 10.1.10.65:80 -r 192.168.184.130 -m -w 2 </code>
<code>echo</code> <code>1></code><code>/proc/sys/net/ipv4/ip_forward</code> <code>#开启ip_forward转发功能</code>
示例图:
两台real server网关必须指向directory routing.
<a href="http://s5.51cto.com/wyfs02/M02/89/D8/wKiom1gfLPmjw7qMAAA8BoNd2T8614.png-wh_500x0-wm_3-wmp_4-s_2253454510.png" target="_blank"></a>
<a href="http://s3.51cto.com/wyfs02/M02/89/D5/wKioL1gfLR6yra7yAAA8BoNd2T8421.png" target="_blank"></a>
添加ipvsadm规则,使用默认权重为1,进行测试,实验结果为轮询。
<a href="http://s3.51cto.com/wyfs02/M00/89/D8/wKiom1gfLR7RcxjOAABHT6s6aRY588.png" target="_blank"></a>
修改默认权重为1:2,及其静态调度算法为加权轮询,测试结果为1:2加权轮询。
<a href="http://s3.51cto.com/wyfs02/M00/89/D5/wKioL1gfLR7gDp2YAABfKVg-Asc695.png" target="_blank"></a>
总结:lvs-nat重要的注意点为路由需指向直连路由,需开启转发功能,常用的静态和动态轮询算法有:rr,wrr,SH,DH,LC,WLC.SED,NQ,LBLC,LBLCR等
专题二:
lvs-dr(lvs director routing)是通过将请求报文重新封装其MAC地址进行转发,源MAC地址为DIP所在接口的IP地址,而目标MAC地址为从后端挑选出来的real server的MAC地址IP首部不发生变换 。
DR模型拓扑图:
<a href="http://s4.51cto.com/wyfs02/M02/89/D5/wKioL1gfMe6xxtpJAAINScCOfME443.png" target="_blank"></a>
原理:lvs-dr模型中,请求报文的目标地址和源地址为发生改变,而在dr上重新封装了MAC地址,最大的改变是后端的real server和dr都配备了VIP地址,而real server响应用户请求时不经由dr进行转发,直接将报文发送给客服端主机。在每个real server和dr上配有VIP地址,因此为了达到real sever不直接响应dr,需修改内核参数,将VIP绑定在lo回环接口的别名上,两参数分别为:arp_ignore,arp_announce。
VIP1:10.1.10.88
DIP1:10.1.10.65
RIP1:10.1.10.66
RIP2:10.1.10.67
要求:需调整内核参数,为每一个需要VIP地址的主机添加VIP地址
10
11
12
13
14
15
16
17
18
19
<code>real server01:</code>
<code>echo</code> <code>2 ></code><code>/proc/sys/net/ipv4/conf/all/arp_announce</code>
<code>echo</code> <code>2 ></code><code>/proc/sys/net/ipv4/conf/lo/arp_announce</code>
<code>echo</code> <code>1 ></code><code>/proc/sys/net/ipv4/conf/all/arp_ignore</code>
<code>echo</code> <code>1 ></code><code>/proc/sys/net/ipv4/conf/lo/arp_ignore</code>
<code>ifconfig</code> <code>lo:0 10.1.10.66 netmask 255.255.255.255 broadcast 10.1.10.66 </code>
<code>route add -host 10.1.10.66 dev lo:0 </code>
<code>real server02</code>
<code>ifconfig</code> <code>lo:0 10.1.10.67 netmask 255.255.255.255 broadcast 10.1.10.67</code>
<code>route add -host 10.1.10.67dev lo:0</code>
<code>virtual server</code>
<code>ifconfig</code> <code>eno16777736:0 10.1.10.66 netmask 255.255.255.255 broadcast 10.1.10.65</code>
<code>ipvsadm -A -t 10.1.10.88:80 -s rr </code>
<code>ipvsadm -a -t 10.1.10.88:80 -r 10.1.10.66 -g -w 1 </code>
<code>ipvsadm -a -t 10.1.10.88:80 -r 10.1.10.67 -g -w 2</code>
上诉均可使用脚本实现如下:
20
21
22
23
24
25
26
27
<code>#!/bin/bash</code>
<code>#</code>
<code>vip=</code><code>'10.1.10.99'</code>
<code>iface=</code><code>'eno16777736:0'</code>
<code>mask=</code><code>'255.255.255.255'</code>
<code>port=</code><code>'80'</code>
<code>rs1=</code><code>'10.1.10.66'</code>
<code>rs2=</code><code>'10.1.10.67'</code>
<code>scheduler=</code><code>'wrr'</code>
<code>type</code><code>=</code><code>'-g'</code>
<code>case</code> <code>$1 </code><code>in</code>
<code>start)</code>
<code> </code><code>ifconfig</code> <code>$iface $vip netmask $mask broadcast $vip up</code>
<code> </code><code>iptables -F</code>
<code> </code><code>ipvsadm -A -t ${vip}:${port} -s $scheduler</code>
<code> </code><code>ipvsadm -a -t ${vip}:${port} -r ${rs1} $</code><code>type</code> <code>-w 1</code>
<code> </code><code>ipvsadm -a -t ${vip}:${port} -r ${rs2} $</code><code>type</code> <code>-w 2</code>
<code> </code><code>;;</code>
<code>stop)</code>
<code> </code><code>ipvsadm -C</code>
<code> </code><code>ifconfig</code> <code>$iface down</code>
<code>*)</code>
<code> </code><code>echo</code> <code>"Usage $(basename $0) start|stop"</code>
<code> </code><code>exit</code> <code>1</code>
<code>esac</code>
示例图:
设置为加权轮询权重比为1:2,及其添加ipvs规则
实验结果如下图,实现1:2说明实验成功 ,可修改其调度算法再次验证其结果的真实性。
<a href="http://s3.51cto.com/wyfs02/M01/89/D6/wKioL1gfPeKhoazAAAAfeRAtUno360.png" target="_blank"></a>
总结:lvs-dr重点在于给dr及其real server配置VIP地址,并且向real server设置内核参数,是的real server中的lo:0上的VIP地址不直接响应dr,而是由real server直接响应客服端请求。上诉实验中有个缺点,当real server主机服务提供服务时,用户请求页面很不友好,需给出相应的应急页面。
三、实战keepalived高可用集群解决方案
专题三:
keepalived是vrrp协议的实现,原生设计目的是为了高可用ipvs服务,keepalived能够配置文件中的定义生成ipvs规则,并能够对各RS的健康状态进行检测;通过共用的虚拟IP地址对外提供服务;在主备模式下,每个热备组内同一时刻只有一台主服务器提供服务,其他服务器处于冗余状态,若当前在线的服务器宕机,其虚拟IP地址将会被其他服务器接替(优先级决定接替顺序),实现高可用为后端主机提供服务。主/备,备/主双主模式下,两台调度器均处于提供服务的状态,当其中一台服务器宕机或出现故障时,VIP将会“漂移”至另一台服务器。
keepalived拓扑图:
<a href="http://s5.51cto.com/wyfs02/M01/89/D6/wKioL1gfRFXBcPUrAAI5zcL6kXg609.png" target="_blank"></a>
原理:keepalived的实现主要是由vrrp协议,自定义vrrp_instance,vrrp_server和一些检测脚本一起共同合作,实现自动分配VIP,和ipvs规则,少去了手动配置ipvs的麻烦,同时还能够配置应急服务器、用简单脚本能在恢复模式下进行系统修复等,比起lvs优越性更高。
DIP1:10.1.10.65
VIP2:10.1.10.99
DIP2:10.1.10.68
要求:配置过程中,主的优先级要高于备,同时将主备的state状态互调。
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<code>编辑</code><code>/etc/keepalived/keepalived</code><code>.conf,将此配置文件拷贝至另一台keepalived主机修改相应部分即可。</code>
<code>! Configuration File </code><code>for</code> <code>keepalived</code>
<code>global_defs {</code>
<code> </code><code>notification_email {</code>
<code>root@localhost</code>
<code> </code><code>}</code>
<code> </code><code>notification_email_from [email protected]</code>
<code> </code><code>smtp_server 127.0.0.1</code>
<code> </code><code>smtp_connect_timeout 30</code>
<code> </code><code>router_id centos7s</code>
<code> </code><code>vrrp_mcast_group4 224.0.4.18</code>
<code>}</code>
<code>vrrp_instance VI_1 {</code>
<code> </code><code>state MASTER </code><code>#实例状态信息</code>
<code> </code><code>interface eno16777736</code>
<code> </code><code>virtual_router_id 51</code>
<code> </code><code>priority 100 </code><code>#优先级</code>
<code> </code><code>advert_int 1</code>
<code> </code><code>authentication {</code>
<code> </code><code>auth_type PASS</code>
<code> </code><code>auth_pass frSAmesXYSSFmw</code>
<code> </code><code>}</code>
<code> </code><code>virtual_ipaddress {</code>
<code> </code><code>10.1.10.88 dev eno16777736 labeleno16777736:0</code>
<code> </code><code>notify_master </code><code>"/etc/keepalived/notify.sh master"</code> <code>#此处调用脚本实现发邮件给管理员</code>
<code> </code><code>notify_backup </code><code>"/etc/keepalived/notify.sh backup"</code>
<code> </code><code>notify_fault </code><code>"/etc/keepalived/notify.sh fault"</code>
<code>vrrp_instance VI_2 {</code>
<code> </code><code>state BACKUP</code>
<code> </code><code>virtual_router_id 52</code>
<code> </code><code>priority 99</code>
<code> </code><code>auth_pass frSAresXYSSFmw</code>
<code> </code><code>10.1.10.99 dev eno16777736 labeleno16777736:1</code>
<code> </code><code>notify_master </code><code>"/etc/keepalived/notify.sh master"</code>
<code>virtual_server 10.1.10.88 80 {</code>
<code> </code><code>delay_loop 6 </code>
<code> </code><code>lb_algo rr </code><code>#调度算法</code>
<code> </code><code>lb_kind DR </code><code>#负载均衡模型</code>
<code> </code><code>protocol TCP</code>
<code> </code><code>sorry_server 127.0.0.1 80 </code><code>#应急服务器</code>
<code> </code><code>real_server 10.1.10.66 80 {</code>
<code> </code><code>weight 1</code>
<code> </code><code>HTTP_GET {</code>
<code> </code><code>url {</code>
<code> </code><code>path /</code>
<code>status_code 200</code>
<code> </code><code>}</code>
<code> </code><code>connect_timeout 3</code>
<code> </code><code>nb_get_retry 3</code>
<code> </code><code>delay_before_retry 3</code>
<code> </code><code>}</code>
<code> </code><code>real_server 10.1.10.67 80 {</code>
<code> </code><code>weight 2</code>
<code>virtual_server 10.1.10.99 80 {</code>
<code> </code><code>delay_loop 6</code>
<code> </code><code>lb_algo rr</code>
<code> </code><code>lb_kind DR</code>
<code> </code><code>sorry_server 127.0.0.1 80</code>
示例图:
配置完成后启动keepalived会自动生成ipvs规则
<a href="http://s3.51cto.com/wyfs02/M00/89/DB/wKiom1gf5rjTqcPGAABekt5FTBU366.png" target="_blank"></a>
测试结果为设定的轮询算法,同时模拟后端某服务器故障,查看相应的服务器是否能符合正常需求
<a href="http://s2.51cto.com/wyfs02/M00/89/D8/wKioL1gf5rmgVJvtAABH9I8mKXQ896.png" target="_blank"></a>
测试结果为设定的轮询算法,同时模拟后端服务器故障,查看相应的ipvs规则是否自动生成
<a href="http://s3.51cto.com/wyfs02/M01/89/D8/wKioL1gf5rqDiIGwAABQPxTSCtc032.png" target="_blank"></a>
测试结果为设定的轮询算法,同时模拟后端某服务器故障,查看相应的应急页面是否能符合正常需求
<a href="http://s2.51cto.com/wyfs02/M01/89/DB/wKiom1gf5rnAzhu2AAArTAGdv1s669.png" target="_blank"></a>
总结:在keepalived中需注意的事项为,配置vrrp_instance实例时需注意主备的状态及其优先级,比起lvs来说keepalived总体配置简单,且ipvs规则自动生成省去了“人工智能”。
四、nginx前端调度高可用实战
专题四:
对于一个大型网站来说,负载均衡是永恒的话题。随着硬件技术的迅猛发展,越来越多的负载均衡硬件设备涌现出来,如F5 BIG-IP、Citrix NetScaler、Radware等等,虽然可以解决问题,但其高昂的价格却往往令人望而却步,因此负载均衡软件仍然是大部分公司的不二之选。nginx作为webserver的后起之秀,其优秀的反向代理功能和灵活的负载均衡策略受到了业界广泛的关注。
nginx高可用拓扑图:
<a href="http://s1.51cto.com/wyfs02/M00/89/D8/wKioL1gf7RiAYSMIAAEKNSCZfoY169.png" target="_blank"></a>
原理:nginx是高度模块化的应用程序,其中nginx_proxy模块即可实现负载均衡,将前端的用户请求通过调度算法分摊在后端的真实主机,达到均衡的效果。nginx_proxy也依赖于vrrp协议来实现VIP的自动分配和漂移,和keepalived不同的是nginx将不会生成ipvs规则,而是使用upstream模块将前端请求转发至后端。
VIP1:10.1.10.88
VIP2:10.1.10.99
RIP1:10.1.10.66
RIP2:10.1.10.67
要求:在配置过程中开启nginx的upstream模块,并代理到后端主机
<code>notification_email {</code>
<code>notification_email_from keepalived@localhost</code>
<code>smtp_server 127.0.0.1</code>
<code>smtp_connect_timeout 30</code>
<code>router_id centos7s</code>
<code>vrrp_mcast_group4 224.0.120.18</code>
<code>vrrp_script chk_down { </code><code>#在恢复模式下实现将机器更新,或更换服务器</code>
<code>script </code><code>"[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"</code>
<code>interval 1</code>
<code>weight -5</code>
<code>vrrp_script chk_nginx { </code><code>#健康状态检测,检测nginx是否存活</code>
<code>script </code><code>"killall -0 nginx && exit 0 || exit 1"</code>
<code>state MASTER</code>
<code>interface eno16777736</code>
<code>virtual_router_id 53</code>
<code>priority 100</code>
<code>advert_int 1</code>
<code>authentication {</code>
<code>auth_type PASS</code>
<code>auth_pass 9818sss1</code>
<code>virtual_ipaddress {</code>
<code>10.1.10.88</code><code>/16</code> <code>dev eno16777736</code>
<code>track_script {</code>
<code>chk_down</code>
<code>chk_nginx</code>
<code>notify_master </code><code>"/etc/keepalived/notify.sh master"</code>
<code>notify_backup </code><code>"/etc/keepalived/notify.sh backup"</code>
<code>notify_fault </code><code>"/etc/keepalived/notify.sh fault"</code>
<code>state BACKUP</code>
<code>virtual_router_id 54</code>
<code>priority 98</code>
<code>auth_pass 9818rss1</code>
<code>10.1.10.99</code><code>/16</code> <code>dev eno16777736</code>
<code>http {</code>
<code>upstream websrvs {</code>
<code> </code><code>server 10.1.10.66:80 weight=1;</code><code>#设置其权重为1,默认为1</code>
<code> </code><code>server 10.1.10.67:80 weight=1;</code><code>#设置其权重为1,默认为1</code>
<code> </code><code>server 127.0.0.1:8080 backup;</code><code>#设置其应急响应服务器</code>
<code>...</code>
<code>server{</code>
<code>location / {</code>
<code> </code><code>#root /usr/share/nginx/html;</code>
<code> </code><code>index index.php index.html index.htm;</code>
<code> </code><code>proxy_pass http:</code><code>//websrvs</code><code>; </code><code>#代理至后端主机</code>
示例图示:
配置vrrp实例后将遵循自动生成VIP地址及其自动实现地址漂移
<a href="http://s3.51cto.com/wyfs02/M02/89/DF/wKiom1ggHauQuvcDAACKs8r-r4Q818.png" target="_blank"></a>
模拟将后端一台服务器故障和全体故障的测试结果
<a href="http://s3.51cto.com/wyfs02/M01/89/DF/wKiom1ggHamyFU8jAABEiXLKclc787.png" target="_blank"></a>
实例中内嵌检测nginx健康状态检测脚本当nginx宕机时,则会自动将权重减去5,VIP地址漂移至优先级高的主机
<a href="http://s3.51cto.com/wyfs02/M01/89/DC/wKioL1ggHaqgf1PiAACKLadXapA774.png" target="_blank"></a>
总结:在所有的负载均衡调度中nginx配置最为简单而且高效,同时很灵活,所以可根据自己业务需求将选择合适自己企业的解决方案。
本文转自chengong1013 51CTO博客,原文链接:http://blog.51cto.com/purify/1870216,如需转载请自行联系原作者