nginx:负载均衡实战nginx=keepalived
Posted WU大雄
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nginx:负载均衡实战nginx=keepalived相关的知识,希望对你有一定的参考价值。
1.keepalived介绍
顾名思义,keepalived就是保持网络在线的,用来保证集群高可用HA的服务软件。主要防止出现单点故障(坏了一个点导致整个系统架构不可用)
2.详解keepalived
2-1 VRRP协议
VRRP全称Virtual Router Redundancy Protocol,即虚拟路由冗余协议。
网络设计的时候,冗余以及容灾是必须的,防止网络单点故障,路由器或三层交换机处的冗余很重要。vrrp总的来说有如下几点。
1)VRRP是用来实现路由器冗余的协议。
2)VRRP协议是为了消除在静态缺省路由环境下路由器单点故障引起的网络失效而设计的主备模式的协议,使得发生故障而进行设计设备功能切换时可以不影响内外数据通信,不需要再修改内部网络的网络参数。
3)VRRP协议需要具有IP备份,优先路由选择,减少不必要的路由器通信等功能。
4)VRRP协议将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器IP(一个或多个)。然而,在路由器组内部,如果实际拥有这个对外IP的路由器如果工作正常的话,就是master,或者是通过算法选举产生的,MASTER实现针对虚拟路由器IP的各种网络功能,如ARP请求,ICMP,以及数据的转发等,其他设备不具有该IP,状态是BACKUP。除了接收MASTER的VRRP状态通告信息外,不执行对外的网络功能,当主级失效时,BACKUP将接管原先MASTER的网络功能。
5)VRRP协议配置时,需要配置每个路由器的虚拟路由ID(VRID)和优先权值,使用VRID将路由器进行分组,具有相同VRID值的路由器为同一个组,VRID是一个0-255的整整数,;同一个组中的路由器通过使用优先权值来选举MASTER。,优先权大者为MASTER,优先权也是一个0-255的正整数。
2-2 keepalived的原理
keepalived有两大功能:(1)提供vrrp (2)心跳检查
keepalived以vrrp为基础。把有相同功能的路由器搞成一个组别,里面有多个matser和backup,master上面有一个浮动的虚拟ip(VIP,也就是vitrue ip),master会发组播,backup收不到的时候就认为(不一定真的挂了!)master挂掉了,这时候根据vrrp,咱有优先级,选举一个当master,这样保证路由器高可用。
2-3 keepalived的组成
keepalived包括以下模块。
core模块:为keepalived的核心组件,负责主进程的启动、维护以及全局配置文件的加载和解析;
check:负责健康检查,包括常见的各种检查方式;
VRRP模块:是来实现VRRP协议的。
system call:系统调用
watch dog:监控check和vrrp进程的看管者,check负责检测器子进程的健康状态,当其检测到master上的服务不可用时则通告vrrp将其转移至backup服务器上。
除此之外,keepalived还有下面两个组件:
libipfwc:iptables(ipchains)库,配置LVS会用到
libipvs*:配置LVS
2-4 keepalived的进程
如上图,keepaalived启动后有3个进程:
父进程:监控子进程用;
子进程有两个,一个负责vrrp,一个负责check检查(如果healthchecks进程检查到master上服务不可用了,就会通知本机上的VRRP子进程,让他删除通告,并且去掉虚拟IP,转换为BACKUP状态。)
3.keepalived的配置文件
3-1 详解
主要包括三部分: 花括号“{}”。用来分隔定义块,因此必须成对出现。如果写漏了,keepalived运行时,不会得到预期的结果。由于定义块内存在嵌套关系,因此很容易遗漏结尾处的花括号,这点要特别注意。 - 全局定义块 global_defs { notification_email { #指定keepalived在发生切换时需要发送email到的对象,一行一个,建议不用,用其他监控方案代替 liutiansi@gmail.com } notification_email_from Alexandre.Cassen@firewall.loc #指定发件人 smtp_server 127.0.0.1 #指定smtp服务器地址 smtp_connect_timeout 3 #指定smtp连接超时时间 router_id LVS_DEVEL #运行keepalived机器的一个标识,在一个网络内,它应该是唯一的 } #监控haproxy 进程 vrrp_script chk_haproxy { # Requires keepalived-1.1.13 script "killall -0 haproxy" # widely used idiom interval 2 # check every 2 seconds weight 2 # add 2 points of prio if OK weight -2 #经测试keepalived 1.17版本加这个配置不能切换,最新版本1.21加上这个则可以 } - VRRP实例定义块 vrrp_sync_group VG_1{ #监控多个网段的实例group,每个实例group必须包含一个vrrp实例 group { inside_network #实例名,确定失败切换(FailOver)包含的路由实例个数。即在有2个负载均衡器的场景, #一旦某个负载均衡器失效,需要自动 切换到另外一个负载均衡器的实例是哪些 outside_network } notify_master /path/xx.sh #指定当切换到master时,执行的脚本 netify_backup /path/xx.sh #指定当切换到backup时,执行的脚本 notify_fault "path/xx.sh VG_1" #故障时执行的脚本 notify /path/xx.sh smtp_alert #使用global_defs中提供的邮件地址和smtp服务器发送邮件通知 } #Vrrp实例vrrp_instance.实例名出自实例组group所包含的那些名字 vrrp_instance inside_network { state BACKUP #实例状态state.只有MASTER和BACKUP两种状态,并且需要大写这些单词。其中MASTER为工作状态,BACKUP为备用状态。 #当MASTER所在的服务器失效时,BACKUP所在的系统会自动把它的状态有BACKUP变换成MASTER; #当失效的MASTER所在的系统恢复时,BACKUP从MASTER恢复到BACKUP状态。 #主备的靠priority决定 #nopreempt #设置为不抢占 注:这个配置只能设置在backup主机上,而且这个主机优先级要比另外一台高 interface eth0 #设置实例绑定的网卡,即vip所在的网卡,因为在配置虚拟IP的时候必须是在已有的网卡上添加的 dont_track_primary #忽略vrrp的interface错误(默认不设置) track_interface{ #设置额外的监控,里面那个网卡出现问题都会切换,一般都会对内外网卡同时进行监控 eth0 eth1 } mcast_src_ip #发送多播包的地址,如果不设置默认使用绑定网卡的primary ip garp_master_delay #在切换到master状态后,延迟进行gratuitous ARP请求 virtual_router_id 50 #虚拟路由标识 ,可通过 #tcpdump vrrp 查看.这个标识是一个数字,并且同一个vrrp实例使用唯一的标识。 #即同一个vrrp_instance,MASTER和BACKUP的virtual_router_id是一致的,同时在整个vrrp内是唯一的。 priority 99 #优先级:这是一个数字,数值愈大,优先级越高。在同一个vrrp_instance里,MASTER的优先级高于BACKUP advert_int 1 #同步通知间隔:MASTER与BACKUP负载均衡器之间同步检查的时间间隔,单位为秒。 preempt_delay #抢占延时,默认5分钟,通过这种方式防止意外的切换导致角色的切换 debug #开启debug,默认可以不开启 authentication { #设置认证 auth_type PASS #类型主要有PASS、AH两种,通常使用的类型为PASS auth_pass 111111 #验证密码为明文,同一vrrp实例MASTER与BACKUP 使用相同的密码才能正常通信。 } virtual_ipaddress { #虚拟IP,即VIP,可以有多个地址,每个地址占一行,不需要指定子网掩码 #注意:如果lvs+keepalived场景中,这个ip必须与我们在lvs客户端设定的vip相一致 192.168.202.200 } virtual_routes { #设置默认路由 # src <IPADDR> [to] <IPADDR>/<MASK> via|gw <IPADDR> dev <STRING> scope <SCOPE> tab src 192.168.100.1 to 192.168.109.0/24 via 192.168.200.254 dev eth1 192.168.110.0/24 via 192.168.200.254 dev eth1 192.168.111.0/24 dev eth2 192.168.112.0/24 via 192.168.100.254 } preempt delay #抢占延迟 } - 虚拟服务器定义块 virtual_server 192.168.202.200 23 { # 这个ip后面一个空格,然后加上端口号。定义一个vip,可以实现多个tcp端口的负载均衡功能 delay_loop 6 #健康检查时间间隔,单位是秒 lb_algo rr #负载均衡调度算法(rr|wrr|lc|wlc|lblc|sh|dh),比较常见的是rr和nlc lb_kind DR #负载均衡转发规则(NAT|DR|TUN) persistence_timeout 50 #会话保持时间,单位是s,此选项用来提供保持会话功能 protocol TCP #使用的协议,TCP和UDP persistence_granularity <NETMASK> #lvs会话保持粒度 virtualhost <string> #检查的web服务器的虚拟主机(host:头) sorry_server<IPADDR> <port> #备用机,所有realserver失效后启用,利用这个sorry server提供一个优雅的维护页面 real_server 192.168.200.5 23 { #也即服务器池。Real_server的值包括ip地址和端口号。多个连续的真实ip weight 1 #权重值是一个数字,数值越大,权重越高。 #使用不同的权重值的目的在于为不同性能的机器分配不同的负载,性能较好的机器,负载分担大些; #反之,性能差的机器,则分担较少的负载,这样就可以合理的利用不同性能的机器资源。 inhibit_on_failure #在服务器健康检查失效时,将其设为0,而不是直接从ipvs中删除 notify_up <string> | <quoted-string> #在检测到server up后执行脚本 notify_down <string> | <quoted-string> #在检测到server down后执行脚本 TCP_CHECK { connect_timeout 3 #连接超时时间 nb_get_retry 3 #重连次数 delay_before_retry 3 #重连间隔时间 connect_port 23 #健康检查的端口的端口 bindto <ip> } HTTP_GET | SSL_GET{ url{ #检查url,可以指定多个 path / digest <string> #检查后的摘要信息 status_code 200 #检查的返回状态码 } connect_port <port> bindto <IPADD> connect_timeout 5 nb_get_retry 3 delay_before_retry 2 } SMTP_CHECK{ host{ connect_ip <IP ADDRESS> connect_port <port> #默认检查25端口 bindto <IP ADDRESS> } connect_timeout 5 retry 3 delay_before_retry 2 helo_name <string> | <quoted-string> #smtp helo请求命令参数,可选 } MISC_CHECK{ misc_path <string> | <quoted-string> #外部脚本路径 misc_timeout #脚本执行超时时间 misc_dynamic #如设置该项,则退出状态码会用来动态调整服务器的权重 #返回0 正常,不修改;返回1,检查失败,权重改为0;返回2-255,正常,权重设置为:返回状态码-2 } }
3-2 实例
主:
! Configuration File for keepalived
global_defs { router_id bhz005 ##标识节点的字符串,通常为hostname } ## keepalived 会定时执行脚本并且对脚本的执行结果进行分析,动态调整vrrp_instance的优先级。这里的权重weight 是与下面的优先级priority有关,如果执行了一次检查脚本成功,则权重会-20,也就是由100 - 20 变成了80,Master 的优先级为80 就低于了Backup的优先级90,那么会进行自动的主备切换。 如果脚本执行结果为0并且weight配置的值大于0,则优先级会相应增加。 如果脚本执行结果不为0 并且weight配置的值小于0,则优先级会相应减少。 vrrp_script chk_nginx { script "/etc/keepalived/nginx_check.sh" ##执行脚本位置 interval 2 ##检测时间间隔 weight -20 ## 如果条件成立则权重减20(-20) } ## 定义虚拟路由 VI_1为自定义标识。 vrrp_instance VI_1 { state MASTER ## 主节点为MASTER,备份节点为BACKUP ## 绑定虚拟IP的网络接口(网卡),与本机IP地址所在的网络接口相同(我这里是eth6) interface eth6 virtual_router_id 172 ## 虚拟路由ID号 mcast_src_ip 192.168.1.172 ## 本机ip地址 priority 100 ##优先级配置(0-254的值) Nopreempt ## advert_int 1 ## 组播信息发送间隔,俩个节点必须配置一致,默认1s authentication { auth_type PASS auth_pass bhz ## 真实生产环境下对密码进行匹配 } track_script { chk_nginx } virtual_ipaddress { 192.168.1.170 ## 虚拟ip(vip),可以指定多个 } }
从:
! Configuration File for keepalived global_defs { router_id bhz006 } vrrp_script chk_nginx { script "/etc/keepalived/nginx_check.sh" interval 2 weight -20 } vrrp_instance VI_1 { state BACKUP interface eth7 virtual_router_id 173 mcast_src_ip 192.168.1.173 priority 90 ##优先级配置 advert_int 1 authentication { auth_type PASS auth_pass bhz } track_script { chk_nginx } virtual_ipaddress { 192.168.1.170 } }
4.心跳检测
在keepalive.conf里面配置,每隔两秒钟执行/etc/keepalived下的nginx——check脚本
网上对于脚本的思路大概都是这样的:
查看nginx的进程是不是0,是的话拉起来nginx,
#!/bin/bash
A=`ps -C nginx –no-header |wc -l`
if [ $A -eq 0 ];then
/usr/local/nginx/sbin/nginx
sleep 2
if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
killall keepalived
fi
fi
附录A 查看日志
tail -f /var/log/messages
# systemctl status keepalived.service 可以看错误日志
如果可能出现这样的报错
[root@BanAn-nginx2 sbin]# systemctl status keepalived.service ● keepalived.service - SYSV: Start and stop Keepalived Loaded: loaded (/etc/rc.d/init.d/keepalived; bad; vendor preset: disabled) Active: failed (Result: exit-code) since 一 2018-12-17 17:02:33 CST; 1min 2s ago Docs: man:systemd-sysv-generator(8) Process: 25668 ExecStart=/etc/rc.d/init.d/keepalived start (code=exited, status=1/FAILURE) 12月 17 17:02:33 BanAn-nginx2 systemd[1]: Starting SYSV: Start and sto.... 12月 17 17:02:33 BanAn-nginx2 keepalived[25668]: Starting keepalived: /…令 12月 17 17:02:33 BanAn-nginx2 keepalived[25668]: [失败] 12月 17 17:02:33 BanAn-nginx2 systemd[1]: keepalived.service: control ...1 12月 17 17:02:33 BanAn-nginx2 systemd[1]: Failed to start SYSV: Start .... 12月 17 17:02:33 BanAn-nginx2 systemd[1]: Unit keepalived.service ente.... 12月 17 17:02:33 BanAn-nginx2 systemd[1]: keepalived.service failed. Hint: Some lines were ellipsized, use -l to show in full. [root@BanAn-nginx2 sbin]# systemctl status keepalived.service -l ● keepalived.service - SYSV: Start and stop Keepalived Loaded: loaded (/etc/rc.d/init.d/keepalived; bad; vendor preset: disabled) Active: failed (Result: exit-code) since 一 2018-12-17 17:02:33 CST; 2min 9s ago Docs: man:systemd-sysv-generator(8) Process: 25668 ExecStart=/etc/rc.d/init.d/keepalived start (code=exited, status=1/FAILURE) 12月 17 17:02:33 BanAn-nginx2 systemd[1]: Starting SYSV: Start and stop Keepalived... 12月 17 17:02:33 BanAn-nginx2 keepalived[25668]: Starting keepalived: /bin/bash: keepalived: 未找到命令 12月 17 17:02:33 BanAn-nginx2 keepalived[25668]: [失败] 12月 17 17:02:33 BanAn-nginx2 systemd[1]: keepalived.service: control process exited, code=exited status=1 12月 17 17:02:33 BanAn-nginx2 systemd[1]: Failed to start SYSV: Start and stop Keepalived. 12月 17 17:02:33 BanAn-nginx2 systemd[1]: Unit keepalived.service entered failed state. 12月 17 17:02:33 BanAn-nginx2 systemd[1]: keepalived.service failed. [root@BanAn-nginx2 sbin]# cd /usr/sbin/
那么这样做就可以了
cd /usr/sbin/ rm -f keepalived cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
以上是关于nginx:负载均衡实战nginx=keepalived的主要内容,如果未能解决你的问题,请参考以下文章