-- ha+lb heartbeat+ldirector keepalived piranha www.keepalived.org lvs + ha 是一个双机热备软件,它可以很好的和LVS进行集成 --下面的架构需要4台虚拟机,主DR和备DR用双网卡,建议使用两个内网来做,以免使用桥接网络会造成IP冲突(用vmware或kvm都可以) client (宿主机) 1.1.1.1 | | | VIP eth0:0 1.1.1.2 心跳 1.1.1.3 eth0---------eth0 1.1.1.4 master DR slave DR 2.2.2.3 eth1---------eth1 2.2.2.4 心跳 VIP eth1:0 2.2.2.2 | | | |-------------------------------| web1 web2 2.2.2.5 2.2.2.6 准备工作 1,主机名绑定 2.2.2.1 li.cluster.com 2.2.2.3 master.cluster.com 2.2.2.4 slave.cluster.com 2.2.2.5 web1.cluster.com 2.2.2.6 web2.cluster.com 2,时间同步 3,关闭iptables,selinux,并设置开机不自动启动 4,配置yum 5,配置静态IP并chkconfig NetworkManager off和chkconfig network on 6,建议两边的网卡名字一致(如两边都为eth0,如果是克隆的虚拟机,可以使用udev改成一致) 准备好架构后 第一大步: 主和备DR上都安装keepalived 软件包路径 笔记目录/arch/keepalived_soft/keepalived-1.2.19.tar.gz # yum install ipvsadm net-snmp* *libnl* -y (两台在编译前先安装相关的依赖性) Master DR-> tar xvf keepalived-1.2.19.tar.gz -C /usr/src/ Slave DR-> tar xvf keepalived-1.2.19.tar.gz -C /usr/src/ Master DR-> cd /usr/src/keepalived-1.2.19/ Slave DR-> cd /usr/src/keepalived-1.2.19/ Master DR-># ./configure --prefix=/usr/local/keepalived --with-kernel-dir=/usr/src/kernels/`uname -r`/ --with-kernel-version=2.6 --enable-snmp --enable-profile --enable-sha1 make ;make install Slave DR-># ./configure --prefix=/usr/local/keepalived --with-kernel-dir=/usr/src/kernels/`uname -r`/ --with-kernel-version=2.6 --enable-snmp --enable-profile --enable-sha1 # make ; make install --with-kernel-dir的参数是和LVS集成必须的编译参数,后面接的是内核源码目录;如果内核目录没有的话,就yum install kernel-devel -y 下面的步骤是主DR和备DR都要做的 cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/rc.d/init.d/ --拷贝服务脚本 cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/ --拷贝全局配置文件 mkdir /etc/keepalived cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/--拷贝主配置文件 cp /usr/local/keepalived/sbin/keepalived /usr/sbin/ --拷贝命令 /etc/init.d/keepalived restart --看服务是否可以启动,能启动表示OK 第二步:修改主备DR的配置文件 在配置前先把主DR和备DR的ipforward打开 # vim /etc/sysctl.conf net.ipv4.ip_forward = 1 # sysctl -p 主DR 配置文件 Master DR->vim /etc/keepalived/keepalived.conf global_defs { notification_email { root@master.cluster.com --email通知,可选,可以写上一个外部邮箱,这里随便写个本机的(保证本机的postfix是启动状态) } notification_email_from root@master.cluster.com --以哪个邮箱身份去发送 smtp_server 127.0.0.1 --邮件服务器IP smtp_connect_timeout 30 router_id LVS_DEVEL --同一个局域网内注意要唯一。用hostonly网段做实验的话保持默认就好了 } vrrp_instance VI_1 { --定义整个VRRP(virtual router reduntancy protocol)实例 state MASTER --主DR要为MASTER,并大写 interface eth0 --提供服务的网卡,在我这里是外网网卡 lvs_sync_daemon_interface eth0 --指定它为一个心跳网卡 virtual_router_id 51 --ID值,主DR和备DR要一致 ; 这里要特别注意;如果都在同一个网段,每个人的ID值请使用不同的,以免冲突(范围为1-255,不能超过这个范围) priority 100 --优先级,主DR要大于备DR advert_int 1 --主备同步的时间间隔 authentication { auth_type PASS --验证类型,还有一种验证类型为AH auth_pass 1111 --验证字符串 } virtual_ipaddress { --vip,多个分行写。我这里是NAT架构,所以有两个vip。但是不能都写在一个vrrp_instance里,否则这两个vip就都在eth0上产生,与我的架构不符 1.1.1.2/24 } } vrrp_instance VI_2 { --实例2 state MASTER interface eth1 --第二个服务网卡,也是我的内网 lvs_sync_daemon_interface eth1 --第二个心跳网卡 virtual_router_id 52 --换一个router_id priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 2.2.2.2/24 --这样写就实现了1.1.1.1这个VIP在eth0,2.2.2.2这个VIP在eth1 } } virtual_server 1.1.1.2 80 { --1.1.1.2为调度VIP,80端口 delay_loop 6 --健康检查时间间隔 lb_algo rr --调度算法 lb_kind NAT --NAT类型 nat_mask 255.255.255.0 protocol TCP --TCP协议 real_server 2.2.2.5 80 { --调度2.2.2.5这台real server 的80端口 weight 1 --权重 TCP_CHECK { --健康检查的方式为TCP端口连接 connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 --健康检查的连接端口为80 } } real_server 2.2.2.6 80 { weight 1 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } } -------------------------------------------- 备DR的配置文件 和主的几乎一样,只用修改两个地方 --因为我是双心跳,有两个vrrp_instance,所以两个实例都要改下面的两个地方 state BACKUP --state改为BACKUP,指定为备 priority 99 --优先级数字要小于你的主DR的数字 --如果你实验的备DR虚拟机是克隆的,可能网卡为(eth1和eth2),那么还需要把网卡也对应的改一下就可以了(eth0改成eth1,对应主DR的eth0;eth1改为eth2对应主DR的eth1) 第三步:配置real server 1,写上不同的主页,方便测试 2,/etc/init.d/httpd start 3,默认网关指向2.2.2.2 --也就是NAT架构内网的VIP 第四步:重启主DR和备DR的keepalived服务 /etc/init.d/keepalived restart 重启后 1,使用ip addr命令查看 主DR eth0是否获取到了1.1.1.2/24和eth1是否获取到了2.2.2.2/24这两个VIP --只能使用ip addr命令查看,使用ifconfig命令是查看不到的 最后在client elinks 1.1.1.2 发现调度成功,或者在主DR使用ipvsadm -ln 查看调度情况 2,停掉web1的httpd,在客户端elinks 1.1.1.2发现只调度web2,当启动web1后,又会调web1和web2,说明检康检查也OK 3, 在主DR上/etc/init.d/network stop (最好是由静态IP才好测试,或者是把keepalived服务停掉),停掉网络,备DR过几秒就能抢到两个vip,并且调度也OK --注意这里有一个问题:如果只把主DR上的一个网卡停掉,那么只有一个VIP会跳到备DR,就会造成主DR和备DR一人一个VIP的情况,那么整个架构也会出现问题(我们可以用脚本监控这两个网卡,如果一个挂掉,则把另一个也挂掉) --如果你的网卡都做了双网卡绑定,你就几乎可以不用考虑网卡坏掉的问题。 4,主DR上/etc/init.d/network start ,再次启动网络,过几秒又自动抢回两个vip,调度OK ------------------------------------------- 另一种healthcheck方式 下面只列出检查健康有关的配置,其它没列出来的和上面的一样 real_server 2.2.2.5 80 { weight 1 HTTP_GET { --健康检查的方式为http协议的get方式 url { path /test.html --会去检查real_server的家目录是否有test.html文件 digest b575527de5b4ba1881f1b14e50016eab --检查2.2.2.5上web家目录里的test.html的md5值,在2.2.2.5上由md5sum命令得出 } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 2.2.2.6 80 { weight 1 HTTP_GET { url { path /test.html digest 0dcdc06c7c61f6e9da0496b1872fc2d5 } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } } 用这种检查方式:会在后端的real server里看到检查日志 tail /var/log/httpd/access_log --可以看到每6秒就会检查一次 2.2.2.3 - - [29/Oct/2014:12:04:09 +0800] "GET /test.html HTTP/1.0" 200 - "-" "KeepAliveClient" 2.2.2.4 - - [29/Oct/2014:12:04:13 +0800] "GET /test.html HTTP/1.0" 200 - "-" "KeepAliveClient" 2.2.2.3 - - [29/Oct/2014:12:04:15 +0800] "GET /test.html HTTP/1.0" 200 - "-" "KeepAliveClient" 2.2.2.4 - - [29/Oct/2014:12:04:19 +0800] "GET /test.html HTTP/1.0" 200 - "-" "KeepAliveClient" 2.2.2.3 - - [29/Oct/2014:12:04:21 +0800] "GET /test.html HTTP/1.0" 200 - "-" "KeepAliveClient" 2.2.2.4 - - [29/Oct/2014:12:04:25 +0800] "GET /test.html HTTP/1.0" 200 - "-" "KeepAliveClient" 2.2.2.3 - - [29/Oct/2014:12:04:27 +0800] "GET /test.html HTTP/1.0" 200 - "-" "KeepAliveClient" --大量的这种检查日志会造成日志分析麻烦,并且日志体积很大。如何解决? 还有一个问题,后面web日志里得到的不是客户访问的外网IP,而是架构前端服务器的内网ip,那么做日志分析的话就无法得到真实的客户端访问IP,如何解决? # vim /etc/httpd/conf/httpd.conf SetEnvIf Request_URI "^/test\.html$" dontlog --加上这一句 CustomLog logs/access_log combined env=!dontlog --在你希望不记录与test.html有关的日志后面加上env=!dontlog /etc/init.d/httpd restart 另一个方法:做sed加crontab做脚本定期清除就可以了 sed -i '/test.html/d' /var/log/httpd/access_log ================================================================ piranha 水虎鱼 食人鱼 图形化配置lvs+ha的软件 NAT架构 架构图与上面架构图一样,只是把keepalived 换成 piranha来做 client | | | VIP eth0:0 1.1.1.2 心跳 1.1.1.3 eth0---------eth0 1.1.1.4 master DR slave DR 2.2.2.3 eth1---------eth1 2.2.2.4 心跳 VIP eth1:0 2.2.2.2 | | | |-------------------------------| web1 web2 2.2.2.5 2.2.2.6 第一步: 安装前准备: 接着上面的实验,继续做 1,先把上面的主DR和备DR的keepalived关闭 /etc/init.d/keepalived stop 2,在主备DR上安装piranha软件 yum install piranha -y 3,先在主DR上进行配置,配置好后,后面再直接SCP给备DR cp /etc/sysconfig/ha/conf/httpd.conf /etc/httpd/conf/ --拷贝piranha配置文件覆盖httpd的配置文件 /etc/init.d/httpd restart --启动httpd,(注意如果rhel6上启动报权限拒绝,记得关闭selinux) lsof -i:3636 --查看到有3636端口 COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME httpd 13252 root 3u IPv6 84841 TCP *:opscenter (LISTEN) httpd 13254 piranha 3u IPv6 84841 TCP *:opscenter (LISTEN) /usr/sbin/piranha-passwd --设置登录密码 New Password: Verify: Adding password for user piranha 随便找一台可以访问,使用浏览器 访问主DR的3636端口 http://主DR的IP:3636/ 使用用户名piranha,密码为刚才设置的密码登陆 ---------------------------------- --上面httpd.conf里配置的权限是默认允许所有的人都可以访问,所以随便找一台能连的客户端就可以配置。你可以限制只有特定的机器才能访问 可以在下面这个目录标签下修改 Order deny,allow Allow from all --默认允许所有 可以修改为 order deny,allow deny from all allow from 1.1.1.3 --拒绝所有,只允许1.1.1.3 ------------------------------------------ 配置过程见笔记目录里的截图(在笔记目录下/arch/png) # cat /etc/sysconfig/ha/lvs.cf serial_no = 16 primary = 1.1.1.3 primary_private = 2.2.2.3 service = lvs backup_active = 1 backup = 1.1.1.4 backup_private = 2.2.2.4 heartbeat = 1 heartbeat_port = 539 keepalive = 6 deadtime = 18 network = nat nat_router = 2.2.2.2 eth1:0 nat_nmask = 255.255.255.0 debug_level = NONE monitor_links = 1 syncdaemon = 0 virtual lvs_http { active = 1 address = 1.1.1.2 eth0:0 sorry_server = 127.0.0.1 vip_nmask = 255.255.255.0 port = 80 send = "GET / HTTP/1.0\r\n\r\n" expect = "HTTP" use_regex = 0 load_monitor = none scheduler = rr protocol = tcp timeout = 6 reentry = 15 quiesce_server = 1 server web1 { address = 2.2.2.5 active = 1 port = 80 weight = 1 } server web2 { address = 2.2.2.6 active = 1 port = 80 weight = 1 } } 第二步: 配置备DR 直接把主DR的lvs.conf配置文件SCP到备DR scp /etc/sysconfig/ha/lvs.cf 1.1.1.4:/etc/sysconfig/ha/ --如果备DR也是使用的克隆的虚拟机,两个网卡为eth1和eth2的话,那么拷过来配置文件后,vim去打开它,把nat_router = 2.2.2.2 eth1:0改成nat_router = 2.2.2.2 eth2:0;把address = 1.1.1.2 eth0:0改成address = 1.1.1.2 eth1:0) 第三步:主备DR都启动pulse服务 /etc/init.d/pulse start 启动后,就可以使用ifconfig在主DR上 看到 eth0:0 1.1.1.1 eth1:0 2.2.2.2 第四步: 因为我这里使用上面原有的架构,所以web1,web2网关仍然还是指的2.2.2.2 直接使用client测试OK 1,测试 master DR 上service network stop,然后发现两个vip都在slave DR, 然后service network start,就又回来了(注意都配置静态IP来测试,否则可能会出问题) 2,断掉master DR上其中一个网卡(注意:在虚拟机图形配置里关闭掉或者ifconfig eth0 down掉)。会发现两个VIP都会切换过去,再打开这个master DR断掉的网卡(发现两个VIP不能抢回来),再断掉slave DR的一个网卡,两个VIP也会切换回master DR.因为我在Monitor NIC links for failures这项打了勾。 3,但这里有些问题:就是切到slave DR的VIP在master DR启动OK后也不会自动回来,需要停slave DR上的pulse服务,或断它的网卡才会回到master DR; ======================================================================= 使用keepalived实现HA+LVS-DR架构 client 3.3.3.3 | | | eth0 3.3.3.1 [router或firewall] <-------------------- eth1 1.1.1.1 | | | | | | | VIP eth0:0 1.1.1.2 | | 心跳 | 1.1.1.3 eth0---------eth0 1.1.1.4 | master DR slave DR | | 2.2.2.3 eth1----------eth1 2.2.2.4 | | | | | | | |-------------------------------| | web1 web2 | 1.1.1.5 1.1.1.6 ---------------> 网关指向 lo:0 1.1.1.2/255.255.255.255 配置firewall 1,ipvsadm 确认没有打开 2,httpd 也就是80端口没有打开 3,/etc/sysctl.conf --打开IP_FORWARD 4,使用防火墙做DNAT,把对firewall的80请求DNAT给Director iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j DNAT --to 1.1.1.2 还做一个SNAT回来 iptables -t nat -A POSTROUTING -p tcp --dport 80 -o eth1 -j SNAT --to-source 1.1.1.1 第二大步:在主DR上配置,这里选用keepalived # /etc/init.d/pulse stop --先在主DR和备DR上确认把piranha关闭 # vim /etc/keepalived/keepalived.conf global_defs { router_id LVS_DEVEL } vrrp_instance VI_1 { state MASTER interface eth0 lvs_sync_daemon_interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 1.1.1.2/24 } } vrrp_instance VI_2 { state MASTER interface eth1 lvs_sync_daemon_interface eth1 virtual_router_id 52 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { --因为是DR架构,只有一个VIP,这个VIP为空 } } virtual_server 1.1.1.2 80 { delay_loop 6 lb_algo rr lb_kind DR --把NAT换成DR nat_mask 255.255.255.0 protocol TCP real_server 1.1.1.5 80 { --因为换成DR架构,web网段与LVS调度是同网段,所以IP也要改成web1的新IP weight 1 HTTP_GET { url { path /test.html digest d41d8cd98f00b204e9800998ecf8427e } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 1.1.1.6 80 { --改成web2的新IP weight 1 HTTP_GET { url { path /test.html digest 56e68bb020b9ec9499897f8146f30c37 } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } } 第三大步:把配置文件由master DR拷到slave DR # scp /etc/keepalived/keepalived.conf 1.1.1.4:/etc/keepalived/ 拷过去后,就把下面两句在slave DR上改一下 state BACKUP priority 99 --如果你实验的备DR虚拟机是克隆的,那么把eth0对应的改成eth1就可以 第四大步; 配置real servers 1,安装httpd监听80端口,并使用两个不同的主页方便后面的测试 2,ifconfig lo:0 1.1.1.2 netmask 255.255.255.255 --注意掩码为4个255 3, 真实服务器把默认路由指向firewall同物理网段的IP 把网关指向1.1.1.1(这个网关可做也可不做,因为前面做了SNAT,那么回去时,sip:1.1.1.5 dip:1.1.1.1,就是同网段,可以直接回去) 4.# vim /etc/sysctl.conf --这步一定要做,如果不做,可能会出现firewall找1.1.1.2这个VIP时,有1.1.1.2IP的都会回应arp广播包(包括web1和web2,因为它们也有1.1.1.2的IP)(你可以在firewall上使用arp -d 1.1.1.2命令后,再用客户端访问elinks -dump 3.3.3.1测试,如果不改这几个内核参数,会可能出现只访问其中一个web而不会调度的情况) net.ipv4.conf.lo.arp_ignore = 1 net.ipv4.conf.lo.arp_announce = 2 net.ipv4.conf.all.arp_ignore = 1 net.ipv4.conf.all.arp_announce = 2 # sysctl -p使它生效 5,在主DR和备DR上都绑定web1和web2的物理地址 (这一步在这个架构中可以不用做,因为web1和web2虚拟了lo:0 1.1.1.2/32后,不会造成主DR和备DR与web1,web2不通的情况,因为主DR和备DR有心跳线路的IP1.1.1.3和1.1.1.4,它们可以与web1,web2通迅,也就是说可以得到web1和web2的MAC地址) # arp -s 1.1.1.5 1.1.1.5的MAC地址 # arp -s 1.1.1.6 1.1.1.6的MAC地址 第五大步: 两边/etc/init.d/keepalived restart 第六大步: 测试:在客户端上elinks -dump 3.3.3.1, 成功 ============================================================== 把上面的keepalived关闭,换成piranha web配置的话,相对于前面做的NAT架构来说,只需要修改三个地方 1,在globel setting里由NAT架构改成DR 2,把web1的IP改成新的1.1.1.5 3,把web2的IP改成新的1.1.1.6 配置文件如下 # cat /etc/sysconfig/ha/lvs.cf serial_no = 52 primary = 1.1.1.3 primary_private = 2.2.2.3 service = lvs backup_active = 1 backup = 1.1.1.4 backup_private = 2.2.2.4 heartbeat = 1 heartbeat_port = 539 keepalive = 6 deadtime = 18 network = direct nat_nmask = 255.255.255.0 debug_level = NONE monitor_links = 1 syncdaemon = 1 syncd_iface = eth0 syncd_id = 51 virtual lvs_http { active = 1 address = 1.1.1.2 eth0:0 sorry_server = 127.0.0.1 vip_nmask = 255.255.255.0 port = 80 send = "GET / HTTP/1.0\r\n\r\n" expect = "HTTP" use_regex = 0 load_monitor = none scheduler = rr protocol = tcp timeout = 6 reentry = 15 quiesce_server = 1 server web1 { address = 1.1.1.5 active = 1 weight = 1 } server web2 { address = 1.1.1.6 active = 1 weight = 1 } }