技术分享
nginx+keepalived实现双机主备容灾
2018-12-21
现在很多多个服务器容灾的解决方案是用的nginx+keepalived,nginx用来反向代理以及负载均衡,keepalived用来监测nginx服务状态,一旦有nginx服务宕机,另一台服务器会自动接管请求,达到服务的高可用目的。
keepalived简单介绍:
keepalived基于VRRP协议(Virtual Router Redundancy Protocol)(虚拟路由冗余协议),VRRP协议的出现就是为了解决单点故障。
keepalived由三个模块组成,vrrp、core和check,其中vrrp用来实现VRRP协议,core是核心模块,负责加载配置文件、启动进程等操作,check负责健康检查,监测是否有宕机行为发生。
keepalived基本工作原理:keepalived为主备部署,一个master多个backup,当keepalived工作时,会不断向backup发送消息,告诉备份机自己还活着,一旦master挂掉了,backup就收不到心跳消息,此时backup会认为master已经挂了,会按优先级高的选举成为新的master,承担报文的转发功能。
接下来开始搞事!
1、安装nginx
首先去官网下载安装包:http://nginx.org/en/download.html
我是直接在链接处右键->保存链接地址之后,用wget下载的。
[root@lgs2 keepalived-2.0.20]# wget http://nginx.org/download/nginx-1.16.1.tar.gz
可以看到安装包已经下载到目录下了:
2. 解压安装包
[root@lgs2 nginx]# tar -zxvf nginx-1.16.1
进入到解压目录,执行configure文件
nginx安装需要依赖其他包,直接执行configure文件会报错,先安装依赖包
#安装依赖包[root@lgs2 nginx-1.16.1]# yum -y install gcc pcre-devel zlib-devel openssl openssl-devel#执行nginx配置[root@lgs2 nginx-1.16.1]# ./configure --prefix=/usr/software.nginx
–prefix参数指定nginx安装目录,不加的话就是默认路径:/usr/local/nginx
再make && make install
[root@lgs2 nginx-1.16.1]# make[root@lgs2 nginx-1.16.1]# make install
此时在nginx安装目录下可以看到生成了一些文件:
…我这是启动之后的,多了一些_temp文件,刚安装好的没有这些_temp结尾的文件夹。
4. 启动nginx
进入到安装目录的/sbin下,执行./nginx启动
./nginx #启动
./nginx -s stop #停止
[root@lgs2 nginx-1.16.1]# ./nginx
检查启动成功
nginx默认开启的是80端口,直接在服务器上执行curl命令检查:
[root@lgs sbin]# curl localhost
出现以下则启动成功:
也可以在浏览器输入ip检查是否启动成功,但是这就要服务器开启80端口防火墙:
#检查80端口防火墙是否开启[root@lgs sbin]# firewall-cmd --query-port=80/tcp
出现no则没开启,以下命令开启防火墙并刷新防火墙状态
[root@lgs sbin]# firewall-cmd --zone=public --add-port=80/tcp --permanent[root@lgs sbin]# firewall-cmd --reload
在浏览器输入ip,出现以下界面则启动成功:
2、安装keepalived
keepalived和nginx安装步骤差不多,首先进入官网下载:https://www.keepalived.org/download.html
自己选择合适的版本,我是选择当前最新的2.0.20
然后和nginx一样:
下载
解压
tar -zxvf keepalived-2.0.20.tar.gz
安装依赖
keepalived需要IPVS支持,否则执行configure会有相关警告,运行以下命令安装:
yum install -y libnl libnl-devel yum install -y libnfnetlink-devel
再执行configure文件,同样可以带参数,–prefix指定安装目录
configure --prefix=/usr/software/keepalived
再make && make install
make && make install
将以下文件进行复制(注意2.0.20版本有写是安装目录没有的文件,要在源码包里找)
[guansheng@lgs keepalived-2.0.20]$ cp /usr/software/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf[guansheng@lgs keepalived-2.0.20]$ ln -s /usr/software/keepalived/sbin/keepalived /usr/sbin/#以下文件在源码包,也就是下载解压后的目录cd /home/guans/documents/keepalived #我的安装包下载位置[guansheng@lgs keepalived-2.0.20]$ cp keepalived/keepalived.service /etc/systemd/system[guansheng@lgs keepalived-2.0.20]$ sudo cp keepalived/etc/init.d/keepalived /etc/init.d/
3、配置服务
3.1、架构
配置服务之前,先说一下准备配置的架构。
首先我这里有三台虚拟机,192.168.252.128,192.168.252.129,192.168.252.130,前面两台配置稍微高一些,我准备将128这台当做nginx主机,129这台当做nginx备份机,130单纯只部署项目服务,128、129各部署一个相同的项目服务,具体架构图如下:
这图实在有点丑,像我这种提起笔来,连个小鸡啄米图都画不出来的人,也就这么个画图水平了,还是稍微解释一下吧。
nginx的主备通过配置keepalived实现,128为主机,129为备份机,前端请求通过虚拟ip进来,keepalived判断主机是哪个,然后主机上的nginx负责反向代理和负载均衡,以默认轮询的方式请求128,129,130三台服务器上部署的springboot服务,springboot服务简单输出hello+ip来判断此刻是请求的哪台服务器。
3.2、配置nginx
在nginx安装目录/conf/nginx.conf文件中配置,如何配置可以参考这篇文章,很详细:Nginx的配置文件详解(超详细)
我的配置如下:
128主机:
#user nobody;user root; #指定Nginx Worker进程运行用户以及用户组,默认由nobody账号运行worker_processes 2; #指定了Nginx要开启的进程数。每个Nginx进程平均耗费10M~12M内存。建议指定和CPU的数量一致即可#error_log logs/error.log; #用来定义全局错误日志文件。日志输出级别有debug、info、notice、warn、error、crit可供选择,其中,debug输出日志最为最详细,而crit输出日志最少#error_log logs/error.log notice;#error_log logs/error.log info;#pid logs/nginx.pid; #用来指定进程pid的存储文件位置#worker_rlimit_nofile=65535; #worker_rlimit_nofile用于绑定worker进程和CPU, Linux内核2.4以上可用#events事件指令是设定Nginx的工作模式及连接数上限events { worker_connections 1024;}http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; #gzip on; #负载均衡配置 upstream cycle.com{ #Weight:指定轮询权值,Weight值越大,分配到的访问机率越高 #方式:默认轮询,ip_hash:每个请求按访问IP的hash结果分配 #fair:比上面两个更加智能的负载均衡算法 #ip_hash; #方式:默认轮询 server 192.168.252.128:8081; server 192.168.252.129:8081; server 192.168.252.130:8081; } server { listen 80; server_name 192.168.252.128; #charset koi8-r; #access_log logs/host.access.log main; location / { proxy_pass http://cycle.com; #适用前面配置的负载均衡策略 } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root html; }}
129备份机:
user root;worker_processes 2;#error_log logs/error.log;#error_log logs/error.log notice;#error_log logs/error.log info;#pid logs/nginx.pid;events { worker_connections 1024;}http { include mime.types; default_type application/octet-stream; #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; #负载均衡配置 upstream cycle.com{ server 192.168.252.128:8081; server 192.168.252.129:8081; server 192.168.252.130:8081; } server { listen 80; server_name 192.168.252.129; #charset koi8-r; #access_log logs/host.access.log main; location / { proxy_pass http://cycle.com; }}
下面可以测试一下nginx负载均衡是否生效,启动三台机器身上的springboot项目,连接128的nginx来访问项目,分别点击三次,看是否是轮询来访问三台服务器:
可以看到确实已经负载均衡生效了,129服务器的nginx也测试过,一样的效果,到此nginx配置完毕,接下来配置keepalived。
3.3、配置keepalived
配置文件本身的位置是在安装目录下的etc/keepalived/keepalived.conf,但是按安装完成的时候已经移动到/etc/keepalived/keepalived.conf了,所以修改/etc/keepalived/keepalived.conf就可以了。
先查看一下ip对应的网卡,绑定虚拟ip的时候需要:
ifconfig
128主机配置:
! 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_128 # 路由id,在一个局域网内要唯一 vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0}#健康检测脚本,必须声明在vrrp_instance节点前vrrp_script chk_nginx { script "/etc/keepalived/nginx_check.sh" ## 检测 nginx 状态的脚本路径 interval 3 # 检测时间间隔,应该要大于脚本中的sleep时间 weight -20 # 如果条件成立,权重-20}#vrrp实例设置vrrp_instance VI_1 { state MASTER #MASTER为主机 interface ens33 #虚拟ip绑定的网卡 virtual_router_id 51 #虚拟路由ID标识,一组的keepalived配置中主备都是设置一致 priority 100 #优先级,主机应高于备份机即可 advert_int 1 authentication { auth_type PASS #认证方式 auth_pass 123456 #认证密码 } virtual_ipaddress { 192.168.252.131 #虚拟ip } track_script { chk_nginx ## 执行 Nginx 监控的服务 }}
检测脚本代码:
这段脚本的意思是:检测到nginx已停止,就启动nginx服务,如果没启动起来,就把keepalived停止。
记得#! /bin/bash这句开头必须定义,不然会出现:Error exec-ing command ‘/etc/keepalived/nginx_check.sh’, error 8: Exec format error的错误
#! /bin/bashcount=$(ps -C nginx --no-heading | wc -l)if [ "$count" = "0" ]; then #/usr/software/nginx/sbin/nginx #这里是启动nginx,为了方便后面的测试,先不写启动的功能,测试完了再解除注释 sleep 2 count=$(ps -C nginx --no-heading | wc -l) if [ "${count}" = "0" ]; then pkill keepalived fifi
脚本写完之后,要保证其为可执行文件,如果不是,那就加权限:
#修改脚本文件为可执行[root@lgs2 keepalived]# chmod +x nginx_check.sh
启动keepalived服务:service keepalived start(前面那几次copy已经将keepalived注册成系统服务了)
service keepalived start
可以查看日志文件,日志文件路径:/var/log/messages
查看虚拟Ip是否已经绑定:
ip addr
可以看到虚拟ip已经绑定到对应网卡上了:
接下来配置备份机的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_129 vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0}vrrp_script chk_nginx { script "/etc/keepalived/nginx_check.sh" ## 检测 nginx 状态的脚本路径 interval 3 ## 检测时间间隔 weight -20 ## 如果条件成立,权重-20}vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 90 advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 192.168.252.131 } track_script { chk_nginx ## 执行 Nginx 监控的服务 }}
备份机的健康检查脚本和主机一致
启动备份机的keepalived,不会生成虚拟ip,生成了那就是有问题,我确实出现了主备双机争抢vip(虚拟ip)的问题(脑裂现象),解决问题花了很久,我单独整理出来一篇文章:keepalived出现主备机同时绑定vip的解决方法
记录一下keepalived服务的启动和停止命令:
启动:service keepalived start 或 systemctl start keepalived.service
重启:service keepalived restart 或 systemctl restart keepalived.service
停止:service keepalived stop 或 systemctl stop keepalived.service
查看状态:systemctl status keepalived.service
4、测试
将主机和备份机的keepalived和nginx都启动,三台服务器的项目都跑起来
1、先看一下主备机vip的绑定情况:
[guansheng@lgs keepalived]$ ip addr
2、通过虚拟ip访问项目:
可以访问,没有问题
3、停止主机的nginx,再通过虚拟ip访问(因为脚本已经暂时注释了重启nginx服务,所以停止nginx就模拟了nginx服务无法重启的情况)
[guansheng@lgs keepalived]$ /usr/software/nginx/sbin/nginx -s stop
再查看主机的vip绑定情况:
备份机vip绑定情况:
可以看到虚拟ip已经漂移到备份机了,此时备份机承担请求的转发任务。
再看主机的keepalived状态:
主机keepalived状态为死亡状态,由此可以看到:nginx结束了进程,主机健康检查检测到nginx已停止,所以关闭了keepalived,此时keepalived主机无法发送组播消息,备份机在规定时间未收到主机的组播消息,认为主机已挂,此时备份机接管主机的业务,虚拟ip漂移至备份机,以此保证服务的高可用。
4、 再次启动主机的keepalived和Nginx服务,模拟主机故障修复:
可以看到vip再次漂移到了主机上
备份机此时vip已解除绑定:
此时再访问项目,依然能访问:
由此可见,在整个过程中,主机与备份机的切换,都是keepalived自动进行的,而人工在这里仅仅只是修复了主机的故障而已,而且整个过程中,服务并没有停止。
到此,一个keepalived+nginx高可用部署方案就已经完成,其实keepalived+nginx还有其他的主备部署方案,那些方案更加节省服务器资源,只是作为初次接触者,我先试了最简单的一种而已!

- 标签:
-
技术分享