1、简述keepalived工作原理
总的来说keepalived的功能主要有两个:
1、集群中各个服务节点的健康状态检查
2、服务的高可用
原理:
Keepalived高可用对之间是通过 VRRP进行通信的, VRRP是通过竞选机制来确定主备的,主的优先级高于备,因此,工作时主会优先获得所有的资源,备节点处于等待状态,当主宕机的时候,备节点就会接管主节点的资源,然后顶替主节点对外提供服务;
在Keepalived服务对之间,只有作为主的服务器会一直发送 VRRP广播包,告诉备它还活着,此时备不会抢占主,当主不可用时,即备监听不到主发送的广播包时,就会启动相关服务接管资源通过选举形式来选择新的主,保证业务的连续性.接管速度最快。
1-2、什么是脑裂
在高可用的系统中,当联系的两个节点之间的‘心跳线’断开时,本来为一个整体、动作协调的HA系统,就分裂成为2个独立的个体。相互之间失去了联系,都以为对方出现了故障。两个故障节点上机器,争抢“共享资源”、争起“应用服务”,就会出现严重的后果,两边的服务都起不来或者两边的服务同时起来,同时提供读写服务,导致数据被破坏。
1-3、脑裂产生的原因
1、高可用服务器(keepalived)之间的心跳线路发生故障,到时无法正常通信
2、心跳线坏了(断了、或者老化)
3、因网卡及相关驱动坏了,ip配置及冲突问题(网卡连接)
4、心跳线之间连接的设备故障(网卡或者交换机)
5、因仲裁的机器出问题(采用仲裁的方案)
6、高可用服务器上开启了iptables防火墙阻挡了心跳消息传输
7、高可用服务器上心跳网卡地址等信息配置不正确,到时发送心跳失败
8、其他服务配置不当,比如心跳方式不同,心跳广插冲突,软件bug等
1-4、解决脑裂的方案
1、同时使用串行电缆和以太网电缆连接,同时用两条心跳线路,这样一条线路故障之后,另一个依然可以使用
2、当检测到裂脑时强行关闭一个心跳节点(这个功能需特殊设备支持,如Stonith、feyce)。相当于备节点接收不到心跳消患,通过单独的线路发送关机命令关闭主节点的电源。
3、做好对裂脑的监控报警(如邮件及手机短信等或值班).在问题发生时人为第一时间介入仲裁,降低损失。管理员可以通过手机回复对应数字或简单的字符串操作返回给服务器.让服务器根据指令自动处理相应故障这样解决故障的时间更短。
1-5、与heartbeat/corosync等的比较
Heartbeat、Corosync、Keepalived这三个集群组件我们到底选哪个好,Heartbeat、Corosync是属于同一类型,Keepalived与Heartbeat、Corosync,根本不是同一类型的。Keepalived使用的vrrp虚拟路由冗余协议方式;Heartbeat或Corosync是基于主机或网络服务的高可用方式;简单的说就是,Keepalived的目的是模拟路由器的高可用,Heartbeat或Corosync的目的是实现Service的高可用。
所以一般Keepalived是实现前端高可用,常用的前端高可用的组合有,就是我们常见的LVS+Keepalived、Nginx+Keepalived、HAproxy+Keepalived。而Heartbeat或Corosync是实现服务的高可用,常见的组合有Heartbeat v3(Corosync)+Pacemaker+NFS+Httpd 实现Web服务器的高可用、Heartbeat v3(Corosync)+Pacemaker+NFS+MySQL 实现MySQL服务器的高可用。总结一下,Keepalived中实现轻量级的高可用,一般用于前端高可用,且不需要共享存储,一般常用于两个节点的高可用。而Heartbeat(或Corosync)一般用于服务的高可用,且需要共享存储,一般用于多节点的高可用。
2、编译安装haproxy
由于centos7之前自带的lua版本太低,不适合haproxy要求的最低(5.3)版本的需求,需要下载编译安装新版本的lua环境,才能编译安装haproxy等
编译安装lua5.4.4
yum install -y gcc readline-devel
wget http://www.lua.org/ftp/lua-5.4.4.tar.gz
tar xvf lua-5.4.4.tar.gz -C /usr/local/src
cd /usr/local/src/lua-5.4.4/
make linux test
src/lua -v
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
编译安装haproxy
yum -y install gcc openssl-devel pcre-devel systemd-devel
tar xvf haproxy-2.3.10.tar.gz -C /usr/local/src
cd /usr/local/src/haproxy-2.3.10/
编译安装选项:根据自己的安装路径,指定相应的地址,我这里的lua路径是/usr/local/src/lua-5.4.4/src/
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/
执行编译安装
make install PREFIX=/apps/haproxy
创建软连接
ln -s /apps/haproxy/sbin/haproxy /usr/sbin/
生成的文件
[root@centos7 ~]#tree /apps/haproxy/
/apps/haproxy/
├── doc
│ └── haproxy
│ ├── 51Degrees-device-detection.txt
│ ├── architecture.txt
│ ├── close-options.txt
│ ├── configuration.txt
│ ├── cookie-options.txt
│ ├── DeviceAtlas-device-detection.txt
│ ├── intro.txt
│ ├── linux-syn-cookies.txt
│ ├── lua.txt
│ ├── management.txt
│ ├── netscaler-client-ip-insertion-protocol.txt
│ ├── network-namespaces.txt
│ ├── peers.txt
│ ├── peers-v2.0.txt
│ ├── proxy-protocol.txt
│ ├── regression-testing.txt
│ ├── seamless_reload.txt
│ ├── SOCKS4.protocol.txt
│ ├── SPOE.txt
│ └── WURFL-device-detection.txt
├── sbin
│ └── haproxy
└── share
└── man
└── man1
└── haproxy.1
6 directories, 22 files
查看haproxy的版本
[root@centos7 ~]#haproxy -v
HA-Proxy version 2.3.10-4764f0e 2021/04/23 - https://haproxy.org/
Status: stable branch - will stop receiving fixes around Q1 2022.
Known bugs: http://www.haproxy.org/bugs/bugs-2.3.10.html
Running on: Linux 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64
创建自定义的service文件
vim /usr/lib/systemd/system/haproxy.service
[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target
[Service]
ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q
ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/lib/haproxy/hap
roxy.pid
ExecReload=/bin/kill -USR2 $MAINPID
LimitNOFILE=100000
[Install]
WantedBy=multi-user.target
创建haproxy.cfg配置文件
mkdir /etc/haproxy
vim /etc/haproxy/haproxy.cfg
global
maxconn 100000
chroot /apps/haproxy
stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
#uid 99
#gid 99
user haproxy
group haproxy
daemon
#nbproc 4
#cpu-map 1 0
#cpu-map 2 1
#cpu-map 3 2
#cpu-map 4 3
pidfile /var/lib/haproxy/haproxy.pid
log 127.0.0.1 local2 info
defaults
option http-keep-alive
option forwardfor
maxconn 100000
mode http
timeout connect 300000ms
timeout client 300000ms
timeout server 300000ms
listen stats
mode http
bind 0.0.0.0:9999
stats enable
log global
stats uri /haproxy-status
stats auth haadmin:123456
listen web_port
bind 192.168.1.142:80
mode http
log global
server web1 192.168.1.29:80 check inter 3000 fall 2 rise 5
创建socket文件夹,并设置权限
mkdir /var/lib/haproxy
useradd -r -s /sbin/nologin -d /var/lib/haproxy haproxy
启动haproxy
systemctl daemon-reload
systemctl enable --now haproxy
[root@centos7 ~]#systemctl status haproxy
● haproxy.service - HAProxy Load Balancer
Loaded: loaded (/usr/lib/systemd/system/haproxy.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2022-04-12 15:39:37 CST; 3s ago
Process: 12492 ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q (code=exited, status=0/SUCCESS)
Main PID: 12495 (haproxy)
CGroup: /system.slice/haproxy.service
├─12495 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/lib/haproxy/haproxy.pid
└─12498 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/lib/haproxy/haproxy.pid
Apr 12 15:39:37 centos7.4-6 systemd[1]: Starting HAProxy Load Balancer...
Apr 12 15:39:37 centos7.4-6 systemd[1]: Started HAProxy Load Balancer.
Apr 12 15:39:37 centos7.4-6 haproxy[12495]: [NOTICE] 101/153937 (12495) : New worker #1 (12498) forked
查看进程
[root@centos7 ~]#pstree | grep haproxy
|-haproxy---haproxy---{haproxy}
3、总结haproxy各调度算法的实现方式及其应用场景
HAProxy通过固定参数 balance 指明对后端服务器的调度算法,该参数可以配置在listen或backend选项中
3-1、静态算法
按照事先定义好的规则轮询进行调度,不关心后端服务器的当前负载、连接数和响应速度等,且无法实时动态修改权重(只能为0和1,不支持其它值)或者修改后不生效,如果需要修改只能靠重启HAProxy生效。
static-rr:
基于权重的轮询调度,不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其它值)及后端服务器慢启动,其后端主机数量没有限制,相当于LVS中的 wrr。
first:
根据服务器在列表中的位置,自上而下进行调度,但是其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务,因此会忽略服务器的权重设置,此方式使用较少。
3-2、动态算法
roundrobin:
基于权重的轮询动态调度算法,支持权重的运行时调整,不同于lvs中的rr轮训模式,
HAProxy中的roundrobin支持慢启动(新加的服务器会逐渐增加转发数),其每个后端backend中最多支持4095个real server,支持对real server权重动态调整,roundrobin为默认调度算法,此算法使用广泛。
leastconn :
加权的最少连接的动态,支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客户端连接),比较适合长连接的场景使用,比如:MySQL等场景。
random:
在1.9版本开始增加 random的负载平衡算法,其基于随机数作为一致性hash的key,随机负载平衡对于大型服务器场或经常添加或删除服务器非常有用,支持weight的动态调整,weight较大的主机有更大概率获取新请求
3-3、其他算法
source:
源地址hash,基于用户源地址hash并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端web服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过hash-type选项进行更改。
map-base 取模法
对source地址进行hash计算,再基于服务器总权重的取模,最终结果决定将此
请求转发至对应的后端服务器。此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度。缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变,hash-type 指定的默认值为此算法。
一致性 hash
一致性哈希,当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动,hash(o)mod n ,该hash算法是动态的,支持使用 socat等工具进行在线权重调整,支持慢启动。
uri
基于对用户请求的URI的左半部分或整个uri做hash,再将hash结果对总权重进行取模后,根据最终结果将请求转发到后端指定服务器,适用于后端是缓存服务器场景,默认是静态算法,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性hash。
注意:此算法基于应用层,所以只支持 mode http ,不支持 mode tcp
url_param
url_param对用户请求的url中的 params 部分中的一个参数key对应的value值作hash计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个real server,如果无没key,将按roundrobin算法。
hdr
针对用户每个http头部(header)请求中的指定信息做hash,此处由 name 指定的http首部将会被取出并做hash计算,然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度。
rdp-cookie
rdp-cookie对远windows远程桌面的负载,使用cookie保持会话,默认是静态,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性hash。
3-4、算法总结
静态
static-rr--------->tcp/http
first-------------->tcp/http
动态
roundrobin-------->tcp/http
leastconn--------->tcp/http
random------------>tcp/http
以下静态和动态取决于hash_type是否consistent
source------------>tcp/http
Uri---------------------->http
url_param------------>http
hdr--------------------->http
rdp-cookie------------>tcp
3-5、各种算法的使用场景
first---------------------------->使用较少
static-rr----------------------->做session共享的 web 集群
roundrobin------------------->同上
random----------------------->同上
leastconn-------------------->数据库
source ----------------------->基于客户端公网 IP 的会话保持
Uri--------------->http,一般用于缓存服务器,CDN服务商,蓝汛、百度、阿里云、腾讯
url_param--------->http ,一般用于可以实现session保持
hdr ---------------------------->基于客户端请求报文头部做下一步处理
4、使用haproxy的ACL实现基于文件后缀名的动静分离"
添加子配置文件,保存配置
mkdir /etc/haproxy/conf.d/
vim /etc/haproxy/conf.d/srv2.cfg
frontend shenqiqi_http_port
bind 192.168.1.11:80 #haproxy的监听地址
mode http #指定负载协议类型
log global # 开启日志功能
balance roundrobin #指定调度算法
option httplog #启用日志记录HTTP请求、会话状态和计时器的功能
########################## acl setting ############################
acl acl_static path_end -i .jpg .jpeg .png .gif .css .js .html #以.jpg .jpeg .png .gif .css .js .html为结尾的访问,命令为acl_static静态资源
acl acl_php path_end -i .php #以.php为结尾的访问,命令为acl_php动态资源
########################## acl hosts ##############################
use_backend mobile_hosts if acl_static #如果访问的是静态资源,就转向后端mobile_hosts主机组
use_backend app_hosts if acl_php #如果访问的是动态资源,就转向后端app_hosts主机组
default_backend pc_hosts #默认访问的是 pc_hosts主机组
########################## backend hosts ##########################
backend mobile_hosts
mode http #指定负载协议类型,必须和上面frontend一致
server web1 192.168.1.12:80 check inter 2000 fall 3 rise 5 #后端web1,地址和端口号,并且要健康检查,健康状态检查间隔时间2000 ms,后端服务器从线上转为线下的检查的连续失效次数,默认为3,
后端服务器从下线恢复上线的检查的连续有效次数,默认为5。
backend app_hosts
mode http
server web2 192.168.1.13:80 check inter 2000 fall 3 rise 5
▽ackend pc_hosts
mode http
server web2 192.168.1.13:80 check inter 2000 fall 3 rise 5
访问测试
[root@192.168.1.12 html]#pwd
/var/www/html
[root@192.168.1.12 html]#ls
1.jpg index.html
[root@192.168.1.13 html]#pwd
/var/www/html
[root@192.168.1.13 html]#ls
test.php
测试界面1
测试界面2