#keepalived
keepalived原理:
基于VIP (虚拟IP) vrrp协议,即建立一个虚拟IP地址(如172.24.0.1/16),让所有设备都能连接这个虚拟的IP,通过配置主从,master首先使用虚拟IP,slave standby状态,master机器主动定时(如1s)广播状态给slave,
如果slave一定时间内没有接收到master的广播,认定master down机,从而slave主动且切换到该虚拟IP;
问:keepalived一定要接入LVS吗?
答:keepalived初始就是为了解决LVS负载均衡而出现的,后期加入了vrrp协议提高了高可用并实现了IP漂移,keepalived三大核心模块之一就有LVS,但是使用keepalived IP漂移是在virtual_server上实现的,虽然理论上不接virtual_server或者只接一台real_server机器,但实际后端服务都是集群容灾形式,所以keepalived不一定非要接入LVS,但是通常我们都接入了LVS;
问:LVS是啥?
答:LVS是集群的负载均衡解决方案,在keepalived高可用集群中,配置文件virtual_server指令块的内容就是LVS配置项
前提:
由于VIP(虚拟IP)只能在子网实现,所以机器只能是在同一个子网中(例如是同一个交换机分出来的设备,而不是独立网络的设备)
服务对接:
上游服务,需接入到装有keepalived的子网中,可直接访问虚拟IP,一般来说上游是接核心交换机,虚拟IP转换成公网IP,测试环境可以接成nginx反向代理实现该功能
下游服务,接入keepalived的real_server服务中
快速搭建:
环境:树莓派4B,额外说明,在公司测试环境和生产环境已验证过,和树莓派方式差不多;
角色:root
方式:apt
安装:
apt install keepalived -y
调试牢记:apt安装的软件配置文件基本都放在/etc/目录下,日志文件基本放在/var/log/目录下,centos7.5和树莓派都测试过,方法一致,KP配置文件/etc/keepalived/keepalived.conf,KP日志文件/var/log/message
配置文件主要块功能说明:
global_defs{}:全局块,主要放置的是预警邮件地址或router id等唯一机器标识或一些其他全局信息,此模块为配置文件必要模块
vrrp_script <块名>{}:脚本块,主要作用是配置监测脚本位置及其执行时间和执行后动作模块,非必须模块,可以在配置文件中不写该块, 如果后端直接接服务,如数据库,建议写入,指定监测服务是否存活的脚本,如果后端接K8S等有额外功能的中间件,可以不写该块
vrrp_instance <块名>{}:vrrp实列块,主要作用是建立一个keepalived集群使用的虚拟IP及其配置keepalived集群个master/backup之间的关系和权重等,非必须模块,如果只是单台机器搭建keepalived可以不需要该模块,若是有多台机器做keepalived的高可用主备集群,需要该模块建立集群通信广播、虚拟IP和配置主从关系,注意该虚拟IP就是给外网访问的可漂移的IP,这里的IP可以是单个也可以是多个;
virtual_server
查看配置文件:
建议参考官方文档:
https://www.keepalived.org/doc/configuration_synopsis.html#vrrp-instance-definitions-synopsis
cd /etc/keepalived/
cat keepalived.conf
! Configuration File for keepalived
global_defs { #全局参数
notification_email {
[email protected] #告警邮件收件人地址
}
notification_email_from [email protected] #邮件发件人地址
smtp_server 192.168.200.1 #发送邮件服务器地址,可以是本机也可以不是本机
smtp_connect_timeout 30 #邮件服务器连接超时
router_id 192.168.1.7 #发送告警邮件的IP主机,最好是主机IP,如果down了该机器,会发送down掉的机器id,可快速判定挂掉的机器位置
vrrp_skip_check_adv_addr
#vrrp_strict #配置这个参数不能直接访问本机服务,注意
vrrp_garp_interval 0
vrrp_gna_interval 0
}
#监测服务是否正常脚本,非必须
vrrp_script check_nginx {
script "/etc/keepalived/scripts/check_nginx.sh"
#间隔
interval 3
#失败后重试次数
fall 3
}
#keepalived实列配置,主要是建立一个keepalived集群通信的虚拟IP及其相关属性,
#注意,相同服务的keepalived集群的virtual_router_id需要一致,而不同服务则不能一致,
#所以这里也可以设置多个vrrp_instance,比如,对接K8S设置一个vrrp_instance,对接MySQL设置一个vrrp_instance,对接nginx设置一个vrrp_instance,即一个keepalived用作多个服务的高可用
vrrp_instance VI_1 {
#MASTER或者BACKUP,如果MASTER初始的权重没有BACKUP高,会被主动切换到BACKUP;
state MASTER
#采用的接口网卡,注意后续所有的虚拟IP都需要在网卡支持的网段范围内,
#比如centos默认是ens33,树莓派是eth0,用ifconfig查看网卡网段,如果网卡只有192.168的内网网段那么虚拟IP也必须要用这个网段
interface eth0
#设置为不抢占,说明:这个配置只能在BACKUP主机上面设置
#nopreempt|preempt
#抢占时间,说明:这个配置只能在BACKUP主机上面设置
#preempt delay 300
#设置VRID标记,不同服务集群内不能重复
virtual_router_id 51
#权重,越高越容易被选为主
priority 100
#心跳监测时间,默认1s
advert_int 1
#VIP组是否需要认证才能加入
authentication {
#验证方式,默认PASS
auth_type PASS
#验证密码,默认1111
auth_pass 1111
}
#这里就是内网中有VIP心跳的虚拟IP,用于检测keepalived集群机器的存活,如果master机器挂了这个IP广播就会不通,backup机器就会主动提升到master,
#虚拟IP可以是一个也可以是多个,多个虚拟IP作用是可以让多个服务使用,如果只是一个服务,如只接K8S,一个IP就够了
#比如K8S使用一个虚拟IP,nginx使用一个虚拟ip,各机器都需要加入相同数据才能加入虚拟IP组
virtual_ipaddress {
#虚拟ip,后面可以指定挂载在那个网卡上,方式:192.168.10.80/32 dev eth0,或者挂载在那个网卡别名上:192.168.200.16/32 dev label eth1:1
192.168.10.16
}
#可选执行脚本,非必须,写法和vrrp_script一样
#track_script {
#}
}
#LVS负载均衡和服务可漂移的虚拟IP配置
#这个IP是就是可漂移的虚拟IP,每个keepalived的机器上virtual_server配置都需要一样才能保障IP正常的漂移
#virtual_server的IP必须要和virtual_ipaddress中的IP地址一致或是virtual_ipaddress地址中的一个
virtual_server 192.168.10.30 80 {
#6秒循环监测
delay_loop 6
# 算法,默认rr
lb_algo rr
# 模式,默认NAT,可以是DR|TUN,注意keepalived和后端服务机器在同一网段下,虚拟IP单独设置一个网段IP,NAT模式会访问不了后端服务,
#这里的模式选择很重要,选错会产生很多无法访问的异常
lb_kind NAT
#连接超时时间
persistence_timeout 50
#连接协议
protocol TCP
# 如果后端应用服务器都不可用,就会定向到那个服务器上
#sorry_server 192.168.200.200 1358
#这个IP是keepalived转发服务的后端服务机器IP,比如后端饥饿nginx机器IP,k8s集群IP等
real_server 192.168.1.7 80 {
#权重
weight 1
#针对应用服务器做健康检查的方法,可以是MSIC_CHECK|SMTP_CHEKC|TCP_CHECK|SSL_GET|HTTP_GET等多种形式,例如:
## 用于检查SMTP服务器的:SMTP_CHEKC {},如果应用服务器不是WEB服务器,就用TCP_CHECK检查:TCP_CHECK {}
#如果对方是HTTPS服务器就用SSL_GET方法去检查 SSL_GET {},使用HTTP_GET方法去检查: HTTP_GET{}
#这里默认的是SSL方法和HTTP_GET用法差不多,但建议还是用TCP_CHECK,最常用和最简单的方式
SSL_GET {
# 检测URL
url {
# 具体检测哪一个URL
path /
# 检测内容的哈希值
digest ff20ad2481f97b1754ef3e12ecd3a9cc
# 除了检测哈希值还可以检测状态码,比如HTTP的200 表示正常,两种方法二选一即可,默认配置是检测哈希值
#status_code 200
}
url {
path /mrtg/
digest 9b3a0c85a887a256d6939da88aabd8cd
}
#向哪一个端口检查,如果不指定默认使用上面定义的端口
#connect_port
# 向哪一个IP检测,如果不指定默认使用上面定义的IP地址
#bindto
connect_timeout 3 # 连接超时时间
nb_get_retry 3 # 尝试次数
delay_before_retry 3 # 每次尝试之间间隔几秒
}
#建议使用TCP_CHECK,当然如果是挂载web服务器,最好还是用http模式检查
TCP_CHECK{
connect_port 80
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
#第二台后端服务机器配置
real_server 192.168.1.4 80 {
weight 2
TCP_CHECK{
connect_port 80
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
#第三台后端服务机器配置
real_server 192.168.1.8 80 {
weight 2
TCP_CHECK{
connect_port 80
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
#如果在keepalived中还想给其他服务配置,比如数据库/中间件等,则在这里就可以再添加vrrp_instance和virtual_server,
#同一个配置文件中不同服务之间virtual_router_id不能相同,而相同服务不同机器之间virtual_router_id各keepalived集群机器配置文件除了主从和权重其他的都需要一致
#vrrp_instance{}
#virtual_server{}
异常排查于解决:
排查:
方式:看日志,默认位置打在系统日志里面,/var/log/message
问题点:
如果当前运行的是主节点并且出现:VRRP_Instance(VI_1) removing protocol VIPs
代表该服务异常,异常来源在这个日志前后会展示,该信息表示因为某种异常导致VIP被移除掉成为不可用状态
可能异常:
1、Unable to load ipset library - libipset.so
没有ipset库,虽然git上说keepalived默认不使用ipset,但既然报错了,安装下也许会解决
以下命令是在公司测试环境centos7下执行的,debian或树莓派相关命令可能有所区别
yum install ipset libnl3-devel ipset-devel
2、虚拟IP能PING通,不能telnet后端服务
这种现象可能有多种情况:
1、arp 缓存,清除即可,arp -n|awk '/^[1-9]/{system("arp -d "$1)}'
2、防火墙,关闭
3、lb_kind选择的通信模式于虚拟IP网段和真实服务IP网段冲突,比如,telnet的机器是内网同真实IP同一网段,然后虚拟IP设置另一个网段,此时通信模式选择NAT时,是无法访问后端的
解决:可以把虚拟IP地址和真实IP放在同一网段下或者调整通信模式,具体知识点参考LVS原理
4、主机能访问从机不能访问,查看virtual_router_id是否一致,相同组的机器virtual_router_id需要一致
5、从加入主后整体不可访问,查看从机和主机配置是否有冲突,比如master、权重等
3、虚拟IP不通
1、关闭vrrp_strict
2、虚拟IP需要设置为网卡支持的IP
心得:
1、lb_kind可以设置为NAT、DR、TUN。这个选项直接关系到你做的 virtual_server和real_server能否进行正确映射
2、日志没有error级别的,所以要多仔细读
3、配置文件冲突要避免
主要还是对网络通信知识需要加深了解
有一个现象不知道有没有人关注过:
假设:我有两台机器A 192.168.32.53 ;B 192.168.32.55,构建虚拟IP地址为:192.168.32.100 端口80
若在A B上同时安装keepalived和nginx,如果nginx默认是80端口
那么启动curl http://192.168.32.100 的时候,53机器永远只会得到55机器nginx的反馈,55机器永远只会得到53机器nginx的反馈,
若55机器下掉了ngixn,那么53机器会curl不通报错网络异常;
这是由于nginx 的网络服务端口和虚拟IP 80端口冲突导致的,即使配置权重也不会得到任何改变,所以后端服务端口建议不要和虚拟IP同一个端口,或者用单独机器跑keepalived
最后贴一下我的测试环境配置文件:
主:
#! Configuration File for keepalived
global_defs {
# notification_email {
# [email protected]
# [email protected]
# [email protected]
# }
# notification_email_from [email protected]
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id 11
vrrp_skip_check_adv_addr
# vrrp_strict
# vrrp_garp_interval 0
# vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 11
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.32.100
}
}
virtual_server 192.168.32.100 80{
delay_loop 6
lb_algo rr
lb_kind NAT
persistence_timeout 50
protocol TCP
# sorry_server 192.168.200.200 1358
real_server 192.168.32.53 80 {
weight 2
TCP_CHECK {
connect_timeout 3
delay_before_retry 3
}
}
real_server 192.168.32.55 80 {
weight 2
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
从:
#! Configuration File for keepalived
global_defs {
# notification_email {
# [email protected]
# [email protected]
# [email protected]
# }
# notification_email_from [email protected]
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id 53
vrrp_skip_check_adv_addr
# vrrp_strict
# vrrp_garp_interval 0
# vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 11
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.32.100
}
}
virtual_server 192.168.32.100 80{
delay_loop 6
lb_algo rr
lb_kind NAT
persistence_timeout 50
protocol TCP
# sorry_server 192.168.200.200 1358
real_server 192.168.32.53 80 {
weight 2
TCP_CHECK {
connect_timeout 3
delay_before_retry 3
}
}
real_server 192.168.32.55 80 {
weight 2
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}