scvmm 发表于 2019-1-5 10:24:47

使用lvs搭建负载均衡集群

  有时候,单台服务器的性能可能无法应付大规模的服务请求,且其一旦出现故障,就会造成用户在一段时间内无法访问。通过集群技术,可以在付出较低成本的情况下获得在性能、可靠性、灵活性方面的相对较高的收益。
  集群是一组相互独立的、通过网络互联的计算机组,并以单一系统的模式加以管理,或用于分摊负载,或用于增强可靠性,或用于高速计算。
  

  一、集群类型
  LB:Load Balancing,负载均衡集群,用于消除单点故障,当一个节点出现故障而无法正常提供服务时,自动、快速地切换到另外的节点上去;常见软件或实现方式有lvs, haproxy, nginx
  HA:High Availability,高可用集群,将客户端的请求遵从恰当的负载均衡原则分配给各节点的集群;heartbeat, corosync+pacemaker, cman+rgmanager, cman + pacemaker, keepalived
  HPC:High Performance Computing,高性能计算集群;hadoop
  

  二、lvs工作原理
  lvs由 ipvsadm/ipvs 这两段代码组成,ipvsadm是工作于用户空间的程序,用于编写规则(定义集群服务、调度标准,指明有哪些后端服务器等)并送给ipvs;ipvs是集成于内核中的真正实现调度功能的代码,工作于netfilter的INPUT链上,它会根据指定的调度标准确定将匹配的请求报文调度到哪台后端服务器,然后对请求报文做一定处理(或修改目标ip、或修改目标MAC等)并转到POSTROUTING链上发往相应的后端服务器
http://s2.运维网.com/wyfs02/M01/7E/6C/wKiom1b-UKejsr0jAABp1-8urn4482.png
  

  三、lvs相关术语
  director:调度器,即提供ipvsadm/ipvs,直接面向客户端请求,实现调度功能的主机
  real server:后端真实服务器,即真正处理客户端请求的服务器
  CIP:client ip
  VIP:virtual ip,客户端请求的目标ip,要配置在director上
  DIP:director ip
  RIP:real server ip
  

  四、lvs的类型
  1、lvs-nat
http://s1.运维网.com/wyfs02/M01/7E/67/wKioL1b-QerzQqtwAABejzYKSPA986.png
  这种模型中,响应报文会经由director转发回client,因此real server和director要位于同一子网中且real server的网关必须指向director,director会对请求报文和响应报文分别做DNAT(目标地址转换)和SNAT(源地址转换)。
  nat类型的特性:
  ①RS可使用私有地址来隐藏服务器;RS的网关必须指向DIP;
  ②请求和响应都要经过Director,因此在高负载场景中,Director易成为性能瓶颈;
  ③支持端口映射;
  ④RS可以使用任意OS;
  

  2、lvs-dr
http://s1.运维网.com/wyfs02/M01/7E/6A/wKioL1b-mHHitMbFAACdy3peeT4217.png
  这种模型中,响应报文不会流经director,而是直接响应给client,因此在real server上必须也配置VIP,且要将其隐藏,即不允许通告和响应arp解析请求,否则请求报文可能不经director而直接到达real server;director不能给请求报文做IP地址转换,只能修改其目标MAC地址以将其送往real server,因此,要求director和real server在同一物理网络中。

  dr类型的特性:
  ⑴保证前端路由将目标地址为VIP的报文统统发往Directory,而不能是RS;
  解决方案:
  ①静态地址绑定:在前端路由器上操作(问题:未必有路由操作权限)
  ②aprtables
  ③修改RS上内核参数,将RS上的VIP配置在lo接口的别名上,并限制其不能响应对VIP地址解析请求;
  ⑵RS可以使用私有地址;也可以使用公网地址,此时可通过互联网通过RIP对其直接访问;
  ⑶RS跟Directory必须在同一物理网络中;
  ⑷请求报文经由Director,但响应报文不经过Director,因此相比NAT模型,Director负荷大大减小。
  ⑸不支持端口映射;
  ⑹RS可以是大多数常见的OS;
  ⑺RS的网关绝不允许指向DIP;
  ⑻缺点:RS上绑定vip,风险大
  

  lvs-dr的配置:
  ⑴RS上首先配置内核参数:
  echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
  echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
  echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
  echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
  说明:
  arp_ignore:如何响应接收到的ARP请求;默认为0,表示只要本机有,就响应;1表示仅当请求解析的IP地址为接收请求报文的端口地址时才进行响应
  arp_annouce:如何通告本机地址;默认为0,通告本机所有接口地址,2表示仅通告网络直连的接口的地址
  这一步的作用在于禁止通告VIP和响应对VIP的ARP解析请求
  ⑵然后在RS上配置VIP:
  ifconfig
