LVS DR模式 + Keepalived +Nginx 高可用部署

1,425 阅读7分钟

1、配置DR有三种方式

第一种方式

在路由器上明显说明vip对应的地址一定是Director上的MAC,只要绑定,以后再跟vip通信也不用再请求了,这个绑定是静态的,所以它也不会失效,也不会再次发起请求,但是有个前提,我们的路由设备必须有操作权限能够绑定MAC地址,万一这个路由器是运行商操作的,我们没法操作怎么办?第一种方式固然很简便,但未必可行。

第二种方式:

在给别主机上(例如:红帽)它们引进的arptables,它有点类似于iptables,它是基于arp或基于MAC做访问控制的,很显然我们只需要在每一个real server上定义arptables规则,如果用户arp广播请求的目标地址是本机的vip则不予相应,或者说相应的报文不让出去,很显然网关(gateway)是接受不到的,也就是director相应的报文才能到达gateway,这个也行。第二种方式我们可以基于arptables。

第三种方式:

在相对较新的版本中新增了两个内核参数(kernel parameter),第一个是arp_ignore定义接受到ARP请求时的相应级别;第二个是arp_announce定义将自己地址向外通告时的通告级别。提示:很显然我们现在的系统一般在内核中都是支持这些参数的,我们用参数的方式进行调整更具有朴实性,它还不依赖于额外的条件,像arptables,也不依赖外在路由配置的设置,反而通常我们使用的是第三种配置。

arp_ignore:定义接受到ARP请求时的相应级别

0: 只要本地配置的有相应地址,就给予响应。(默认)

1: 仅回应目标IP地址是本地的入网地址的arp请求。

2: 仅回应目标IP地址是本地的入网地址,而且源IP和目标IP在同一个子网的arp请求。

3: 不回应该网络界面的arp请求,而只对设置的唯一和连接地址做出回应。

4-7:保留未使用

8: 不回应所有的arp请求。

arp_announce:定义将自己地址向外通告是的通告级别

0: 将本地任何接口上的任何地址向外通告

1: 试图仅向目标网络通告与其网络匹配的地址

2: 仅向与本地接口上地址匹配的网络进行通告

2、节点规划

Director Server 节点Real Server 节点Virtual IP
192.168.31.101(Master)192.168.31.103(nginx)192.168.31.110
192.168.31.102(Backup)192.168.31.104(nginx)

3、Director Server 节点配置

1、安装Keepalived服务

 yum install -y curl gcc openssl-devel libnl3-devel net-snmp-devel
 yum install -y keepalived
 ​
 # (Master、Backup节点都需要安装)

2、配置文件

Master 配置文件 /etc/keepalived/keepalived.conf

 # 全局配置
 global_defs {
    router_id LVS_TEST
 }
 ​
 # VRRP 实例配置
 vrrp_instance VI_110 {
     state MASTER
     interface eth0
     virtual_router_id 110
     priority 100
     advert_int 1
     authentication {
         auth_type PASS
         auth_pass qwer1234
     }
     virtual_ipaddress {
         192.168.31.110
     }
 }
 ​
 virtual_server 192.168.31.110 80 {
     # 服务轮询的时间间隔
     delay_loop 1
     # 设置 LVS 调度算法 rr|wrr|lc|wlc|lblc|sh|dh
     lb_algo wlc
     # 设置 LVS 集群模式 NAT|DR|TUN
     lb_kind DR
 ​
     # 设置会话保持时间秒为单位即以用户在 120 秒内被分配到同一个后端 realserver, 超过此时间就重新分配
     persistence_timeout 0
     # 设置健康检查用的是 TCP 还是 UDP
     protocol TCP
 ​
     real_server 192.168.31.103 80 {
         # 权重为x
         weight 10
         # 表示在节点失败后把他权重设置成 0 而不是在 IPVS 中删除
         inhibit_on_failure
         TCP_CHECK {
             # 设置监控检查的端口
             connect_port 80
             # 设置连接超时时间
             connect_timeout 6
             # 健康检测重试试间
             nb_get_retry 3
             # 设置重连间隔
             delay_before_retry 3
         }
     }
 ​
     real_server 192.168.31.104 80 {
         weight 10
         inhibit_on_failure
         TCP_CHECK {
             connect_port 80
             connect_timeout 6
             nb_get_retry 3
             delay_before_retry 3
         }
     }
 }

Backup节点需要修改的参数:state Backuppriority 50 (其他的不变)

3、打开IP转发

 echo 1 > /proc/sys/net/ipv4/ip_forward
 ​
 # 0:禁止、1:转发。

