1.基础

A. 用途

故障转移:实现负载均衡中MASTER主机BACKUP主机之间的故障转移和自动切换;

  心跳检测:负载均衡定期检查RS服务器的可用性决定是否给其分发请求;

  B. VRRP(Vritrual Router Redundancy Protocol)协议:是一种容错协议,为了解决静态路由的单点故障;是通过一种竞选协议机制来将路由任务交给某台VRRP路由器,通过优先级来确定MASTER和BACKUP;保证当主机的下一条路由器出现故障时,由另一台路由器来替代出现故障的路由器进行工作,从而保证网络通信的连续性和可靠性,而且自身使用了加密协议;

  C. 故障切换转移原理:在Keepalived正常工作时,MASTER节点会不断的向BACKUP节点发送心跳消息,用来告诉BACKUP节点自己还活着,当MASTER节点发生故障时,BACKUP节点就无法继续检测到MASTER节点的心跳,进而调用自身的接管程序,接管MASTER节点的IP资源和服务,当MASTER节点恢复故障时,BACKUP节点会释放MASTER节点故障时自身接管的IP资源和服务,恢复到原来的自身的备用角色;

  D. 工作方式分类

  抢占式(默认模式):在抢占模式中,keepalived的某台机器挂了之后VIP漂移到了备节点,当主节点恢复后主会将VIP再次抢回,这就是keepalive的抢占模式。keepalived默认工作在抢占模式下。在抢占模式中,主节点的state设为MASTER,备节点的state设为BACKUP,主节点的优先级要比备节点的优先级要高。

   非抢占模式:两者的state都设为BUAKUP(官网说的),一个节点的优先级要比另一个节点的优先级要高,同时高优先级的节点设置nopreempt参数,该参数表示不抢占vip。这样,当高优先级的节点挂了之后,vip就会漂移到低优先级的节点上,但是当高优先级的节点再次恢复正常后再次起来后不会再抢回vip,因为它加了nopreempt参数。

## 一、介绍

- Keepalived:是一种高性能的服务器高可用或热备解决方案, Keepalived 可以用来防止服务器单点故障的发生,通过配合 Nginx 可以实现 web 前端服务的高可用。

- HAProxy:是一个使用C语言编写的自由及开放源代码软件,其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。

### 二、安装Haproxy

1.部署环境

|vip|ip|主机名|nginx端口|默认主从|

|-------|-------|-------|-------|-------|

|192.168.0.200|192.168.0.135|master1|90|master|

|192.168.0.200|192.168.0.136|node1|90|backup|

|web服务器|192.168.0.137|node2|90|nginx|

2.IP:192.168.0.135,192.168.0.136两台机器都安装HAProxy,Keepalived,IP:192.168.0.137安装nginx作为web服务器

HAProxy在编译安装时需要用到lua,并且lua的最低版本要求为5.3。目前CentOS8系列通过yum安装lua是符合版本要求的,而CentOS7及之前版本的Linux系统则无法达到该要求,因此要使用CentOS7或之前版本的Linux系统进行编译安装HAProxy,必须先编译安装较新版本的lua环境

