keepalived介绍
keepalived相关原理,可以参考网络教程 负载均衡之备胎转正 以及 骏马金龙keepalived系列教程,以下为简单介绍。
keepalived是使用C语言编写的路由热备软件,该项目软件起初是专门为LVS负载均衡设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可以实现高可用的VRRP功能。因此,
keepalived除了能够管理LVS软件外,还可以作为其他服务(例如:Nginx,Haproxy,MySQL等)的高可用解决方案软件。
keepalived通过VIP(虚拟IP)使服务对外提供统一的访问入口,通过VIP在多台服务器间切换实现服务故障转移,即VIP漂移。
keepalived VIP漂移触发机制包括:实例加入、实例故障、实例权重变化等
keepalived主要是通过VRRP协议实现高可用功能的。VRRP是Virtual Router Redundancy Protocol(虚拟路由器冗余协议)的缩写,VRRP出现的目的就是为了解决静态路由单点故障问题的,它能够保证当个别节点宕机时,整个网络可以不间断地运行。
Keepalived服务的工作原理
- keepalived高可用之间是通过VRRP进行通信的,VRRP是通过竞选机制来确定主备的,主的优先级高于备,因此,工作时主会优先获得所有的资源,备节点处于等待状态,当主挂了的时候,备节点就会接管主节点的资源,然后顶替主节点对外提供服务。
- 在keepalived服务之间,只有作为主的服务器会一直发送VRRP广播包,告诉备它还活着,此时备不会抢占主,当主不可用时,即备监听不到主发送的广播包时,就会启动相关服务接管资源,保证业务的连续性。接管速度最快可以小于1秒。
所以,keepalived提供了两个主要功能:
- LVS节点健康检查
- 实施VRRP协议以处理负载均衡器故障转移,即高可用
keepalived服务架构
- keepalived服务启动时,将产生三个相关进程,一个父进程和两个子进程
- 主进程:Watchdog看门狗主进程
- 子进程1:VRRP Child
- 子进程2:Healthchecking Child
- 两个子进程都会开启本地套接字Unix Domain Socket
- 当keepalived服务启动后,父进程会通过unix domain socket每隔5秒发送一个hello消息给子进程
- 如果父进程无法发送消息给子进程,将认为子进程出现问题,于是会重启子进程
- 核心组件
- Watchdog
- 看门狗,负责fork和监控子进程,对Checkers和vrrp stack进行监控
- Checkers
- 负责RealServer的健康状况检查,并在LVS的拓扑中移除、添加RealServer
- 它支持layer4/5/7层的协议检查,该组件使用独立的子进程负责,但被父进程监控
- VRRP Stack
- 提供Director的故障转移功能从而实现Director的高可用
- 该组件可独立提供功能,无需LVS的支持,该组件使用独立的子进程负责,但被父进程监控
- System Call
- 提供读取自定义脚本的功能,该组件在使用时,将临时产生一个子进程来执行任务
- IPVS wrapper
- 负责将配置文件中的IPVS相关规则发送到内核的ipvs模块
- Netlink Reflector
- 用来设定、监控vrrp的ip地址
- IO复用器
- 内存管理
- 配置文件分析器
特别关注
keepalived运行时会根据实际使用的组件启动进程,共 2-3 个,所以如果要做keepalived服务的守护,请根据实际使用情况识别进程。
keepalived安装
方式有:yum安装、二进制安装。
本文介绍二进制安装方式,因为系统yum仓库中keepalived版本一般很低,如CentOS7.5yum源,keepalived版本为1.3.5,而截至当前,官方版本为2.2.7。
组件安装操作步骤参考 组件安装部署手册模板,根据不同组件的安装目标,部分操作可以省略。
本文将按照该参考步骤执行。
一、获取组件可执行程序库,包括主程序,此为组件的基本文件
1.官网下载keepalived源码
创建目录 /usr/local/keepalived,将源码包下载到该目录下
2.安装依赖组件
keepalived组件编译安装依赖一些第三方组件
yum -y install make gcc openssl-devel libnfnetlink-devel libnl3-devel net-snmp-devel
3.解压安装
源码安装步骤包括 配置(configure)、编译(make)、安装(make install)
[root@localhost keepalived]# tar -zxvf keepalived-2.2.7.tar.gz [root@localhost keepalived]# cd keepalived-2.2.7/ #--prefix指定安装的路径,组件文件统一存放,方便日后卸载删除 [root@localhost keepalived-2.2.7]# ./configure --prefix=/usr/local/keepalived #-j 4指定并行编译任务数,适用多核CPU,一般配置为cpu核数的2倍 [root@localhost keepalived-2.2.7]# make -j 4 && make install
二、安装系统服务
make install安装完成后,自动生成系统服务文件,其中
service文件存放在 /usr/lib/systemd/system/keepalived.service
[root@localhost ~]# ll /usr/lib/systemd/system/keepalived.service -rw-r--r--. 1 root root 540 1月 28 09:34 /usr/lib/systemd/system/keepalived.service
三、主程序加入到环境变量
1.将keepalived主程序拷贝到环境变量目录,可以直接拷贝主程序文件,或创建软连接
[root@localhost keepalived-2.2.7]# cd /usr/local/keepalived/ [root@localhost keepalived]# ll 总用量 1164 drwxr-xr-x 2 root root 21 1月 28 09:34 bin drwxr-xr-x 4 root root 41 1月 28 09:34 etc drwxrwxr-x 11 1000 1000 4096 1月 28 09:34 keepalived-2.2.7 -rw-r--r-- 1 root root 1180180 1月 28 09:25 keepalived-2.2.7.tar.gz -rw-r--r-- 1 root root 1193 1月 28 09:15 keepalived.conf drwxr-xr-x 2 root root 24 1月 28 09:34 sbin drwxr-xr-x 5 root root 40 1月 28 09:34 share [root@localhost keepalived]# cp /usr/local/keepalived/sbin/keepalived /usr/sbin/keepalived
2.keepalived启动脚本依赖一些变量,将变量引用文件拷贝到系统目录
[root@localhost keepalived]# cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/keepalived [root@localhost keepalived]# ll /etc/sysconfig/keepalived -rw-r--r-- 1 root root 667 1月 28 09:59 /etc/sysconfig/keepalived
四、配置文件
配置文件需要存放在 /etc/keepalived 目录,该目录需要人工创建
[root@localhost keepalived]# mkdir -p /etc/keepalived [root@localhost keepalived]# cp /usr/local/keepalived/etc/keepalived/keepalived.conf.sample /etc/keepalived/keepalived.conf [root@localhost keepalived]# ll /etc/keepalived/ 总用量 4 -rw-r--r-- 1 root root 3550 1月 28 10:02 keepalived.conf
一个功能比较完整的常用的 keepalived 配置文件,主要包含以下三块
! Configuration File for keepalived #全局定义块 global_defs { ... } #VRRP 实例定义块 vrrp_instance VI_1 { ... } #虚拟服务器定义块 virtual_server 10.10.10.2 1358 { ... }
特别关注:配置文件中指定的所有路径,请在启动前确保已存在
特别关注:全局定义块是必须配置项;如果Keepalived只用来做HA,则虚拟服务器是可选配置。
下面详细介绍Keepalived配置文件:
1.全局定义块
这部分主要用来设置Keepalived的故障通知机制和Router ID标识。示例代码如下:
参数说明:
1)第一行是注释
2)第4~8行:email通知,用于服务有故障时发送邮件报警。可选项,不建议用。需系统开启sendmail服务,建议用第三方独立监控服务,如使用nagios监控代替。
3)第9行:指定发件人,可选配置。
4)第10行:指定发送邮件的smtp服务器地址,可选配置。
5)第11行:指定连接smtp的超时时间,可选配置。
6)第12行:用户标识本节点的名称,通常为 hostname
2.VRRP 实例定义块
虚拟路由配置,用于高可用
参数说明:
1)第15行:定义一个vrrp_install实例,名称为VI_1
2)第16行:表示该实例的角色状态,有MASTER和BACKUP两种主备状态。
3)第17行:对外提供服务的网络接口,如eth0,ens33
4)第18行:虚拟路由ID标识,主备服务器配置中相同实例的ID必须一致,否则将出现脑裂问题。
5)第19行:priority表示实例优先级。数字越大,优先级越高,以此实现VIP漂移。
6)第20行:advert_int为同步通知间隔。主备之间通信检查的时间间隔,默认为1秒。
7)第21~24行:权限认证配置。
8)第25~29行:虚拟IP地址,即VIP;可以配置多个IP,每个IP占一行。注意,这里的IP就是在工作中需要和域名绑定的ip,即可配置的高可用服务监听的ip保持一致。
特别关注:关于state 与 priority
keepalived实际运行中,最终会根据 priority 确认 master 角色,而非配置的 state,所以实际使用中可以采用如下方案
- 配置为 master 的角色将 priority 配置较大,启动后竞争为master
- 将所有keepalived配置为 backup,根据 priority 控制角色
特别关注:关于服务器故障恢复后VIP漂移
配置为 backup 角色的实例,keepalived服务重启后,默认会重新发起竞选,即抢占模式,如果此时 priority 较高,则VIP会重新漂移回该服务器,虽然VIP漂移间隔很小,但也会造成不必要的问题以及资源浪费,所以建议在 vrrp_instance 配置中加入 nopreempt,即开启非抢占模式
3.虚拟服务器定义块
虚拟服务器列表配置,用于负载均衡,如果使用 nginx、haproxy等负载均衡方案,可以不配置此模块
参数说明:
1)virtual_server:定义一个虚拟服务器,这个ip是virtual_address中定义的其中一个。语法格式:ip+空格+服务端口
- 第58行:delay_loop 6
健康检查时间间隔,单位:秒
- 第59行:lb_algo rr
负载均衡调度算法,互联网应用常用方式为 wlc或rr
- 第60行:lb_kind NAT
负载均衡转发规则。包括DR、NAT、TUN 3种,一般使用路由(DR)转发规则。
- 第61行:persistence_timeout 50
http服务会话保持时间,单位:秒
- 第62行:protocol TCP
转发协议,分为TCP和UDP两种
2)real_server:真实服务器IP和端口,可以定义多个
- 第67行:weight 1
负载权重,值越大,转发的优先级越高
- 第68行:HTTP_GET
keepalived后对端server的健康检查,下文详细介绍
- 第81行:connect_timeout 3
服务连接超时时长,单位:秒
- 第82行:nb_get_retry 3
服务连接失败重试次数
- 第83行:delay_before_retry 3 :重试连接间隔,单位:秒
特别关注:关于keepalived健康检查
keepalived对后端realserver的健康检查方式主要有以下几种
- TCP_CHECK:工作在第4层,keepalived向后端服务器发起一个tcp连接请求,如果后端服务器没有响应或超时,那么这个后端将从服务器池中移除。
- HTTP_GET:工作在第5层,向指定的URL执行http请求,将得到的结果用md5加密并与指定的digest值比较看是否匹配,不匹配则从服务器池中移除;此外还可以指定http返回码来判断检测是否成功。HTTP_GET可以指定多个URL用于检测,这个一台服务器有多个虚拟主机的情况下比较好用。
- SSL_GET:跟上面的HTTP_GET相似,不同的只是用SSL连接
- MISC_CHECK:用脚本来检测,脚本如果带有参数,需将脚本和参数放入双引号内。脚本的返回值需为:
0) 检测成功
1) 检测失败,将从服务器池中移除
2-255)检测成功;如果有设置misc_dynamic,权重自动调整为 退出码-2,如退出码为200,权重自动调整为198=200-2。
- SMTP_CHECK:用来检测邮件服务的smtp的
4.配置信息补充
关于业务系统健康检查,如果使用了nginx、haproxy等负载均衡方案,将不再配置virtual_server、real_server模块,无法使用其提供的健康检查接口,所以需要配置专用的业务系统健康检查脚本,此时配置文件结构如下
! Configuration File for keepalived #全局定义块 global_defs { ... } #定义业务检查脚本块 vrrp_script scriptname{ #脚本路径,脚本执行是否成功,根据脚本的退出码确认,默认为0,即exit 0 script "" #脚本检测周期 interval 2 ##权重策略是:根据脚本执行结果计算权重,然后触发keepalived重新选举 #当weight > 0时:脚本执行成功了 Priority + Weight,执行失败 Priority #当weight < 0时:脚本执行成功了 Priority 执行失败 Priority + Weight weight 10 } #VRRP 实例定义块 vrrp_instance VI_1 { ... #检查脚本,与vrrp_script对应 track_script{ scriptname } } #虚拟服务器定义块 virtual_server 10.10.10.2 1358 { ... }
其中,业务健康检查的设计方案可以参考如下
- 为健康检查脚本设置相应的权重(可以是正数、负数),结合虚拟路由本来的权重决定keepalived切换策略
- 健康检查脚本不设置权重,在脚本中根据业务场景直接实现keepalived切换,如重启keepalived服务
五、运行用户
默认使用root运行即可。
六、开机启动
请参考教程 Linux开机启动方案
七、服务启动运行
通过service命令或systemctl命令启动服务
systemctl start keepalived
service keepalived start #service命令会自动重定向为以上systemctl命令执行
通过 ip a 命令查看虚拟IP绑定在哪台服务器(以VIP 192.168.11.200为例,keepalived运行在192.168.11.13)
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: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 08:00:27:46:65:8b brd ff:ff:ff:ff:ff:ff inet 192.168.11.13/24 brd 192.168.11.255 scope global noprefixroute enp0s3 valid_lft forever preferred_lft forever inet 192.168.11.200/24 scope global secondary enp0s3 valid_lft forever preferred_lft forever inet6 fe80::c08b:489f:1587:3bb6/64 scope link tentative noprefixroute dadfailed valid_lft forever preferred_lft forever inet6 fe80::a33a:d49b:da44:119a/64 scope link tentative noprefixroute dadfailed valid_lft forever preferred_lft forever inet6 fe80::d071:eb89:2f12:8e56/64 scope link noprefixroute valid_lft forever preferred_lft forever [root@localhost ~]#
特别关注:系统默认启用了SELinux内核模块(安全子系统),影响keepalived自动检测切换功能。
此时需要禁用SELinux,修改 /etc/selinux/config 文件,设置SELINUX=disabled,然后重启linux系统。