/proc/sys/net/ipv4/ip_forward 基本用途:

出于安全考虑,Linux系统默认是禁止数据包转发的。所谓转发即当主机拥有多于一块的网卡时,其中一块收到数据包,根据数据包的目的ip地址将包发往本机另一网卡,该网卡根据路由表继续发送数据包。这通常就是路由器所要实现的功能。

配置Linux系统的ip转发功能,首先保证硬件连通,然后打开系统的转发功能 less /proc/sys/net/ipv4/ip_forward,该文件内容为0,表示禁止数据包转发,1表示允许,将其修改为1。可使用命令echo 1 > /proc/sys/net/ipv4/ip_forward 修改文件内容,重启网络服务或主机后效果不再。若要其自动执行,可将命令写入脚本/etc/rc.d/rc.local 或者在/etc/sysconfig/network脚本中添加 FORWARD_IPV4="YES"

4、运行服务

 systemctl start keepalived

4、Real Server 节点配置

两个Nginx节点配置相同

1、网卡配置

方法一:

 cat << EOF > /etc/sysconfig/network-scripts/ifcfg-lo:0
 DEVICE=lo:0
 IPADDR=192.168.31.110
 NETMASK=255.255.255.255
 NETWORK=127.0.0.0
 BROADCAST=127.255.255.255
 ONBOOT=yes
 NAME=loopback
 EOF
 systemctl restart network

方法二:

 ifconfig lo:0 192.168.31.110 broadcast 192.168.31.110 netmask 255.255.255.255 up
 ​
 # 注意:此方法重启网络后需要重新配置

2、配置ARP规则

 echo "1" >/proc/sys/net/ipv4/conf/eth0/arp_ignore
 echo "2" >/proc/sys/net/ipv4/conf/eth0/arp_announce
 ​
 echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
 echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
 ​
 echo "0" > /proc/sys/net/ipv4/conf/eth0/rp_filter
 echo "0" > /proc/sys/net/ipv4/conf/lo/rp_filter
 ​
 # 注意:此方法重启网络后需要重新配置

rp_filter:定义是否进行源地址校验

0:不开启源地址校验。

1:开启严格的反向路径校验。对每个进来的数据包,校验其反向路径是否是最佳路径。如果反向路径不是最佳路径,则直接丢弃该数据包。

2:开启松散的反向路径校验。对每个进来的数据包,校验其源地址是否可达,即反向路径是否能通(通过任意网口),如果反向路径不同,则直接丢弃该数据包。

3、Nginx 配置

     server {
         listen       80;
         server_name  localhost;
 ​
         location / {
             default_type text/plain;
             return 200 'host is nginx-103\n'; 
             # nginx-103 or  nginx-104
         }

5、测试

1、查看状态

 [root@lvs-101 ~]# 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.31.110:80 wlc
   -> 192.168.31.103:80            Route   10     0          0
   -> 192.168.31.104:80            Route   10     0          0

2、查看IP

 [root@lvs-101 ~]# ip addr
 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
     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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
     link/ether 52:54:00:d9:53:64 brd ff:ff:ff:ff:ff:ff
     inet 192.168.31.101/24 brd 192.168.31.255 scope global noprefixroute eth0
        valid_lft forever preferred_lft forever
     inet 192.168.31.110/32 scope global eth0
        valid_lft forever preferred_lft forever

3、查看请求情况

 [fong@host-machine ~]$ for i in {1..10}; do curl http://192.168.31.110:80 ;done
 host is nginx-104
 host is nginx-103
 host is nginx-104
 host is nginx-103
 host is nginx-104
 host is nginx-103
 host is nginx-104
 host is nginx-103
 host is nginx-104
 host is nginx-103

4、关闭lvs-101服务后查看IP是否切换

 [root@lvs-101 ~]# systemctl stop keepalived
 ​
 [root@lvs-101 ~]# ip addr
 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
     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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
     link/ether 52:54:00:d9:53:64 brd ff:ff:ff:ff:ff:ff
     inet 192.168.31.101/24 brd 192.168.31.255 scope global noprefixroute eth0
        valid_lft forever preferred_lft forever
        
 [root@lvs-102 ~]# ip addr
 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
     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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
     link/ether 52:54:00:41:37:fb brd ff:ff:ff:ff:ff:ff
     inet 192.168.31.102/24 brd 192.168.31.255 scope global noprefixroute eth0
        valid_lft forever preferred_lft forever
     inet 192.168.31.110/32 scope global eth0
        valid_lft forever preferred_lft forever