Nginx+Keepalived实现站点高可用
vrrp
虚拟路由冗余协议(Virtual Router Redundancy Protocol,简称VRRP)是由IETF提出的解决局域网中配置静态网关出现单点失效现象的路由协议,1998年已推出正式的RFC2338协议标准。VRRP广泛应用在边缘网络中,它的设计目标是支持特定情况下IP数据流量失败转移不会引起混乱,允许主机使用单路由器,以及及时在实际第一跳路由器使用失败的情形下仍能够维护路由器间的连通性。
1、vrrp相关术语,摘自H3C VRRP白皮书
虚拟路由器:由一个 Master 路由器和多个 Backup 路由器组成。主机将虚拟路由器当作默认网关。
VRID:虚拟路由器的标识。有相同 VRID 的一组路由器构成一个虚拟路由器。
Master 路由器:虚拟路由器中承担报文转发任务的路由器。
Backup 路由器: Master 路由器出现故障时,能够代替 Master 路由器工作的路由器。
虚拟 IP 地址:虚拟路由器的 IP 地址。一个虚拟路由器可以拥有一个或多个IP地址。
IP 地址拥有者:接口 IP 地址与虚拟 IP 地址相同的路由器被称为IP地址拥有者。
虚拟 MAC 地址:一个虚拟路由器拥有一个虚拟MAC地址。虚拟MAC地址 的格式为 00-00-5E-00-01-{VRID}。通常情况下,虚拟路由器回应 ARP 请求使用的是虚拟MAC地址,只有虚拟路由器做特殊配置的时候,才回应接口的真实 MAC 地址。
优先级: VRRP 根据优先级来确定虚拟路由器中每台路由器的地位。
非抢占方式:如果 Backup 路由器工作在非抢占方式下,则只要 Master 路由器没有出现故障, Backup 路由器即使随后被配置了更高的优先级也不会成为Master 路由器。
抢占方式:如果 Backup 路由器工作在抢占方式下,当它收到 VRRP 报文后,会将自己的优先级与通告报文中的优先级进行比较。如果自己的优先级比当前的 Master 路由器的优先级高,就会主动抢占成为 Master 路由器;否则,将保持 Backup 状态。
VRRP的工作过程为:
1) 虚拟路由器中的路由器根据优先级选举出 Master。Master路由器通过发送免费ARP报文,将自己的虚拟MAC地址通知给与它连接的设备或者主机,从而承担报文转发任务
2) Master 路由器周期性发送 VRRP 报文,以公布其配置信息(心跳,优先级等)和工作状况;
3) 如果 Master 路由器出现故障,虚拟路由器中的 Backup 路由器将根据优先级重新选举新的 Master;
4) 虚拟路由器状态切换时, Master 路由器由一台设备切换为另外一台设备,新的 Master 路由器只是简单地发送一个携带虚拟路由器的 MAC 地址和虚拟 IP地址信息的免费 ARP 报文,这样就可以更新与它连接的主机或设备中的ARP 相关信息。网络中的主机感知不到 Master 路由器已经切换为另外一台设备。
5) Backup 路由器的优先级高于 Master 路由器时,由 Backup 路由器的工作方式(抢占方式和非抢占方式)决定是否重新选举 Master。
VRRP的功能:
Master 路由器的选举;
Master 路由器状态的通告;心跳,优先级等;
提高安全性的认证功能;简单字符认证,MD5认证
VRRP工作模式:
1、主备备份;主备备份方式表示业务仅由Master路由器承担。当Master路由器出现故障时,才会由选举出来的Backup路由器接替它工作。初始情况下, Device A是Master路由器并承担转发任务, Device B和Device C是Backup路由器且都处于就绪监听状态。如果Device A发生故障,则虚拟路由器内处于Backup状态的Device B和Device C路由器将根据优先级选出一个新的Master路由器,这个新Master路由器继续为网络内的主机转发数据。如下图;
2、主主备份;在路由器的一个接口上可以创建多个虚拟路由器,使得该路由器可以在一个虚拟路由器中作为Master路由器,同时在其他的虚拟路由器中作为Backup路由器。多台路由器同时承担业务,式需要两个或者两个以上的虚拟路由器,每个虚拟路由器都包括一个Master路由器和若干个Backup路由器,各虚拟路由器的Master路由器可以各不相同,实现负载分担。如下图;
Keepalived介绍
Keepalived是一个基于VRRP协议来实现的服务高可用方案,可以利用其来避免IP单点故障,原生设计的目的为了高可用ipvs服务:实现基于vrrp协议完成地址流动,根据配置文件中的定义为vip地址所在的节点生成ipvs规则,为ipvs集群的各RS做健康状态检测,基于脚本调用接口通过执行脚本完成脚本中定义的功能,进而影响集群事务;
程序组件:
1、核心组件
2、控制组件:配置文件分析器
3、IO复用器
4、内存管理组件
核心组件如下;
Watch dog:高可用监视器
checkers:健康状态检测器(TCP、HTTP、SSL、MISC… …)
smtp:支持发送邮件通告机制
System call:支持系统调用机制,作出管理操作
vrrp stack:VRRP栈的实现,实现VRRP协议调用
Netlink Reflectior:VRRP借助于Netlink监控网络,实现网络功能配置
ipvs wrapper:ipvs控制
keepalived高可用集群配置前提
1)各节点时间要同步;必须不能超过一秒,一般使用网络时间同步服务器(ntp, chrony)
2)确保iptables及selinux不会成为障碍;
3)各节点之间可通过主机名互相通信(对KA并非必须);节点的名称设定与hosts文件中解析的主机名都要保持一致; #uname -n 获得的主机,与解析的主机名要相同;建议使用/etc/hosts文件实现
4)各节点之间的root用户可以基于密钥认证的ssh服务完成互相通信;(并非必须)
keepalived程序环境配置
keepalived在CentOS 6.4+收录到发行版光盘内,否则需要编译安装或者第三方RPM包
程序环境:
1)配置文件:/etc/keepalived/keepalived.conf
2)主程序:/usr/sbin/keepalived
3)Unit File:keepalived.service
配置文件组件部分:
1)GLOBALCONFIGURATION:全局配置有两个组件组成 Global definitions:全局定义 Static routes/addresses:静态路由配置 2)VRRPDCONFIGURATION:配置vrrp VRRP synchronization group(s):VRRP同步组 VRRP instance(s):VRRP实例,即定义虚拟路由器 3)LVSCONFIGURATION:ipvs的相关配置集群服务,服务内的RS; Virtual server group(s):虚拟服务组 Virtual server(s):虚拟服务示例的定义
GLOBALCONFIGURATION:全局配置
常用配置参数: notification_email{…}:收件人邮箱地址 notification_email_from:发件人邮箱地址 smtp_server:邮件发送服务器IP; smtp_connect_timeout:邮件服务器建立连接的超时时长;默认30秒 router_id LVS_DEVEL:物理节点的标识符;建立使用主机名; vrrp_mcast_group4:IPV4多播地址,默认224.0.0.19;
VRRPDCONFIGURATION:配置vrrp实例
配置语法: 配置虚拟路由器: vrrp_instance <STRING> { .... } 常用配置参数: state MASTER|BACKUP:当前节点在此虚拟路由器上的初始状态;只能有一个是MASTER,余下的都应该为BACKUP; interface IFACE_NAME:绑定为当前虚拟路由器使用的物理接口; virtual_router_id VRID:当前虚拟路由器的惟一标识,范围是0-255; priority 100:当前主机在此虚拟路径器中的优先级;范围1-254; advert_int 1:vrrp通告的时间间隔; 认证方式配置 authentication{ # Authentication block #PASS||AH #PASS - Simple Passwd (suggested) 推荐使用简单字符串认证 #AH - IPSEC (not recommended)) 不推荐使用高级认证机制 auth_typePASS #Password for accessing vrrpd. #should be the same for all machines. #Only the first eight (8) characters are used. auth_pass1234 认证密钥不能超过8个字符,如果超过八个字符,则只有前八个字符生效 } 虚拟IP配置: irtual_ipaddress { <IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL> 192.168.200.17/24 dev eth1 192.168.200.18/24 dev eth2 label eth2:1 } 配置参数: <IPADDR>:ip地址,可以只有ip <MASK>:掩码 brd <IPADDR>:广播地址 dev <STRING>:配置在哪个设备上 scope <SCOPE>:生效作用域:表示只能与本机通信还是要与外部通信,一般默认都是能够与外部通信 label <LABEL>:需要的时候可以定义到网卡别名上。一般之间指定到设备上就ok 监控网络设备接口配置:配置要监控的网络接口,一旦接口出现故障,则转为FAULT状态并且重新触发选举; track_interface { eth0 eth1 ... } 对于转为FAULT状态的网络接口恢复的时候的模式定义配置;默认为抢占模式 nopreempt:定义工作模式为非抢占模式; preempt_delay 300:抢占式模式下,节点上线后触发新选举操作的延迟时长; 定义通知脚本的配置: notify_master <STRING>|<QUOTED-STRING>:当前节点成为主节点时触发的脚本; notify_backup <STRING>|<QUOTED-STRING>:当前节点转为备节点时触发的脚本; notify_fault <STRING>|<QUOTED-STRING>:当前节点转为“失败”状态时触发的脚本; notify <STRING>|<QUOTED-STRING>:通用格式的通知触发机制,一个脚本可完成以上三种状态的转换时的通知;
单主配置示例:需要启用网卡多播功能,(前提:网卡支持多播):ip link set dev DEVICE multicast on
! Configuration File for keepalived global_defs { notification_email { root@localhost } notification_email_from keepalived@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id node1 vrrp_mcast_group4 224.0.100.19 } vrrp_instance VI_1 { state BACKUP interface eno16777736 virtual_router_id 14 priority 98 advert_int 1 authentication { auth_type PASS auth_pass 571f97b2 } virtual_ipaddress { 10.1.0.91/16 dev eno16777736 } }
双主模型示例:
! Configuration File for keepalived 第一步:node1节点配置 global_defs { notification_email { root@localhost } notification_email_from keepalived@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id node1 vrrp_mcast_group4 224.0.100.19 } vrrp_instance VI_1 { state MASTER interface eno16777736 virtual_router_id 14 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 571f97b2 } virtual_ipaddress { 10.1.0.91/16 dev eno16777736 } } vrrp_instance VI_2 { state BACKUP interface eno16777736 virtual_router_id 15 priority 98 advert_int 1 authentication { auth_type PASS uth_pass 578f07b2 } virtual_ipaddress { 10.1.0.92/16 dev eno16777736 } } 第二步:node2节点配置 global_defs { notification_email { root@localhost } notification_email_from keepalived@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id node1 vrrp_mcast_group4 224.0.100.19 } vrrp_instance VI_1 { state BACKUP interface eno16777736 virtual_router_id 14 priority 98 advert_int 1 authentication { auth_type PASS auth_pass 571f97b2 } virtual_ipaddress { 10.1.0.91/16 dev eno16777736 } } vrrp_instance VI_2 { state MASTER interface eno16777736 virtual_router_id 15 priority 100 advert_int 1 authentication { auth_type PASS uth_pass 578f07b2 } virtual_ipaddress { 10.1.0.92/16 dev eno16777736 } }
通知脚本示例:
#!/bin/bash # contact='root@localhost' notify() { mailsubject="$(hostname) to be $1, vip floating" mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1" echo "$mailbody" | mail -s "$mailsubject" $contact } case $1 in master) notify master ;; backup) notify backup ;; fault) notify fault ;; *) echo "Usage: $(basename $0) {master|backup|fault}" exit 1 ;; esac 脚本的调用方法: notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault"
keepalived高可用ipvs服务配置:
1.定义集群服务方法
方法1、virtual_server IP port{ ... } 方法2、virtual_server fwmark int{ { ... real_server { ... } ... } 常用参数: delay_loop <INT>:服务轮询的时间间隔;用来定义做健康状态检测的时候每隔多长时间做一次健康状态检测 lb_algo rr|wrr|lc|wlc|lblc|sh|dh:定义调度方法; lb_kind NAT|DR|TUN:集群的类型; persistence_timeout <INT>:持久连接时长; protocol TCP:服务协议,仅支持TCP; sorry_server <IPADDR> <PORT>:备用服务器地址;
2.定义RS的方法(应用上下文virutal_server)
常用参数: real_server <IPADDR> <PORT>{ weight #:指明当前RS权重 notify_up <STRING>|<QUOTED-STRING>:定义up脚本 notify_down <STRING>|<QUOTED-STRING>:定义down脚本 HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK { ... }:定义当前主机的健康状态检测方法; }
keepalived健康状态检测机制
1.web应用层检测
检测参数; HTTP_GET|SSL_GET { url { :检测URL path <URL_PATH>:定义要监控的URL路径; status_code <INT>:期望返回判断上述检测机制为健康状态的响应码; digest <STRING>:判断上述检测机制为健康状态的响应的内容的校验码; } nb_get_retry <INT>:检测每隔多长时间的重试次数; delay_before_retry <INT>:每次重试之前的延迟时长; connect_ip <IP ADDRESS>:向当前RS的哪个IP地址发起健康状态检测请求 connect_port <PORT>:向当前RS的哪个PORT发起健康状态检测请求 bindto <IP ADDRESS>:发出健康状态检测请求时使用的源地址; bind_port <PORT>:发出健康状态检测请求时使用的源端口; connect_timeout <INTEGER>:连接请求的超时时长; }
2.传输层检测(tcp协议层)
检测参数; TCP_CHECK { connect_ip <IP ADDRESS>:向当前RS的哪个IP地址发起健康状态检测请求 connect_port <PORT>:向当前RS的哪个PORT发起健康状态检测请求 bindto <IP ADDRESS>:发出健康状态检测请求时使用的源地址; bind_port <PORT>:发出健康状态检测请求时使用的源端口; connect_timeout <INTEGER>:连接请求的超时时长; }
keepalived调用外部的辅助脚本进行资源监控,并根据监控的结果状态能实现优先动态调整;
第一步:在global_defs中定义脚本;可以是直接写进配置文件中的脚本,也可以调用一个外部脚本
vrrp_script <SCRIPT_NAME> { script "" #指明脚本是什么,可以是个路径,也可以直接写在这里 interval INT #每个多长时间执行一次脚本监控 weight -INT #脚本执行失败后减去权重的值(要确保减去后的优先级低于备用的优先级) }
第二步:在vrrp_instance实例追踪定义脚本,用于作为实例的当前节点的监控机制
track_script { SCRIPT_NAME_1 SCRIPT_NAME_2 ... }
示例:
在vrrp_instance配置段之外编辑 vrrp_script chk_down { script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0" #判断是否在/etc/keepalived目录下有down文件 interval 1 #检测down文件不在的话就每隔1秒检测一次 weight -5 #检测down文件在的话就将权重减5 } 在vrrp_instance配置段之内编辑 track_script{ chk_down #定义追踪chk_down这个脚本 }
注意:节点1和节点2都需要配置,配置完以后只需在主节点主机的/etc/keepalived目录下创建一个down文件就可实现动态切换而无需停掉服务,删除掉down文件后当前节点就可再次成为主节点。
此功能也可以用于实现在nginx服务故障的时候自动切换节点,如在脚本判断中检测nginx进程是否存在来进行自动切换
原创文章,作者:M20-1马星,如若转载,请注明出处:http://www.178linux.com/58148