一、介绍:用nginx做负载均衡,作为架构的最前端或中间层,随着日益增长的访问量,需要给负载均衡做高可用架构,利用keepalived解决单点风险,一旦 nginx宕机能快速切换到备份服务器,可以理解为nginx的多节点实现。目前主流实现web网站及数据库服务高可用软件包括:keepalived、heartbeat、corosync,cman;高可用简称HA;
1、keepalived主要功能:对RealServer进行健康状态检查,支持3层、4层、7层协议进行健康检查;并支持VRRP冗余协议,所以keepalived两个功能是监控检查,VRRP冗余协议;
2、keepalived的作用:检查web服务器的状态,如果有一台web服务器/mysql服务器宕机或故障,keepalived将故障节点从系统中剔除,当故障恢复的时候自动加入服务器集群中,非常智能化,只需要手动修复坏的节点即可。
3、keepalived的layer3、4、7层分别是IP层、传输层、应用层的实现原理如下:
1)、layer3:keepalived定期向集群中服务器发送ICMP的包,如果发现哪台ping不通,便报告这台服务器失效,并将其剔除集群;(判断标准为IP是否有效)
2)、layer4:主要以TCP端口(也可以是udp)状态来决定服务器工作是否正常,如web服务器的80端口如果没有工作,则将其剔除集群(判断标准为端口)
3)、layer7:应用层,keepalived将根据用户的设定,检查服务器程序的运行是否正常,如果不是设定值,则将其剔除集群(判断标准为程序是否正常)
4、keepalived原理:
1)VRRP(虚拟路由冗余协议)最早是为了解决网关的点单故障的路由协议,在主机上如何选定到达目的的下一跳路由,这个问题通常解决方案是,动态路由协议RIP,OSPF;再有就是静态路由协议,主机中实现动态路由协议非常不实际,管理,开销,维护等诸多问题,因此通常是配置静态路由协议,但是路由器或网管就经常出现单点,VRRP就是解决此静态路由单点问题,VRRP通过竞选协议来动态交给LAN中的虚拟路由器中的某台VRRP路由器。
2)VRRP虚拟路由器集群中,由多台物理机组成,但是并不是同时工作,而是由master负载路由工作,其他都是backup,master也不是一成不变,VRRP会让每个VRRP路由参与竞选最终优先的就是master,master的特权是拥有虚拟路由器的IP地址,即VIP,负责转发给网关地址的包和响应ARP请求。
3)VRRP通过竞选来实现虚拟路由器的功能,所有协议报文都是通过IP多播包(多播地址224.0.0.18)发送的,虚拟路由器有VRID(0~255)和一组IP地址组成,对外表现为一个mac地址,所以一组虚拟路由器集群中,不管谁是master,对外都是一个相同mac和VIP,客户端没有感知,master的VRRP路由器会一直发送VRRP广播包,backup不会抢占master,除非优先级(priority)更高,当master不可用时(backup收不到广播包),多台backup中优先级最高的这台会抢占master,抢占是非常快速的,并且VRRP包还使用了加密协议进行传输;keepalived基于VRRP将两台主机当做路由器,组成虚拟路由器集群,master高的主机产生VIP,该VIP负责转发用户发起的IP包或请求。
5、keepalive架构模型:一个父进程两个子进程
为了确保健壮及稳定性,守护进程被分为3个不同的进程,父进程负责fork和监控子进程,因此父进程也称为watchdog,凉饿子进程,一个负责VRRP,另一个负责健康检查,每个进程都有自己的I/O多路复用器,这样可以优化VRRP调度抖动,因为VRRP比健康检查更重要,两个子进程开启本地套接字Unix Domain Socket,当keepalive启动后,父进程通过unix domain socket每隔5s发送一个hello消息给子进程,如果父进程无法发送消息给子进程,将认为子进程出现问题,于是重启子进程。watchdog这种设计的两个好处是,第一父进程发送给远程子进程的hello数据包是通过I/O多路复用程序完成的,这样他就可以在子调度框架中检测死循环,第二是使用sysV信号检测dead children。
解释:(1)0userspace 用户空间;kernelspace 内核空间
(2)checker组件:负责RS健康状态检查,并在LVS拓扑中移除、添加,支持layer3/4/7的协议检查,该组件使用独立的子进程负责,但被父进程监控。这个组件就是实现健康检查(TCP\HTTP\SSL\MISC......)
(3)VRRP stack:提供director的故障转移功能从而实现director的高可用,该组件可独立提供功能,无需LVS支持,也是独立的子进程负责,父进程监控,vrrp stact就是vrrp的实现,比如vrrp协议调用。
(4)system call组件:提供抓取自定义脚本的功能,该组件在使用时,将临时产生一个子进程来执行任务,支持系统调用机制,做出管理操作。
(5)IPVS wrapper组件:负责将配置文件中IPVS相关规则发送到内核的IPVS模块,就是生产ipvs规则的。
(6)netlink reflector:用来设定,监控vrrp的vip地址,负责交互,VRRP借助于netlink健康网络,实现网络功能配置。
(7)schedule-I/O Multiplexer:并发控制。
(8)memory mngt:内存管理。
(9)control plane configuration file parser:配置文件,分析的主控工具。
(10)watch dog:可以理解为高可用监视器。
6、实例:如现有服务my-service-demo,希望实现高可用和负载均衡:
首先,my-service-demo服务部署在两台机器上,通过nginx去代理这两个节点,负载均衡就实现了。如果只有一个nginx,这台nginx机器一旦宕机,访问nginx会报错。这时候在另外一台机器nginx2上也安装nginx,并配置同样的代理,可以解决上述问题,但是暴露给用户的只有一个域名(或ip),不可能给用户提供两个域名,域名1(nginx机器1)访问不了了再让用户访问域名2(nginx机器2),这时候就可以使用keepalived将nginx机器1和nginx机器2封装成一个Vritrual IP(虚拟ip),vip的主机宕机了可以自动切到备用机器上,把这个虚拟ip暴露给用户实现高可用。
案例1:前后端分离项目,后端地址在nginx中做负载均衡代理,前端访问upstream代理的域名,再由一个虚拟ip代理前端页面实现高可用,部署图:
案例2:再如mysql配置主从数据库,主库可写,从库只读。项目里面需要配置主库的地址,如果主库挂了,从库切为主库,则需要改代码配置,并且需要重启项目比较麻烦。这时候可以把主从库绑定成一个vip提供给项目连接。如果主从库切换,只需要改动keepalived的配置,不需要改代码。
二、Keepalived下载与安装(linux环境):
方法一:yum方式
1、yum安装:
安装依赖包
[root@localhost ~]# yum install -y curl gcc openssl-devel libnl3-devel net-snmp-devel
[root@localhost ~]# yum install -y keepalived
2、初始化及启动:
[root@localhost ~]# systemctl start keepalived //启动keepalived
[root@localhost ~]# systemctl enable keepalived //加入开机启动keepalived
[root@localhost ~]# systemctl restart keepalived //重新启动keepalived
[root@localhost ~]# systemctl status keepalived //查看keepalived状态
方法二:源码包
1、官网下载keepalived的最新版本,解压并安装:
[root@master src]# pwd
/usr/local/src
[root@master src]# wget http://www.keepalived.org/software/keepalived-2.0.7.tar.gz
[root@master src]# tar xvf keepalived-2.0.7.tar.gz
[root@master src]# cd keepalived-2.0.7
[root@master keepalived-2.0.7]# ./configure --prefix=/usr/local/keepalived
[root@master keepalived-2.0.7]# make && make install
完成后会在以下路径生成:
/usr/local/keepalived/etc/keepalived/keepalived.conf
/usr/local/keepalived/etc/sysconfig/keepalived
/usr/local/keepalived/sbin/keepalived
2、初始化及启动:依次执行以下命令
# keepalived启动脚本变量引用文件,默认文件路径是/etc/sysconfig/,也可以不做软链接,直接修改启动脚本中文件路径即可(安装目录下)
[root@localhost /]# cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/keepalived
# 将keepalived主程序加入到环境变量(安装目录下)
[root@localhost /]# cp /usr/local/keepalived/sbin/keepalived /usr/sbin/keepalived
# keepalived启动脚本(源码目录下),放到/etc/init.d/目录下就可以使用service命令便捷调用
[root@localhost /]# cp /usr/local/src/keepalived-2.0.7/keepalived/etc/init.d/keepalived /etc/init.d/keepalived
# 将配置文件放到默认路径下
[root@localhost /]# mkdir /etc/keepalived
[root@localhost /]# cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf
最后执行启动、关闭、重启命令:service keepalived start|stop|restart
三、Keepalived配置文件:安装后默认配置文件:
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
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 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.200.16
192.168.200.17
192.168.200.18
}
}
virtual_server 192.168.200.100 443 {
delay_loop 6
lb_algo rr
lb_kind NAT
persistence_timeout 50
protocol TCP
real_server 192.168.201.100 443 {
weight 1
SSL_GET {
url {
path /
digest ff20ad2481f97b1754ef3e12ecd3a9cc
}
url {
path /mrtg/
digest 9b3a0c85a887a256d6939da88aabd8cd
}
connect_timeout 3
retry 3
delay_before_retry 3
}
}
}
virtual_server 10.10.10.2 1358 {
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.200.2 1358 {
weight 1
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl3/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
connect_timeout 3
retry 3
delay_before_retry 3
}
}
real_server 192.168.200.3 1358 {
weight 1
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334c
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334c
}
connect_timeout 3
retry 3
delay_before_retry 3
}
}
}
virtual_server 10.10.10.3 1358 {
delay_loop 3
lb_algo rr
lb_kind NAT
persistence_timeout 50
protocol TCP
real_server 192.168.200.4 1358 {
weight 1
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl3/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
connect_timeout 3
retry 3
delay_before_retry 3
}
}
real_server 192.168.200.5 1358 {
weight 1
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl3/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
connect_timeout 3
retry 3
delay_before_retry 3
}
}
}