![image-1678798093151](https://zmzycc.top/upload/2023/03/image-1678798093151.png)

4.lua在编译安装时需要用到gcc和readline-devel这两个依赖包。

```

yum -y install gcc openssl-devel pcre-devel systemd-devel readline-devel

curl -R -O http://www.lua.org/ftp/lua-5.4.4.tar.gz

tar zxf lua-5.4.4.tar.gz -C /usr/local/src

cd /usr/local/src/lua-5.4.4

make all test

```

5.编译安装完毕,可以看到lua程序文件在已解压的目录下的src子目录中,需记好该目录位置,后面编译安装HAProxy时要用到

6.安装haproxy,依赖

```

yum install gcc gcc-c++ make automake autoconf libtool pcre pcre-devel zlib zlib-devel openssl openssl-devel

wget https://www.haproxy.org/download/2.4/src/haproxy-2.4.4.tar.gz

tar -zxvf haproxy-2.4.4.tar.gz -C /usr/local/src

cd /usr/local/src/haproxy-2.4.4

make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_LUA=1 LUA_INC=/usr/local/src/lua-5.4.4/src/ LUA_LIB=/usr/local/src/lua-5.4.4/src/

```

7.编译完成后,我们可以看到目录下已经生成了HAProxy的二进制程序,接下来就是执行make install+指定程序安装位置命令来进行安装(注意PREFIX要使用大写)。

```

make install PREFIX=/etc/haproxy

```

同Nginx服务的编译安装相同,为了使用方便,建议针对HAProxy的路径创建软链接,此时直接执行haproxy -v命令已经能查看到版本信息等。

```

ln -s /etc/haproxy/sbin/haproxy /usr/local/bin

```

![image-1678799203068](https://zmzycc.top/upload/2023/03/image-1678799203068.png)

8.haproxy 启动脚本配置

```

vim /etc/systemd/system/haproxy.service

[unit]

Description=HAProxy Load Balancer

After=syslog.target network.target

[Service]

ExecStartPre=/etc/haproxy/sbin/haproxy -f /etc/haproxy/conf/haproxy.cfg -c -q

ExecStart=/etc/haproxy/sbin/haproxy -Ws -f /etc/haproxy/conf/haproxy.cfg -p /var/run/haproxy/haproxy.pid

ExecReload=/bin/kill -USR2 $MAINPID

[Install]

WantedBy=multi-user.target

```

9.由于启动脚本文件中设置的配置文件和PID文件存放路径并不存在,所以还需手动创建,同时可参考yum安装的HAProxy配置文件来写一个简化版的配置文件。与Nginx和Apache等服务相同,建议创建一个同名账号来管理服务。

```

adduser -s /sbin/nologin haproxy

mkdir /var/run/haproxy

mkdir /etc/haproxy/conf

```

vim /etc/haproxy/conf/haproxy.cfg

```

global

log 127.0.0.1 local0 info #local0是下面日志开启的关键,需保持一样

#log loghost local0 info

maxconn 20480 //最大连接限制(优先级低)

#chroot /usr/local/haproxy //工作目录(安全)

pidfile /var/run/haproxy.pid

#maxconn 4000

user haproxy

group haproxy

daemon //守护进程运行

#---------------------------------------------------------------------

#common defaults that all the 'listen' and 'backend' sections will

#use if not designated in their block

#---------------------------------------------------------------------

defaults

mode http //模式7层LB

log global //日志使用全局配置

option dontlognull

option httpclose //客户端和服务器完成一次连接请求后,HAProxy主动关闭TCP链接(优化选项)

option httplog //启用日志记录HTTP请求。

option forwardfor //启用后后端服务器可以获得客户端IP

option redispatch //用于cookie保持环境。(如后端服务器故障,客户端cookie不会刷新,用此来把用户请求强制定向到正常服务器)

balance roundrobin //负载均衡算法

timeout connect 10s //#连接服务器最长等待时间

timeout client 10s //客户端发送请求最长等待时间

timeout server 10s //服务器会复客户端最长等待时间

timeout check 10s //对后端服务器的检测超时时间

maxconn 60000 //最大连接数(优先级中)

retries 3 //健康检查。3次连接失败就认为服务不可用

#--------------统计页面配置------------------

listen admin_stats

bind 0.0.0.0:8189 #监控页面URL路径:ip:端口/admin_stats

stats enable

mode http

log global

stats uri /haproxy_stats //设置监控页面URL路径

stats realm Haproxy\ Statistics

stats auth admin:admin //账号和密码

stats hide-version //隐藏HAProxy版本信息

stats admin if TRUE //设置TURE后可在监控页面手工启动关闭后端真实服务器

stats refresh 30s //HAProxy监控页面统计自动刷新时间

#---------------web设置-----------------------

listen webcluster

bind 0.0.0.0:80

mode http

#option httpchk GET /index.html //启用HTTP服务状态检测功能 (后端服务器一定要存在此文件,不然haproxy认为其故障),就上面定义校验三次使用的方式

log global

maxconn 3000

balance roundrobin //负载均衡算法

server web01 192.168.35.137:80 check inter 2000 fall 5

```

haproxy算法:

```

1、roundrobin

轮询,在服务器的处理时间保持均匀分布时,这是最平衡,最公平的算法.此算法是动态的,这表示其权重可以在运行时进行调整.

2、static-rr

基于权重进行轮询,与roundrobin类似,但是为静态方法,在运行时调整其服务器权重不会生效.不过,其在后端服务器连接数上没有限制

3、leastconn

新的连接请求被派发至具有最少连接数目的后端服务器.

4、source

将请求的源地址进行hash运算,并由后端服务器的权重总数相除后派发至某匹配的服务器.这可以使得同一个客户端IP的请求始终被派发至某特定的服务器

```

10.启用日志

日志传输基于udp,所以需要取消这两行的注释。

vim /etc/rsyslog.conf

```

$ModLoad imudp

$UDPServerRun 514

```

在文件末尾添加

```

local0.* /var/log/haproxy.log #添加此行

```

systemctl restart haproxy rsyslog

11.没什么问题后就会在/var/log/haproxy.log日志中看到类似如下的日志了。

![image-1678805033333](https://zmzycc.top/upload/2023/03/image-1678805033333.png)

12.管理页面

![image-1678805459828](https://zmzycc.top/upload/2023/03/image-1678805459828.png)

### 三、安装keepalived

下载安装包,依赖

```

yum install gcc openssl-devel libnl3-devel net-snmp-devel -y

wget https://www.keepalived.org/software/keepalived-2.2.4.tar.gz

tar -zxvf keepalived-2.2.4.tar.gz

cd keepalived-2.2.4

./configure --prefix=/usr/local/keepalived/

make

make install

```

编写启动服务

vim /etc/systemd/system/keepalived.service

```

[Unit]

Description=LVS and VRRP High Availability Monitor

After=network-online.target syslog.target

Wants=network-online.target

Documentation=man:keepalived(8)

Documentation=man:keepalived.conf(5)

Documentation=man:genhash(1)

Documentation=https://keepalived.org

[Service]

Type=forking

PIDFile=/run/keepalived.pid

KillMode=process

EnvironmentFile=/usr/local/keepalived/etc/sysconfig/keepalived

ExecStart=/usr/local/keepalived/sbin/keepalived $KEEPALIVED_OPTIONS

ExecReload=/bin/kill -HUP $MAINPID

[Install]

WantedBy=multi-user.target

```

#从上面的文件我们可以看得出来,Keepalived使用/usr/local/keepalived/sbin/keepalived命令启动,并指定

#了$KEEPALIVED_OPTIONS参数,而这个参数是在环境变量的配置文件/usr/local/keepalived/etc/sysconfig/keepalived里定义

我们查看一下这个环境变量配置文件

![image-1678809866596](https://zmzycc.top/upload/2023/03/image-1678809866596.png)

修改添加-f /usr/local/keepalived/etc/keepalived/keepalived.conf -D -S 0

![image-1678812856960](https://zmzycc.top/upload/2023/03/image-1678812856960.png)

启动Keepalived

仍需检查一下keepalived的配置文件/usr/local/keepalived/etc/keepalived/keepalived.conf 参数,因为里面有个vip绑定的网卡,这个网卡写的不对,Keepalive启动仍会是失败。

vi /usr/local/keepalived/etc/keepalived/keepalived.conf

interface ens33 #vip绑定的网卡名称,填写你的网卡名称

```

systemctl daemon-reload #重载

systemctl stop keepalived.service

systemctl start keepalived.service #启动keepalived

systemctl status keepalived.service #keepalived状态正常

```

![image-1678812939818](https://zmzycc.top/upload/2023/03/image-1678812939818.png)

到这里,keepalived已经正常启动了,但是加载的配置文件内容是官网给的样例,我们仍需要修改配置

192.168.0.135作为主keepalived

配置文件如下

```

! Configuration File for keepalived

global_defs { #全局参数

router_id LVS_01 #指定名称,各个服务器名称要不一样

}

vrrp_instance VI_1 { #指定vrrp热备参数

state MASTER #服务器角色是master,备份服务器设置为BACKUP

interface enp2s0 #修改物理网卡名称,默认是centos6的eth0

virtual_router_id 10 #组号相同

priority 150 #优先级,主服务器设置要大于备服务器

advert_int 1

authentication {

auth_type PASS #验证类型和密码,不建议修改

auth_pass 123

}

virtual_ipaddress {

192.168.0.100 #漂移地址(VIP)地址,可以有多个

}

}

```

网卡名称

```

ip addr

```

![image-1679307891927](https://zmzycc.top/upload/2023/03/image-1679307891927.png)

systemctl start keepalived

192.168.0.136作为从keepalived

```

! Configuration File for keepalived

global_defs { #全局参数

router_id LVS_02 #指定名称,各个服务器名称要不一样

}

vrrp_instance VI_1 { #指定vrrp热备参数

state BACKUP #服务器角色是master,备份服务器设置为BACKUP

interface ens33 #修改物理网卡名称,默认是centos6的eth0

virtual_router_id 10 #组号相同

priority 145 #优先级,主服务器设置要大于备服务器

advert_int 1

authentication {

auth_type PASS #验证类型和密码,不建议修改

auth_pass 123

}

virtual_ipaddress {

192.168.0.100 #漂移地址(VIP)地址,可以有多个

}

}

```

![image-1679308197767](https://zmzycc.top/upload/2023/03/image-1679308197767.png)

重启keepalived

systemctl restart keepalived

此时可通过192.168.0.100访问

![image-1679308854526](https://zmzycc.top/upload/2023/03/image-1679308854526.png)

可关闭主keepalived服务,测试。还是能访问nginx首页,说明从节点已经拉起

如果要监控指定应用可以通脚本参数,在配置文件/usr/local/keepalived/etc/keepalived/keepalived.conf中加入

```

vrrp_script check_nginx { #定义要检测的脚本,check_nginx是指定的检测脚本名称

script /etc/keepalived/check_nginx.sh #指定哪个脚本,定义脚本路径

interval 2 #脚本检测的时间间隔,表示每n秒就检查一次,默认1秒就检测一次

timeout 2 #脚本检测超时时间,超过这个时间则认为检测失败

#通过此权重调整优先级,(默认值:0)

#有关反转的描述,请参见track_script。

#'weight 0 reverse' 将在脚本启动时导致vrrp实例关闭,反之亦然。

weight 0 #这个参数会调整优先级的,保持默认值0吧

rise 2 # 表示需要连续成功2次才能认为是成功的

fall 2 # 表示需要连续失败2次才能认为是失败的

user root # 指定哪个用户指定脚本

init_fail #设置默认脚本最初为失败状态,监测成功之后再转换为成功状态

}

```

完整的配置文件

```

! Configuration File for keepalived

global_defs { #全局参数

router_id LVS_02 #指定名称,各个服务器名称要不一样

}

vrrp_script check_nginx { #定义要检测的脚本,check_nginx是指定的检测脚本名称

script /etc/keepalived/check_nginx.sh #指定哪个脚本,定义脚本路径

interval 2 #脚本检测的时间间隔,表示每n秒就检查一次,默认1秒就检测一次

timeout 2 #脚本检测超时时间,超过这个时间则认为检测失败

#通过此权重调整优先级,(默认值:0)

#有关反转的描述,请参见track_script。

#'weight 0 reverse' 将在脚本启动时导致vrrp实例关闭,反之亦然。

weight 0 #这个参数会调整优先级的,保持默认值0吧

rise 2 # 表示需要连续成功2次才能认为是成功的

fall 2 # 表示需要连续失败2次才能认为是失败的

user root # 指定哪个用户指定脚本

init_fail #设置默认脚本最初为失败状态,监测成功之后再转换为成功状态

}

track_script { #指定要检测的脚本

check_nginx #指定我们定义的要检查的脚本名称

}

vrrp_instance VI_1 { #指定vrrp热备参数

state BACKUP #服务器角色是master,备份服务器设置为BACKUP

interface ens33 #修改物理网卡名称,默认是centos6的eth0

virtual_router_id 10 #组号相同

priority 145 #优先级,主服务器设置要大于备服务器

advert_int 1

authentication {

auth_type PASS #验证类型和密码,不建议修改

auth_pass 123

}

virtual_ipaddress {

192.168.0.100 #漂移地址(VIP)地址,可以有多个

}

}

```

脚本的意义:检测当前服务是否掉线,如果掉线就主动kill掉“主keepalived服务”,让“备keepalived服务”启动。