Keepalived
一、环境,2台虚拟机(centos2.6.32-358.el6.x86_64)
Vm1:121
Vm2:122
二、keepalived实现高可用(多主多备)
1)Vm1和Vm2的keepalived配置文件keepalived.conf
2)注意;
a.router_id每一个keepalived实例不能相同;
b.track_script必须放在virtaul_ipaddress后面,等vip绑定了才能进行验证负载均衡的nginx是否存活;
c.interface对应的值是本机的网卡名;
d.virtaul_ipaddress会根据配置,绑定vip到本机网卡interface;
e.同一个virtaul_ipaddress对应的主从virtual_router_id的,必须一致,才能识别彼此是主从,否则两个vip所对应的BACKUP状态的vrrp_instance都会“TransitiontoMASTERSTATE”;
f.同一个keepalived实例的不同vrrp_instance实例,对应的virtual_router_id不能相同,如果相同,那就同一个物理机做主备,意义不大;
g.priority,主vrrp_instance必须大于备vrrp_instance;否则备vrrp_instance将会“VRRP_Instance(nginx_1)TransitiontoMASTERSTATE”;
h.主备机vrrp_instance之间通信是通过协议vrrp,注意关闭iptables(serviceiptablesstop)或者把vrrp通信的通道加入iptables规则中允许通过(iptables-AINPUT-d224.0.0.18-jACCEPT),否则会因为主备不能通讯,而不知道是否存活,导致备机全部转成MASTER的状态。
i.state BACKUP #MASTER的状态改为BACKUP
nopreempt #MASTER设置为不抢占,BACKUP不用设置
priority 200 #MASTER的优先级比BACKUP要高
j.interface eth0 这个是指定vrrp通信的网卡,可以在内网网卡进行主备通信。
3)需要额外的一个track_script来验证负载均衡的nginx是否存在,及其相应对策:
vim/home/script/check_nginx.sh
#-------------------------start----------------------------
#!/bin/bash
url="http://121/index.html"
resp_status=$(curl-s--head"$url"|awk'/HTTP/{print$2}')
if["$resp_status"!="200"];then
echo"121nginxdie"
pkillkeepalived
Fi
#-------------------------end----------------------------
该脚本,执行间隔为interval为2s,每隔2s去检查nginx的状态,如果发现nginx返回非200状态码,则终止keepalived,vip的绑定随之移除,则备机的BACKUP的keepalived发现对方没存活,则把vrrp_instance“TransitiontoMASTERSTATE”。这样就实现了自动切换,从而达到高可用性。
三、nginx做负载均衡
Nginx是使用反向代理来实现负载均衡;
1、Vim$nginx_home/conf/nginx.conf
#------------------------------start------------------------------------------
......
upstreamapp1{
ip_hash;
serverlocalhost:8011weight=1max_fails=2fail_timeout=30s;
serverlocalhost:8012weight=1max_fails=2fail_timeout=30s;
}
upstreamapp2{
serverlocalhost:8021weight=1max_fails=2fail_timeout=30s;
serverlocalhost:8022weight=1max_fails=2fail_timeout=30s;
}
server{
listen80;
......
location/app1{
proxy_next_upstreamhttp_502http_504errortimeoutinvalid_header;
proxy_passhttp://app1;
proxy_set_headerHost$host;
proxy_set_headerX-Forwarded_For$remote_addr;
}
location/app2{
proxy_next_upstreamhttp_502http_504errortimeoutinvalid_header;
proxy_passhttp://app2;
proxy_set_headerHost$host;
proxy_set_headerX-Forwarded_For$remote_addr;
}
......
#------------------------------end------------------------------------------
2、注意点:
a.“location/app1”根据url规则来进行分发请求(“proxy_passhttp://app2”),实现负载方式之一
b.“proxy_next_upstream”实现的是发现upstream中一个后端的服务器响应回来是502,或者504,则转发到另外一个后端的服务器;
c.“max_fails=2fail_timeout=30s”,实现的是,最多错误2次,在30s内,任何下一次请求,将忽略该服务器,不再转发给这个服务器;
d.“ip_hash”,这个功能实现的是,根据当前连接的真实ip来计算iphash值,进行定位到后端的一台服务器,这种情况容易出现负载不均衡的现象,查了下源码“iphp->addr=(u_char*)&sin->sin_addr.s_addr;”这个功能根据的iphash是获取的是当前连接,如果nginx负载之前是由前端转发过来的请求,获取到的ip是该连接的ip,而不是真实的客户端ip,保持会话的通道不是支持的很好;
e.Nginx有一个第三方的插件,nginx-sticky-module,版本nginx-1.5.3和nginx-sticky-module-1.1(https://code.google.com/p/nginx-sticky-module/)编译会有点问题,应该是nginx新版本没有相应的nginx-sticky-module,需要对nginx-sticky-module-1.1/ngx_http_sticky_misc.c的281行改为digest->len=ngx_sock_ntop(in,sizeof(structsockaddr_in),digest->data,len,1);重新编译即可(./configure --prefix=/home/local/nginx --with-pcre=/home/download/pcre-8.33/ --with-zlib=/home/download/zlib-1.2.8/ --with-openssl=/home/download/openssl-1.0.1e/ --with-http_stub_status_module --with-http_ssl_module --with-http_realip_module --add-module=/home/download/nginx-sticky-module-1.1);经过验证,模块sticky会根据请求的cookie来定位到后端的服务器,该cookie是请求首次经过nginx的时候附加上去的,从而实现了会话长连接的保持。
最后,keepalived+nginx能轻松的实现负载均衡,多主多备,自动切换,发现后端某一节点故障,能自动的把请求切换到另外一个节点;建议,使用nginx来进行负载,最好不要用ip_hash,而使用类似于nginx-sticky-module进行基于session负载,可以维持会话长连接。
最后的把nginx负载接入到LVS上:
把nginx接入到LVS后面,直接在lvs那边的keepalived.conf上的节点vrrp_instance上,加入real_server节点,指向用于负载均衡的nginx即可,其他的保持和上面的一致。