lo:0 VIP netmask 255.255.255.255 broadcast VIP up
  route add -host VIP dev lo:0#请求报文本来是物理接口eth#接收的,需要添加一条使请求报文到达VIP所在接口(VIP通常配置在lo:0上)的路由,这样响应报文的源地址才能是VIP。
  

  3、lvs-tun
  lvs-tun不同于lvs-dr的地方在于它允许director和real server在不同的网络中,这是通过隧道机制实现的。在这种模型中,director会在请求报文原有IP首部之外再封装一层首部,这样,请求报文的IP首部就变成:内层IP首部(源地址:CIP,目标地址:VIP),外层IP首部(源地址:DIP,目标地址:RIP)。real server收到报文后,先将报文解封获得原来目标地址为VIP的报文,发现VIP地址被配置在本地的IP隧道设备上,所以就处理这个请求,然后根据路由表将响应报文直接返回给客户。
http://s2.运维网.com/wyfs02/M01/7E/6A/wKioL1b-paSiHC36AACHykrrvoY200.png
  

  tun类型的特性:
  ①RIP、VIP、DIP全部是公网地址;
  ②RS的网关不会也不可能指向DIP;
  ③请求报文经由Director,但响应报文必须不能经过Director;
  ④不支持端口映射;
  ⑤RS的OS必须支持隧道功能,一般需安装隧道网卡;
  ⑥由于该模型允许Director和RS不在同一物理网络中,因此常用于异地容灾的场景中
  lvs-tun的配置可参考http://www.linuxidc.com/Linux/2012-09/71340p3.htm
  

  4、lvs-fullnat
