本文主要講述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原理介紹和配置實踐