一、理论部分:
keepalived是vrrp协议的实现:原生设计目的为高可用ipvs服务;keepalived能够配置文件中的定义生成ipvs规则;并能够对各RealServer的健康状态进行检测;
vrrp协议:虚拟冗余路由协议:早期只是主要在路由器上提供的一种非常简单的完成将多个物理设备组建成一个虚拟设备,并且在多个物理设备之间漂移地址一种协议;非常轻量化,性能非常好。而keepalived无非就是通过vrrp协议在Linux主机上通过一个守护进程,把Linux主机扮演成路由器,而后能够让地址漂移的这么一种解决方案;
keepalives能够配置文件中的定义生成ipvs规则,并能够对各RS的健康状态进行检测;
keepalived它能够保证IP地址,一定会配置在正常的、在线的那台主机上,keepalived服务的设计者还在现有的基础上,在其内部添加了一种线程机制,这个线程它能够帮助我们去完成按需监控后端的real server,向ipvs之上添加事先所定义好的高可用集群服务,并监控各real server的健康状态;而后完成按需增删的功能;
keepalived描述:
核心组件: VRRP Stack、IPVS wrapper、Checkers;keepalived主要就是依靠这三种工具来实现了高可用的ipvs集群;
VRRP Stack:VRRP协议的实现,完成地址流动;
SMTP:通过SMTP协议实现邮件发送通知,从主节点到备节点切换后以邮件发送至管理员;
IPVS wrapper:能够根据配置文件去分析用户的ipvs配置,将其生成规则定义保存在ipvs栈;
Checkers:检测器,基于以下协议以及各种方式对后端的real server做健康状态检测的功能;如果检测到哪个real server宕机,它需要从ipvs的规则当中把real server移除,移除完之后通过调用SMTP协议通知管理员。还要借助于IPVS wrapper(IPVS包装器)通过调用IPVS的接口来向IPVS上添加、删除和修改相关的规则,但是这个过程并不使用IPVS命令,而是内部实现;检测的机制支持向应用层的:HTTP_GET, SSL_GET, TCP_CHHECK.等;
WatchDog:如果keepalived自己的checkers进程或者VRRP Stack进程挂了怎么办? WatchDog会尝试重启他们;
虚拟路由器:由一个Master路由器和多个Backup路由器组成。主机将虚拟路由器当做默认网关。
VRID:集群名称,虚拟路由器标识,取值范围0-255。有相同VRID的一组路由器构成一个虚拟路由器。
Master路由器:虚拟路由器中承担报文转发任务额路由器;
Backup路由器:Master路由器出现故障时,能够代替Master路由器工作的路由器;
虚拟IP地址(VIP):虚拟路由器的IP地址。一个细腻路由区可以拥有一个或多个IP地址;
IP地址拥有者:接口IP地址与虚拟IP地址相同的路由器被称为IP地址拥有者。
虚拟MAC地址:一个虚拟路由器拥有一个虚拟MAC地址。虚拟MAC地址的格式为00-005E-00-01-{VRID}。通常情况下,虚拟路由器回应ARP请求使用的是虚拟MAC地址,只有虚拟路由器做特殊配置的时候,才回应接口的真实MAC地址;
优先级:VRRP根据优先级来确定虚拟路由器中每台路由器的位置。
工作方式:
抢占方式:如果Backup路由器工作在抢占式下,当它收到VRRP报文后,会将自己的优先级与通告报文中的优先级进行比较。如果自己的优先级比当前的Master路由器的优先级高,就会主动抢占成为Master路由器;否则,将保持Backup状态;
非抢占式:如果Backup路由器工作在非抢占式方式下,则只要Master路由器没有出现故障,Backup路由器及时随后被配置了更高的优先级也不会成为Master路由器。
VRRP还提供了三种认证方式:
无认证:不进行任何VRRP报文的合法性认证,不提供安全性保障。
简单字符串认证:预共享密钥;在一个有可能受到安全威胁的网络中,可以将认证方式设置为简单字符认证。发送VRRP报文的路由器将认证字填入到VRRP报文中,而收到VRRP报文的路由器会将收到的VRRP报文中的认证字和本地配置的认证字进行比较。如果认证字相同,则认为接收到的报文是合法的VRRP报文;否则认为接收到的报文是一个非法报文。
md5认证:在一个非常不安全的网络中,可以将认证方式设置为MD5认证。发送VRRP报文的路由器利用认证字和MD5算法对VRRP报文进行加密,加密后的报文保存在Authentication Header(认证头)中。收到VRRP报文的路由器会利用认证字解密报文,检查该报文的合法性。
组件:
控制组件:配置文件分析器;
内存管理
IO复用
核心组件:
vrrp stack
checker
ipvs wrapper
watch dog
二、配置文件详解:
CentOS 6.4以上的版本, keepalived程序包已经被收进base源中;
##yum -y install keepalived
主配置文件:/etc/keepalived/keepalived.conf
Unit file:/usr/lib/systemd/system/keepalived.service
配置文件:/etc/sysconfig/keepalived
配置文件内容块分为三部分:
(1)global configuration:全局配置,主要是放在global_defs中;
global_defs {
...
}
(2)vrrpd configuration:主要有两部分:
vrrp_sync_group GROUP_NAME { :第一种,vrrp的同步组;
...
}
vrrp_instance INST_NAME { :第二种:vrrp实例;
...
}
(3)lvs configuration:虚拟服务器配置;分为两种:
virtual_server_group VIRTUAL_SERVER_GROUP_NAME { :虚拟服务器组;
....
}
virtual_server IP port |
virtual_server fwmark int {
protocolTCP ##keepalived只支持TCP协议;
...
real_server <IPADDR><PORT> { ##引入后端server的地址和端口,端口要和virtual_server的端口保持一致
...
}
real_server <IPADDR><PORT> {
...
}
}
配置实例:
global_defs { notification_email { ##接收邮件的地址;就是说通知邮件应该发送给谁,通常写自己的地址; [email protected] ##收件人,表示发送给本机的root用户; } notification_email_from [email protected] ##发件人; smtp_server 127.0.0.1 ##表示哪个服务器是帮你传递邮件的服务; smtp_connect_timeout 30 ##邮件服务发布邮件的超时时长; router_id node1 ##当前路由器设备的id号;设备的号码通常是一个主机名; vrrp_mcast_group4 224.0.100.18 ##vrrp协议是通过多播向外发送的;这里指的是ipv4的多播地址;vrrp_mcast_group6,就表示ipv6的地址;如果不指默认都是用224.0.0.18发送; }
虚拟路由配置实例:
vrrp_instance <string> { ##虚拟路由实例,名称可以自定义; state MASTER ##当前物理设备在这个虚拟路由器中的初始状态,是主节点还是备节点;MASTER|BACKUP; interface eth0 ##vrrp通过哪一个网卡接口上进工作;通过这个接口绑定多播地址,基于多播地址发送心跳信息; virtual_router_id 51 ##当前虚拟路由器设备的id号;有效范围0-255;默认是51; priority 100 ##优先级,当前路由器物理设备在当前虚拟路由器当中的优先级;要定义MASTER优先级是最高的; advert_int 1 ##广播通告的时间间隔,每隔多长时间向外发送自身的心跳信息,默认是一秒钟一次; authentication { ##认证,定义消息认证机制; auth_type PASS ##简单字符串认证; auth_pass 1111 ##密码,不能超过8位;可使用#openssl rand -base64 8命令定义随机字符串; } virtual_ipaddress { ##定义虚拟IP地址;可以有多个;如果不指就是上interface的接口; 方法: <IPADDR>/<MASK>brd<IPADDR>dev<STRING>scope<SCOPE>label<LABE;> 示例: 192.168.200.18 192.168.200.16/24 dev eth1 192.168.200.17/24 dev eth2 label eth2:1 } track_interface { ##表示要监听的接口,以确保这个接口出现故障时,能够将地址向其他的示例节点转移; eth0 eth1 ... } nopreempt ##工作于非抢占模式; preempt_delay 300: ##抢占延迟,表示等待多长时间再抢占; ##在对整个路由设备来讲内部出现故障时还可以通告: 通告脚本定义: notify_master <STRING>|<QUOTED-STRING> ##当前节点成为主节点时发送通告;指定一个脚本路行通告; notify_backup <STRING>|<QUOTED-STRING> ##当前节点成为备节点时发送通告;指定一个脚本路行通告; notify_fault <STRING>|<QUOTED-STRING> ##当前节点故障了,指定一个脚本路径通告; nitify <STRING>|<QUOTED-STRING> ##以上三个功能用一个脚本就能搞定(无论发生什么变化),指定一个脚本进行通告;
调用方法:要使用双引号,没有引号或单引号都不可以;
虚拟服务器配置实例:
virtual_server 192.168.200.100 443 { ##虚拟服务器的IP/PORT,要和 virtual_ipaddress中定义的地址保持一致; delay_loop 6 ##定义服务轮询时间间隔;每隔多长时间对本机做健康状态检测; lb_algo rr ##负载均衡调度方法 lb_kind NAT ##LVS集群的类型; nat_mask 255.255.255.0 ##如果是nat模式的话,要指明nat当中后端服务对应的掩码; persistence_timeout 50 ##定义持久连接时长;单位是秒钟; protocol TCP ##服务的协议;keepalived仅支持TCP协议; sorry_server 192.168.200.2 1358 ##所有后端主机故障时,提供say sorry页面; real_server 192.168.201.100 443 { ##real server的地址和端口; weight 1 ##权重; notify_up <STRING>|<QUOTED-STRING> ##real server节点上线时调用的通知脚本; notify_down <STRING>|<QUOTED-STRING> ##real server节点离线时调用的通知脚本; SSL_GET { ##对real server健康状态检测的方式之一;应用层的检测;支持所有健康的状态: HTTP_GET|SSL_GET|TCP_CHECK(传输层检测;)|SMTP_CHECK|MISC_CHECK(杂项) url { ##指明要请求哪个资源的url路径; path / ##指明健康状态检测时请求的URL; digest ff20ad2481f97b1754ef3e12ecd3a9cc ##主页的内容要求这个资源的摘要信息做MD5计算;做摘要信息的结果必须是这个内容;可通过/usr/bin/genhash命令测试keepalived配置文件的hash码,保存到里面; status_code <INT> } url { path /mrtg/ digest 9b3a0c85a887a256d6939da88aabd8cd } connect_timeout 3 ##连接超时时长; nb_get_retry 3 ##重试请求的次数; delay_before_retry 3 ##两次重试之间等待的时长; 以上三项表示,一旦连接超时,等上三秒钟,再次重试,最多重试三次; connect_ip <IP ADDRESS> ##向此处指定的地址发测试请求;而不是real server所给定的地址; connect_port <PORT> ##向此处指定的端口发测试请求;而不是real server所给定的端口; bindto <IP ADDRESS> ##指明测试请求报文的源IP; binmd_port <PORT> ##指明测试请求报文的源PORT; } } }
HA 集群配置的前提:
(1)各节点时间同步;
ntp协议,chrony
(2)确保iptables及selinux不会阻碍;
(3)各节点之间可通过主机名互相通信(对keepalived并非必须);
名称解析服务器的解析结果必须与本机的“uname -n”命令的结果一致;解析结果和真正的主机名必须完全一致;
(4)各节点之间的root用户可以基于密钥认证的ssh通信(对keepalived并非必须);
三、基于keepalived+LVS-DR构建HA主备模型
拓扑:
环境:
Name | ip address |
主: | VIP:172.18.200.6/32,IP:172.18.200.2/16 |
备 | VIP:172.18.200.6/32,IP:172.18.200.1/16 |
real server1 |
VIP:172.18.200.6/32,IP:172.18.100.100/16 |
real server2 | VIP:172.18.200.6/32,IP:172.18.100.110/16 |
操作步骤:
(1)安装keepalived、http;各节点时间同步;
##yum -y install keepalived httpd #前端两台主机都要安装;
##ntpdate 172.18.0.1 #同步时间; 两个节点都要同步;
##crontab -e #创建计划任务,每5分钟同步一次时间; 两个节点都要同步;
*/5 * * * * /usr/sbin/ntpdate 172.18.0.1 &> /dev/null
(2)配置俩节点,并启动之;
主节点配置:
! Configuration File for keepalived global_defs { notification_email { [email protected] } notification_email_from [email protected] smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id node1 vrrp_mcast_group4 224.0.100.18 } vrrp_instance VI_1 { state MASTER interface eno16777736 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass pBkfC1ax } virtual_ipaddress { 172.18.200.6 dev eno16777736 label eno16777736:0 } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" } virtual_server 172.18.200.6 80 { ##定义虚拟IP地址; delay_loop 6 lb_algo rr ##算法 lb_kind DR ##dr模型 protocol TCP sorry_server 127.0.0.1 80 ##定义sorry页面 real_server 172.18.200.100 80 { ##real server的地址和端口; weight 1 HTTP_GET { url { path / status_code 200 } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 172.18.200.110 80 { weight 2 HTTP_GET { url { path / status_code 200 } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } }
备节点配置:
! Configuration File for keepalived global_defs { notification_email { [email protected] } notification_email_from [email protected] smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id node1 vrrp_mcast_group4 224.0.100.18 } vrrp_instance VI_1 { state BACKUP interface eno16777736 virtual_router_id 51 priority 98 advert_int 1 authentication { auth_type PASS auth_pass pBkfC1ax } virtual_ipaddress { 172.18.200.6 dev eno16777736 label eno16777736:0 } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" } virtual_server 172.18.200.6 80 { ##定义虚拟IP地址; delay_loop 6 lb_algo rr ##算法 lb_kind DR ##dr模型 protocol TCP sorry_server 127.0.0.1 80 ##定义sorry页面 real_server 172.18.200.100 80 { ##real server的地址和端口; weight 1 HTTP_GET { url { path / status_code 200 } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 172.18.200.110 80 { weight 2 HTTP_GET { url { path / status_code 200 } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } }
定义集群的规则是keepalived启动之后自动加载上去的;
##systemctl start keepalived.servcie ##启动两个节点;显示vip和集群规则已经配置在主节点上了,
(3)编写通知脚本示例:当状态发生改变时,可通过邮件发送一个简单的警告信息;##俩节点都要配置;
#vim /etc/keepalived/notify.sh
#scp /etc/keepalived/notify.sh [email protected],1:/etc/keepalived/
#脚本定义的邮件通知机制;
(4)在Real Server上配置:
限制响应级别和通告级别:
#echo 1> /proc/sys/net/ipv4/conf/all/arp_ignore
#echo 1> /proc/sys/net/ipv4/conf/lo/arp_ignore
#echo 2> /proc/sys/net/ipv4/conf/all/arp_announce
#echo 2> /proc/sys/net/ipv4/conf/lo/arp_announce
#ifconfig lo:0 172.18.200.6 netmask 255.255.255.255 broadcast 172.18.200.6
##表示目标地址是172.18.200.6的从lo:0接口进来,就从lo:0出去;
#route add -host 172.18.200.6 dev lo:0
(5)在real server1和2定义测试页面;
server1 server2
## vim /var/www/html/index.html ##vim /vaw/www/html/index/html
<html>Real Server 200.100 </html> <h1>Real server 200.110</h1>
5.1 MASTER测试;
5.2、把MASTER关掉,VIP已经漂移至BACKUP节点上,并发送脚本通知机制;
测试:
5.3 当real server故障时,会自动移除故障的主机;这里来关闭后端的server2测试:
##两台主备节点集群规则中已经没有server2条目;
##systemctl stop httpd.service
##在启动server2会自动添加回来:
##systemctl start httpd.service
(6)在上面的keepalived配置文件中,定义了sorry_server;这里在主备节点定义sorry_server页面;当后端的server都故障时,将用自定义的页面响应给用户;
主: 备:
##vim /var/www/html/index,html ##vim /var/www/html/index.html
<html> sorry server 1</html> <h1>sorry server 2</h1>
6.1 测试:
把后端的server都关闭:并显示调度在本机上指定的sorry页面;
再把主节点关闭,将显示备节点上的错误页面,并显示调度在本机上指定的sorry页面;
写的不周到之处,请各路大神不吝赐教。下一篇主主模型;