http://s5.运维网.com/wyfs02/M00/7E/7A/wKiom1cBPH7TXOBNAABhFhlgWBM183.png
  同时修改请求报文的源地址和目标地址(CIP--VIP ==> DIP--RIP);实现director和RS之间跨子网通信,并且in/out流都会经过director;支持端口映射。
  fullnat模式没有被整合进linux内核,若要使用需要向内核打补丁,并且不被ipvsadm支持,不过可以使用keepalive生成规则。
  

  四、lvs调度方法
  grep -i 'VS' /boot/config-VERSION
  ⑴静态方法:仅根据调度算法本身进行调度
  rr: round robin,轮流,轮询,轮叫
  wrr: weighted round robin, 加权轮询
  sh: source hashing,源地址hash,表示将来源于同一个CIP的请求始终定向至同一个RS;SESSION保持;
  dh: destination hashing, 目标地址hash,后端一般为缓存服务器,可提高缓存命中率
  ⑵动态方法:根据算法及各RS当前的负载状况进行调度
  lc: least connection,最少连接
  Overhead=Active*256+Inactive#overhead值越小越优先被选中,若overhead值一样,则根据real server列表自上而下挑选
  wlc: weighted lc,默认调度方法
  Overhead=(Active*256+Inactive)/weight
  sed: shortest expection delay;
  wlc有个缺点,就是当overhead值相同时,权重小的若在列表中靠前则会被优先选择,当请求量只有一个或很少时,这种调度不合适,而sed调度的主要目的在于让权重大的优先接受请求
  Overhead=(Active+1)*256/weight
  nq: Never Queue,先按权重轮询一圈,然后依照sed的overhead值选择
  lblc: Locality-Based Least Connection,动态版dh
  lblcr:Replicated lblc
  

  五、使用ipvsadm配置director
  yum -y install ipvsadm
  ⑴定义一个集群服务:

  ipvsadm -A|E -t|u|f service-address [-s scheduler]
  -A: 添加
  -E: 修改
  -f: firewall mark
  

  -t: 说明提供的是TCP服务
  -u: 说明提供的是UDP服务
  -f: 说明是经过iptables标记过的服务类型
  

  service-address:
  -t|u: VIP:Port
  -f: #
  例如:ipvsadm -A -t 172.16.100.7:80 -s wlc
  ⑵向一个已经存在集群服务添加一个RS:
  ipvsadm -a|e -t|u|f service-address -r server-address
  -a: 添加RS记录
  -e: 修改RS记录
  options:
  -w weight
  -g, --gatewaying: 指定lvs工作模式为DR模式,缺省模式
  -i, --ipip: ipip encapsulation (tunneling)
  -m, --masquerading: masquerading (NAT)
  例如:ipvsadm -a -t 172.16.100.7:80 -r 10.0.0.8 -m -w 2
  ⑶查看已经定义的集群服务及RS:
  ipvsadm -L -n
  -c: 查看各连接
  --stats: 统计数据
  --rate: 速率
  --exact: 精确值
  ⑷从集群服务中删除RS:ipvsadm -d -t|u|f service-address -r server-address
  ⑸删除集群服务:ipvsadm -D -t|u|f service-address
  ⑹清空所有的集群服务:ipvsadm -C
  ⑺保存集群服务定义:
  ipvsadm -S > /path/to/some_rule_file
  ipvsadm-save > /path/to/some_rule_file
  service ipvsadm save#该命令会将规则保存于/etc/sysconfig/ipvsadm中
  ⑻让规则文件中的规则生效:
  ipvsadm -R < /path/from/some_rule_file
  ipvsadm-restore < /path/from/some_rule_file
  可将该命令写入/etc/rc.d/rc.local中,这样开机启动时就自动导入了
  service ipvsadm start#以服务的方式启动ipvsadm,它会从/etc/sysconfig/ipvsadm中读取定义的集群服务规则
  ⑼基于防火墙标记定义集群服务
  功能:将同属于同一组应用的多个不同端口的服务定义成一个集群服务,统一调度;例如http和https
  结合netfilter来实现一种集群服务定义机制;
  ①在mangle表的PREROUTING链定义规则,实现指定防火墙标记;
  iptables -t mangle -A PREROUTING -d VIP -p {tcp|udp} --dport PORT -j MARK --set-mark #
  ②基于此前的标记定义集群服务;
  ipvsadm -A -f # [-s METHOD]
  ipvsadm -a -f # -r RS
  例如:
  iptables -t mangle -A PREROUTING -d 192.168.30.13 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 2
           ipvsadm -A -f 2 -s wlc
           ipvsadm -a -f 2 -r 172.16.100.2 -g -w 3
  ⑽lvs持久连接功能
  无论使用什么调度方法,持久连接功能都能保证在指定的一段时间内,来自同一个客户端的请求始终被定向至同一个RS。当使用LVS持久连接时,调度器使用连接跟踪(持久连接模板)来记录每一个客户端和给其分配的real server的映射关系
  -p, --persistent :使用持久连接,默认时长为300秒
  持久连接类型:
  ①PCC(persistent client connections):持久客户端连接,又称零端口连接
  在基于tcp或udp定义集群服务时,将来自于同一个客户端对所有端口的请求,始终定向至此前选定的RS;以0作为端口号
  例:ipvsadm -A -t 172.16.100.7:0 -s rr -p
  ②PPC(persistent port connections):持久端口连接,将对同一端口的请求,始终定向至此前选定的RS;单服务调度;各集群服务分开调度
  例:ipvsadm -A -t 172.16.100.7:21 -s rr -p
  ③PFMC(persistent
firewall mark connections):持久防火墙标记连接
  iptables -t mangle -A PREROUTING -d 192.168.30.13 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 2
  ipvsadm -A -f 2 -s wlc -p 600
  -M, --netmask 选项:
  配合persistence_timeout使用,表示持久连接的粒度,默认是255.255.255.255,即单独的客户端IP。如果改成255.255.255.0,则表示只要是一个网段的client都会被分配到同一台后端服务器上
  

  六、配置示例
  注意:lvs-nat模型中,director需要开启报文转发功能,而lvs-dr模型中则不需要
  1、配置lvs-nat
   以下示例中,我们以node3为director,以node3上的两个容器centos2和centos3(容器的创建详见博客http://9124573.blog.运维网.com/9114573/1761114)作为real server,node1作为客户端
   VIP:192.168.30.13
   DIP:172.16.100.1
   RIP1:172.16.100.2
   RIP2:172.16.100.3
#首先启动容器,并保证其httpd服务正常运行
# lxc-start -n centos2 -d
# lxc-start -n centos3 -d
# ssh root@172.16.100.2
root@172.16.100.2's password:
Last login: Wed Apr6 13:31:11 2016
# service httpd start
Starting httpd: httpd:                                          
# ss -tnl
State       Recv-Q Send-Q                        Local Address:Port                      Peer Address:Port
LISTEN      0      0                           *:22                                    *:*   
LISTEN      0      0                           :::22                                 :::*   
LISTEN      0      0                           :::80                                 :::*
# logout
Connection to 172.16.100.2 closed.
# ssh root@172.16.100.3
root@172.16.100.3's password:
Last login: Wed Apr6 13:31:38 2016
# service httpd start
Starting httpd: httpd:                                          
# logout
Connection to 172.16.100.3 closed.
# yum -y install ipvsadm
...
Installed:
ipvsadm.x86_64 0:1.26-4.el6                                                                                                                                             
Complete!
# rpm -ql ipvsadm
/etc/rc.d/init.d/ipvsadm   #ipvsadm也有服务脚本
/etc/sysconfig/ipvsadm-config
/sbin/ipvsadm
/sbin/ipvsadm-restore
/sbin/ipvsadm-save
/usr/share/doc/ipvsadm-1.26
/usr/share/doc/ipvsadm-1.26/README
/usr/share/man/man8/ipvsadm-restore.8.gz
/usr/share/man/man8/ipvsadm-save.8.gz
/usr/share/man/man8/ipvsadm.8.gz
# ipvsadm -A -t 192.168.30.13:80 -s rr   #定义一个集群服务,采用轮循调度
# ipvsadm -a -t 192.168.30.13:80 -r 172.16.100.2 -m   #添加real server
# ipvsadm -a -t 192.168.30.13:80 -r 172.16.100.3 -m
# ipvsadm -L -n   #查看定义的集群服务及RS
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port         Forward Weight ActiveConn InActConn
TCP192.168.30.13:80 rr
-> 172.16.100.2:80            Masq    1      0          0         
-> 172.16.100.3:80            Masq    1      0          0
# cat /proc/sys/net/ipv4/ip_forward   #确保开启报文转发功能
1
# iptables -L -n   #确保已开放集群服务端口
Chain INPUT (policy DROP)
target   prot opt source               destination         
ACCEPT   all--0.0.0.0/0            0.0.0.0/0         state ESTABLISHED
ACCEPT   tcp--0.0.0.0/0            192.168.30.13       tcp dpt:22 state NEW
ACCEPT   tcp--0.0.0.0/0            172.16.100.1      tcp dpt:22 state NEW
ACCEPT   tcp--0.0.0.0/0            192.168.30.13       tcp dpt:80 state NEW
Chain FORWARD (policy ACCEPT)
target   prot opt source               destination         
Chain OUTPUT (policy ACCEPT)
target   prot opt source               destination#这里为演示负载均衡的效果,刻意让后端两个RS上的网页内容不同,实际环境是当然是相同的
# curl 192.168.30.13
hello
# curl 192.168.30.13
how are you
# curl 192.168.30.13
hello
# curl 192.168.30.13
how are you# ipvsadm -L -n -c
IPVS connection entries
pro expire state       source             virtual            destination
TCP 01:17TIME_WAIT   192.168.30.10:38368 192.168.30.13:80   172.16.100.2:80
TCP 01:17TIME_WAIT   192.168.30.10:38369 192.168.30.13:80   172.16.100.3:80
TCP 01:15TIME_WAIT   192.168.30.10:38367 192.168.30.13:80   172.16.100.3:80
TCP 01:14TIME_WAIT   192.168.30.10:38366 192.168.30.13:80   172.16.100.2:80
# ipvsadm-save > /tmp/lvs   #将定义的规则保存至某个文件中
# ipvsadm -D -t 192.168.30.13:80   #删除指定的集群服务
# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port         Forward Weight ActiveConn InActConn
# ipvsadm-restore < /tmp/lvs
# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port         Forward Weight ActiveConn InActConn
TCP192.168.30.13:80 rr
-> 172.16.100.2:80            Masq    1      0          0         
-> 172.16.100.3:80            Masq    1      0          0  

  2、配置lvs-dr
  以下示例中,node1为客户端,node3为director,node4和node5为real server,可将VIP配置于虚拟接口上,DIP与RIP要位于同一物理网络;
  DIP:192.168.30.13,eth0
  VIP:192.168.30.100,eth0:0
  RIP1:192.168.30.14
  RIP2:192.168.30.15
# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
# ifconfig lo:0 192.168.30.100 netmask 255.255.255.255 broadcast 192.168.30.100 up
# route add -host 192.168.30.100 dev lo:0
# service httpd start
Starting httpd: httpd: apr_sockaddr_info_get() failed for node5
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
                                                         
# iptables -F  再在node5的做相同配置,略
#在director上配置VIP,定义集群服务,添加后端RS
# ifconfig eth0:0 192.168.30.100/24 up   #配置VIP
# ifconfig
eth0      Link encap:EthernetHWaddr 00:0C:29:CB:26:9B
          inet addr:192.168.30.13Bcast:192.168.30.255Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fecb:269b/64 Scope:Link
          UP BROADCAST RUNNING MULTICASTMTU:1500Metric:1
          RX packets:28711 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9590 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:4456933 (4.2 MiB)TX bytes:1970077 (1.8 MiB)
eth0:0    Link encap:EthernetHWaddr 00:0C:29:CB:26:9B
          inet addr:192.168.30.100Bcast:192.168.30.255Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICASTMTU:1500Metric:1
...
# cat /proc/sys/net/ipv4/ip_forward
1
# ipvsadm -C
# iptables -t mangle -A PREROUTING -d 192.168.30.100 -p tcp -m multiport --dports 80,243 -j MARK --set-mark 1
# ipvsadm -A -f 1 -s wlc   #基于防火墙定义集群服务
# ipvsadm -a -f 1 -r 192.168.30.14 -g -w 2
# ipvsadm -a -f 1 -r 192.168.30.15 -g -w 1
# iptables -P INPUT ACCEPT  负载均衡效果测试:
# curl 192.168.30.100
hello
# curl 192.168.30.100
hello
# curl 192.168.30.100
how are you  六、Session持久机制
  ①session绑定:始终将来自同一个源IP的请求定向至同一个RS;没有容错能力;有损均衡效果;
  ②session复制:在RS之间同步session,每个RS拥有集群中的所有的session;对大规模集群不适用;
  ③session服务器:利用单独部署的服务器来统一管理集群中的session;
  

  七、real server的健康状态检测
  lvs自身不具备后端RS健康状态检测功能,需要借助keepalived,keepalived不仅能为lvs提供高可用,还可以给lvs生成规则。
  1、如何检测RS的健康状态:
  应用层:利用集群服务依赖的协议进行检测
  传输层:利用端口扫描或探测类工具对指定协议的端口进行探测
  网络层:如ping
  2、处理措施:
  ①自动上下线各RS;
  online --> fail,探测三次及以上;
  offline --> ok,一次即可;
  ②所有RS均故障时,应该提供一个back server;
  ipvsadm -a -t 192.168.30.13:80 -r 127.0.0.1 -m -w 0



页: [1]
查看完整版本: 使用lvs搭建负载均衡集群