本文主要讲述LVS-DR原理介绍和配置实践,HA高可用方案基于Keepalived。html
LVS-DR原理介绍和配置实践
2019年09月03日 - 拆分LVS-Keepalived中LVS-DR
2019年08月23日 - 更新LVS/NAT、LVS/DR、LVS/TUN三种模式的原理和配置实践
2018年12月03日 - 精简和更新配置步骤
2018年07月31日 - 初稿前端
阅读原文 - https://wsgzao.github.io/post...node
扩展阅读linux
LVS - http://www.linuxvirtualserver...
Keepalived - http://www.keepalived.org/git
Virtual Server via Direct Routing - http://www.linuxvirtualserver...
LVS和Keepalived官方中文手册PDF - https://pan.baidu.com/s/1s0P6...github
如下术语涉及LVS三种工做模式的原理
VS/NAT | VS/TUN | VS/DR | |
---|---|---|---|
server | any | tunneling | non-arp device |
server network | private | LAN/WAN | LAN |
server number | low (10~20) | high | high |
server gateway | load balancer | own router | own router |
模式与特色 | NAT 模式 | IPIP 模式 | DR 模式 |
---|---|---|---|
对服务器的要求 | 服务节点可使任何操做系统 | 必须支持 IP 隧道,目前只有 Linux 系统支持 | 服务器节点支持虚拟网卡设备,可以禁用设备的 ARP 响应 |
网络要求 | 拥有私有 IP 地址的局域网络 | 拥有合法 IP 地址的局域,网或广域网 | 拥有合法 IP 地址的局域,服务器节点与负载均衡器必须在同一个网段 |
一般支持节点数量 | 10 到 20 个,根据负载均衡器的处理能力而定 | 较高,能够支持 100 个服务节点 | 较高,能够支持 100 个服务节点 |
网关 | 负载均衡器为服务器节点网关 | 服务器的节点同本身的网关或者路由器链接,不通过负载均衡器 | 服务节点同本身的网关或者路由器链接,不通过负载均衡器 |
服务节点安全性 | 较好,采用内部 IP,服务节点隐蔽 | 较差,采用公用 IP 地址,节点安全暴露 | 较差,采用公用 IP 地址,节点安全暴露 |
IP 要求 | 仅须要一个合法的 IP 地址做为 VIP 地址 | 除了 VIPO 地址外,每一个服务器界定啊须要拥有合法的 IP 地址,能够直接从路由到客户端 | 除了 VIP 外,每一个服务节点需拥有合法的 IP 地址,能够直接从路由到客户端 |
特色 | 地址转换 | 封装 IP | 修改 MAC 地址 |
配置复杂度 | 简单 | 复杂 | 复杂 |
LVS 由2部分程序组成,包括 ipvs 和 ipvsadm。
在lvs+keepalived环境里面,lvs主要的工做是提供调度算法,把客户端请求按照需求调度在real服务器,keepalived主要的工做是提供lvs控制器的一个冗余,而且对real服务器作健康检查,发现不健康的real服务器,就把它从lvs集群中剔除,real服务器只负责提供服务。算法
重点将请求报文的目标MAC地址设定为挑选出的RS的MAC地址
(1) 当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP
(2) PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链
(3) IPVS比对数据包请求的服务是否为集群服务,如果,将请求报文中的源MAC地址修改成DIP的MAC地址,将目标MAC地址修改RIP的MAC地址,而后将数据包发至POSTROUTING链。 此时的源IP和目的IP均未修改,仅修改了源MAC地址为DIP的MAC地址,目标MAC地址为RIP的MAC地址
(4) 因为DS和RS在同一个网络中,因此是经过二层来传输。POSTROUTING链检查目标MAC地址为RIP的MAC地址,那么此时数据包将会发至Real Server。
(5) RS发现请求报文的MAC地址是本身的MAC地址,就接收此报文。处理完成以后,将响应报文经过lo接口传送给eth0网卡而后向外发出。 此时的源IP地址为VIP,目标IP为CIP
(6) 响应报文最终送达至客户端vim
LVS/DR模型的特性
特色1的解决方案:
DR(Direct Routing 直接路由模式)此模式时LVS 调度器只接收客户发来的请求并将请求转发给后端服务器,后端服务器处理请求后直接把内容直接响应给客户,而不用再次通过LVS调度器。LVS只须要将网络帧的MAC地址修改成某一台后端服务器RS的MAC,该包就会被转发到相应的RS处理,注意此时的源IP和目标IP都没变。RS收到LVS转发来的包时,链路层发现MAC是本身的,到上面的网络层,发现IP也是本身的,因而这个包被合法地接受,RS感知不到前面有LVS的存在。而当RS返回响应时,只要直接向源IP(即用户的IP)返回便可,再也不通过LVS。后端
注意:
(1) 确保前端路由器将目标IP为VIP的请求报文发往Director:安全
(a) 在前端网关作静态绑定; (b) 在RS上使用arptables; (c) 在RS上修改内核参数以限制arp通告及应答级别; arp_announce arp_ignore
(2) RS的RIP可使用私网地址,也能够是公网地址;RIP与DIP在同一IP网络;RIP的网关不能指向DIP,以确保响应报文不会经由Director;
(3) RS跟Director要在同一个物理网络;
(4) 请求报文要经由Director,但响应不能经由Director,而是由RS直接发往Client;
(5) 此模式不支持端口映射;
缺点:惟一的缺陷在于它要求LVS 调度器及全部应用服务器在同一个网段中,所以不能实现集群的跨网段应用。
优势:可见在处理过程当中LVS Route只处理请求的直接路由转发,全部响应结果由各个应用服务器自行处理,并对用户进行回复,网络流量将集中在LVS调度器之上。
# Install keepalived # Ubuntu apt-get install keepalived ipvsadm # CentOS yum install keepalived ipvsadm # update iptables vim /etc/sysconfig/iptables # For keepalived: # allow vrrp -A INPUT -p vrrp -j ACCEPT -A INPUT -p igmp -j ACCEPT # allow multicast -A INPUT -d 224.0.0.18 -j ACCEPT # reload iptables service iptables reload # open ip_forward echo "1" > /proc/sys/net/ipv4/ip_forward # edit sysctl.conf vi /etc/sysctl.conf net.ipv4.ip_forward = 1 sysctl -p # keepalived for lvs-dr vim /etc/keepalived/keepalived.conf vrrp_sync_group GOP { group { VI_PRI_CONNECT VI_PRI_AUTH } } vrrp_instance VI_PRI_CONNECT { state BACKUP interface bond0 virtual_router_id 128 priority 100 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 10.65.32.28/23 dev bond0 } } virtual_server 10.65.32.28 80 { delay_loop 6 lb_algo rr lb_kind DR protocol TCP real_server 10.65.32.13 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } real_server 10.65.32.14 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } } virtual_server 10.65.32.28 443 { delay_loop 6 lb_algo rr lb_kind DR protocol TCP real_server 10.65.32.13 443 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 443 } } real_server 10.65.32.14 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 443 } } } vrrp_instance VI_PRI_AUTH { state BACKUP interface bond0 virtual_router_id 129 priority 100 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 10.65.32.29/23 dev bond0 } } virtual_server 10.65.32.29 80 { delay_loop 6 lb_algo rr lb_kind DR protocol TCP real_server 10.65.32.22 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } real_server 110.65.32.23 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } } virtual_server 10.65.32.29 443 { delay_loop 6 lb_algo rr lb_kind DR protocol TCP real_server 10.65.32.22 443 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 443 } } real_server 110.65.32.23 443 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 443 } } } # enable and start keepalived systemctl start keepalived systemctl enable keepalived watch ipvsadm -L -n --stats
# add TYPE=Loopback echo "TYPE=Loopback" >> /etc/sysconfig/network-scripts/ifcfg-lo # add ifcfg-lo:0 cat > /etc/sysconfig/network-scripts/ifcfg-lo:0 << EOF DEVICE=lo:0 IPADDR=10.65.32.28 NETMASK=255.255.255.255 ONBOOT=yes EOF # ifup lo:0 ifup lo:0 # add real_start cat > /root/real_start.sh << EOF #!/bin/bash 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 EOF # chmod 755 chmod 755 /root/real_start.sh # add real.service cat > /usr/lib/systemd/system/real.service << EOF [Unit] Description=autostart lvs real After=network.target remote-fs.target nss-lookup.target [Service] Type=forking ExecStart=/root/real_start.sh [Install] WantedBy=multi-user.target EOF # enable service systemctl enable real.service # lvs real server example vim /root/lvs_real.sh #!/bin/bash ### BEGIN INIT INFO # Provides: # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start realserver # Description: Start realserver ### END INIT INFO # change the VIP to proper value VIP=10.65.32.28 case "$1" in start) echo "Start REAL Server" /sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up 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 ;; stop) /sbin/ifconfig lo:0 down echo "Stop REAL Server" echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce ;; restart) $0 stop $0 start ;; *) echo "Usage: $0 {start|stop}" exit 1 ;; esac exit 0
# 关于3中模式的参数 [packet-forwarding-method] -g, --gatewaying Use gatewaying (direct routing). This is the default. -i, --ipip Use ipip encapsulation (tunneling). -m, --masquerading Use masquerading (network access translation, or NAT). Note: Regardless of the packet-forwarding mechanism specified, real servers for addresses for which there are interfaces on the local node will be use the local forwarding method, then packets for the servers will be passed to upper layer on the local node. This cannot be specified by ipvsadm, rather it set by the kernel as real servers are added or modified. # ipvsadm命令行混配 /sbin/ifconfig tunl0 10.10.36.11 broadcast 10.10.36.11 netmask 255.255.255.255 up /sbin/route add -host 10.10.36.11 dev tunl0 /sbin/ipvsadm -At 10.10.36.11:80 -s rr /sbin/ipvsadm -at 10.10.36.11:80 -r 10.10.36.4:80 -g -w 1 /sbin/ipvsadm -at 10.10.36.11:80 -r 10.10.36.7:80 -i -w 1 # keepalived混配 vrrp_sync_group GOP { group { VI_PRI_AUTH } } vrrp_instance VI_PRI_AUTH { state BACKUP interface em1 virtual_router_id 11 priority 100 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 10.10.36.11/23 dev em1 } } virtual_server 10.10.36.11 80 { delay_loop 6 lb_algo rr lb_kind DR protocol TCP real_server 10.10.36.4 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } } virtual_server 10.10.36.11 80 { delay_loop 6 lb_algo rr lb_kind TUN protocol TCP real_server 10.10.36.7 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } } # 检查结果可用 [root@d126027 wangao]# for i in {1..100}; do curl 10.10.36.11; sleep 0.5; done rs2 rs1 rs2 rs1 rs2 [root@d126009 keepalived]# ipvsadm -Ln --stats IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes -> RemoteAddress:Port TCP 10.10.36.11:80 100 700 0 36700 0 -> 10.10.36.4:80 50 350 0 18350 0 -> 10.10.36.7:80 50 350 0 18350 0
DR和TUN的模式基本不用作改动
LVS和Keepalived的原理介绍和配置实践
LVS原理介绍和配置实践
Keepalived原理介绍和配置实践
LVS-NAT原理介绍和配置实践
LVS-DR原理介绍和配置实践
LVS-TUN原理介绍和配置实践