keepalived+lvs-dr+nginx雙主模型

前言

    本文主要介紹,使用keepalived+lvs實現負載均衡及高可用功能,後端webserver使用nginxkeepalived使用雙主模型。

    keepalived基於VRRP實現

        VRRP的工作過程爲:

        (1)  虛擬路由器中的路由器根據優先級選舉出 Master。Master 路由器通過發送免費 ARP 報文,將自己的虛擬 MAC 地址通知給與它連接的設備或者主機,從而承擔報文轉發任務;

        (2)  Master 路由器週期性發送 VRRP 報文,以公佈其配置信息(優先級等)和工作狀況;

        (3)  如果 Master 路由器出現故障,虛擬路由器中的 Backup 路由器將根據優先級重新選舉新的 Master;

        (4)  虛擬路由器狀態切換時,Master 路由器由一臺設備切換爲另外一臺設備,新的 Master 路由器只是簡單地發送一個攜帶虛擬路由器的 MAC 地址和虛擬 IP地址信息的免費 ARP 報文,這樣就可以更新與它連接的主機或設備中的ARP 相關信息。網絡中的主機感不到 Master 路由器已經切換爲另外一臺設備。

        (5)  Backup 路由器的優先級高於 Master 路由器時,由 Backup 路由器的工作方式(搶佔方式和非搶佔方式)決定是否重新選舉 Master。

        由此可見,爲了保證Master路由器和Backup路由器能夠協調工作,VRRP需要實現以下功能:

        1、Master 路由器的選舉;

        2、Master 路由器狀態的通告;

        3、同時,爲了提高安全性,VRRP 還提供了認證功能;

    keepalived分爲搶佔式和非搶佔式

        搶佔示:當一個優先級較大的Server重新上線後,將VIP直接搶回,自己響應請求

        非搶佔式:優先級較大的Server上線後,看到VIP已經在其他節點工作,雖然自己的優先級高,但也不會強VIP,只會等待VIP所在節點down掉之後,纔會重新上線

關於VRRP的內容可以參照VRRP白皮書
      LVS-DR模型:

        LVS-DR模型,是通過爲請求報文重新封裝一個MAC首部,源MAC爲Director的MAC地址,目標MAC是被選中後端RS的MAC地址,IP首部不會變。

    (1)確保前端路由器將目標IP爲VIP的請求報文發往Director:

    解決方案:

     在路由器上靜態綁定VIP和Director的MAC地址;

     禁止RS響應VIP的ARP請求,禁止RS的VIP進行通告

      (a) arptables

      b) 修改RS的內核參數,並把VIP綁定lo的別名上;

       arp_ignore, arp_announce

顯然,第一種方案不可行,我們不可能去運營商修改,所以只能使用後者,通過修改後端RS,關閉arp請求,來實現

    (2)RS的RIP可以使用私有地址,也可以使用公網地址;

    (3) RS跟Director必須在同一物理網絡;RS的網關必須不能指向DIP;

    (4) 請求報文必須由Directory調度,但響應報文必須不能經由Director;

    (5) 不支持端口映射;

    (6) RS可以使用大多的OS;


環境介紹

Director1Director2WebServer_Nginx1WebServer_Nginx2
DIP:192.168.0.108DIP:192.168.0.109RIP:192.168.0.10RIP:192.168.020

VIP:192.168.0.111:M

VIP:192.168.0.222:B

VIP:192.168.0.111:B

VIP:192.168.0.222:M

VIP:192.168.0.111

VIP:192.168.0.222

VIP:192.168.0.111

VIP:192.168.0.222

M:表示爲Master B:表示爲BACKUP


實驗拓撲圖

wKioL1c2hUnwzdjzAAFHSd0XHko018.png

配置前端Director

Director1配置

安裝程序包:

# yum install keepalived ipvsadm -y

修改配置文件:

! Configuration File for keepalived

global_defs {
   notification_email {
     root@localhost
   }
   notification_email_from [email protected]
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_mcast_group4 224.0.4.223
}
vrrp_instance VI_1 {
    state MASTER
    interface eno16777736
    virtual_router_id 108
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.0.111
    }
}

virtual_server 192.168.0.111 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    nat_mask 255.255.255.0
    protocol TCP

    real_server 192.168.0.10 80 {
        weight 1
        HTTP_GET {
            url {
              path /
	      status_code 200
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.0.20 80 {
        weight 1
        HTTP_GET {
            url {
              path /
	      status_code 200
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

vrrp_instance VI_2 {
    state BACKUP
    interface eno16777736
    virtual_router_id 109
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.0.222
    }
}

virtual_server 192.168.0.222 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    nat_mask 255.255.255.0
    protocol TCP

    real_server 192.168.0.10 80 {
        weight 1
        HTTP_GET {
            url {
              path /
	      status_code 200
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.0.20 80 {
        weight 1
        HTTP_GET {
            url {
              path /
	      status_code 200
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
 }

Director2配置

安裝程序包:

# yum install keepalived ipvsadm -y

修改配置文件:

! Configuration File for keepalived

global_defs {
   notification_email {
     root@localhost
   }
   notification_email_from [email protected]
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_mcast_group4 224.0.4.223
}
vrrp_instance VI_1 {
    state BACKUP
    interface eno16777736
    virtual_router_id 108
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.0.111
    }

virtual_server 192.168.0.111 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    nat_mask 255.255.255.0
    protocol TCP

    real_server 192.168.0.10 80 {
        weight 1
        HTTP_GET {
            url {
              path /
	      status_code 200
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.0.20 80 {
        weight 1
        HTTP_GET {
            url {
              path /
	      status_code 200
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

vrrp_instance VI_2 {
    state MASTER
    interface eno16777736
    virtual_router_id 109
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.0.222
    }
}

virtual_server 192.168.0.222 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    nat_mask 255.255.255.0
    protocol TCP

    real_server 192.168.0.10 80 {
        weight 1
        HTTP_GET {
            url {
              path /
	      status_code 200
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.0.20 80 {
        weight 1
        HTTP_GET {
            url {
              path /
	      status_code 200
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}


# 此處暫時不啓動服務,在配置好nginx之後啓動服務


配置後端WebServer

禁止RS響應arp請求和通告腳本

#!/bin/bash
vip1=192.168.0.111
vip2=192.168.0.222
interface1="lo:0"
interface2="lo:1"

case $1 in
start)
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
	ifconfig $interface1 $vip1 broadcast $vip1 netmask 255.255.255.255 up
	route add -host $vip1 dev $interface1
	ifconfig $interface2 $vip2 broadcast $vip2 netmask 255.255.255.255 up
	route add -host $vip2 dev $interface2
;;
stop)
echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
	ifconfig $interface1 down
	ifconfig $interface2 down
;;
*)
echo "Usage: `basename $0` {start|stop|status}"
    exit 1
esac

RS1執行腳本並查看

# bash arp.sh start
# ip add show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet 192.168.0.111/32 brd 192.168.0.111 scope global lo:0
       valid_lft forever preferred_lft forever
    inet 192.168.0.222/32 brd 192.168.0.222 scope global lo:1
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:a7:a7:33 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.10/24 brd 192.168.0.255 scope global eno16777736
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fea7:a733/64 scope link 
       valid_lft forever preferred_lft forever
# cat /proc/sys/net/ipv4/conf/all/arp_ignore
1
# cat /proc/sys/net/ipv4/conf/all/arp_announce 
2

RS2執行腳本並查看

# bash arp.sh start
# ip add show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet 192.168.0.111/32 brd 192.168.0.111 scope global lo:0
       valid_lft forever preferred_lft forever
    inet 192.168.0.222/32 brd 192.168.0.222 scope global lo:1
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:ec:85:42 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.20/24 brd 192.168.0.255 scope global eno16777736
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:feec:8542/64 scope link 
       valid_lft forever preferred_lft forever
# cat /proc/sys/net/ipv4/conf/all/arp_ignore
1
# cat /proc/sys/net/ipv4/conf/all/arp_announce 
2

配置Nginx,提供測試頁面

WebServer1

# 安裝Nginx
# yum install nginx -y
# rpm -q nginx
nginx-1.6.3-8.el7.x86_64
# vim /usr/share/nginx/html/index/html
<h1>Server1</h1>
# nginx #啓動nginx

WebServer2

# 安裝Nginx
# yum install nginx -y
# rpm -q nginx
nginx-1.6.3-8.el7.x86_64
# vim /usr/share/nginx/html/index/html
<h1>Server2</h1>
# nginx #啓動nginx

啓動前端調度器並測試

Director1:啓動服務

# systemctl start keepalived

Director2:啓動服務

# systemctl start keepalived

Director1:查看虛擬ip及RS是否添加

# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.0.111:80 rr
  -> 192.168.0.10:80              Route   1      0          0         
  -> 192.168.0.20:80              Route   1      0          0         
TCP  192.168.0.222:80 rr
  -> 192.168.0.10:80              Route   1      0          0         
  -> 192.168.0.20:80              Route   1      0          0       
# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:43:ad:7b brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.108/24 brd 192.168.0.255 scope global eno16777736
       valid_lft forever preferred_lft forever
    inet 192.168.0.111/32 scope global eno16777736
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe43:ad7b/64 scope link 
       valid_lft forever preferred_lft forever  
# 此處可以看到VIP:192.168.0.111

Director2:查看虛擬ip及RS是否添加

# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.0.111:80 rr
  -> 192.168.0.10:80              Route   1      0          0         
  -> 192.168.0.20:80              Route   1      0          0         
TCP  192.168.0.222:80 rr
  -> 192.168.0.10:80              Route   1      0          0         
  -> 192.168.0.20:80              Route   1      0          0         
# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:dd:c1:9c brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.109/24 brd 192.168.0.255 scope global eno16777736
       valid_lft forever preferred_lft forever
    inet 192.168.0.222/32 scope global eno16777736
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fedd:c19c/64 scope link 
       valid_lft forever preferred_lft forever
# 此處可以看到VIP:192.168.0.222

正常測試:

wKiom1c2oHHDrfUhAAIxZuBH8AE587.gif

關閉後端Webserver1,再進行測試

    步驟:

        1、WebServer1關閉Nginx

        2、測試機請求,可以看到 只能請求道Server2

        3、在調度器查看,可以看到,其中一臺webserver已經被移除,說明健康狀態檢查是有效的

wKioL1c2ohayo-muAAk7GUntkms981.gif


關閉Director2,再進行測試

    步驟:

        1、WebServer1啓動ginx

        2、關閉Director2

        3、在調度器查看,可以看到,此時有兩個VIP

        4、在測試測試,可以正常訪問


wKiom1c2ol6TBVY2AAsTOYplWx4563.gif


文章就寫到這裏了,後續還會寫一篇關於LNAMMP的文章,文章中會介紹session等信息。 
 作者:Ace QQ1257465991 Linux運維攻城獅一隻 
 Q/A:如有問題請慷慨提出

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章