Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6961098
  • 博文数量: 637
  • 博客积分: 10265
  • 博客等级: 上将
  • 技术积分: 6165
  • 用 户 组: 普通用户
  • 注册时间: 2004-12-12 22:00
文章分类

全部博文(637)

文章存档

2011年(1)

2010年(1)

2009年(3)

2008年(12)

2007年(44)

2006年(156)

2005年(419)

2004年(1)

分类: LINUX

2005-03-20 23:23:30

LVS+Heartbeat+Ldirectord在Red Hat9.0下的实现

陆 飞(、)
杭州市地方税务局西湖征收管理局
2003年9月

随着Internet技术的迅猛发展,网络技术、性能的不断提高,高可伸缩性、高可用性、可管理性、价格有效性的网络服务技术将 成为网络服务技术的主导。各种平台下的技术方案应运而生。本文试图以一篇完整的理论+实践性的文字来介绍如何在优秀的开源操作系统Linux下创建低成 本、高性能、高可用的服务集群系统。文中所使用的系统和软件包均为最新版本。希望通过对本文的阅读能使你对如何创建Linux下的集群系统有所帮助。

Linux下的集群系统通常可以分为三类:

  1. HA容错集群 (Fail-over Cluster)
    高可用性集群(High available)用于不可间断服务的环境下。提供冗余的容错备份,在主节点失效后,能够立即接管相关资源及继续提供相应服务。
  2. 负载均衡集群 (Load Balancing Cluster)
    在应用服务的高负载情况下运用该技术,由多台节点提供高可伸缩的,高负载的服务器组。以保证对外提供良好的服务响应。
  3. HPC高性能计算机集群 (High Performance Computing)
    概念并不完全统一,有一定争论,应该理解为并行系统,主要用于科学计算。

本文所要介绍的是前两类集群的一个完美的组合。

1.1. Linux Virtual Server项目

在1998年5月,由章文嵩博士成立了Linux Virtual Server的自由软件项目,进行Linux服务器集群的开发工作。同时,Linux Virtual Server项目也是国内最早出现的自由软件项目之一。该项目针对高可伸缩、高可用网络服务的需求,给出了基于IP层和基于内容请求分发的负载平衡调度解 决方法,它通过前端一个负载调度器(Load Balancer)无缝地将网络请求调度到真实服务器上,从而使得服务器集群的结构对客户是透明的,客户访问集群系统提供的网络服务就像访问一台高性能、 高可用的服务器一样。客户程序不受服务器集群的影响不需作任何修改。系统的伸缩性通过在服务机群中透明地加入和删除一个节点来达到,通过检测节点或服务进 程故障和正确地重置系统达到高可用性。并在Linux内核中实现了这些方法,将一组服务器构成一个实现可伸缩的、高可用网络服务的虚拟服务器。

虚拟服务器的体系结构如图2所示。


图2:虚拟服务器的结构

1.1.1. LVS的核心软件IPVS

在调度器的实现技术中,IP负载均衡技术是效率最高的。在已有的IP负载均衡技术中有通过网络地址转换(Network Address Translation)VS/NAT技术的基础上,IPVS软件实现了三种IP负载均衡技术:

1)Virtual Server via Network Address Translation(VS/NAT) 网络地址转换 (如图1)
2)Virtual Server via IP Tunneling(VS/TUN) 隧道技术 (如图2)
3)Virtual Server via Direct Routing(VS/DR) 直接路由 (如图3)

针对不同的网络服务需求和服务器配置,IPVS调度器实现了如下十种负载调度算法:

  1. 轮叫(Round Robin)
  2. 加权轮叫(Weighted Round Robin)
  3. 最少链接(Least Connections)
  4. 加权最少链接(Weighted Least Connections)
  5. 基于局部性的最少链接(Locality-Based Least Connections)
  6. 带复制的基于局部性最少链接(Locality-Based Least Connections with Replication)
  7. 目标地址散列(Destination Hashing )
  8. 源地址散列(Source Hashing)
  9. 最短期望延迟(Shortest Expected Delay)(新增加调度算法)
  10. 无须队列等待(Never Queue)(新增加调度算法)

其中9-10是最新1.09版IPVS软件包中新增的调度算法,这十种调度算法将会在后面的ipvsadm配置文件中用到,通常用英文单词的第一个字母的缩写来表示。例如:轮叫(Round Robin)表示为rr。

三种IP负载均衡技术的优缺点比较


VS/NATVS/TUNVS/DR
服务器(OS)任意支持隧道多数(支持Non-arp )
服务器网络私有网络局域网/广域网局域网
服务器数目(100M网络)10~20100多(100)
服务器网关负载均衡器自己的路由自己的路由
效率一般最高

三种IP负载均衡技术中特别是后两种技术VS/TUN,VS/DR极大地提高系统的伸缩性,它们的相关技术原理不是本文讨论的重点,若需了解详细内容,请参看章文嵩博士的相关撰文。


图1


图2


图3

1.2. High Availability of LVS

较为成熟的方案有mon+heartbeat+fake+coda 和ldirectord+heartbeat 方案,本文我们采用的是ldirectord+heartbeat 方案。

1.2.1. Heartbeat

Linux-HA 项目开始于 1998 年,是 Linux-HA HOWTO(Haranld Milz 著)的产物。该项目目前由 Alan Robertson 领导,许多其他代码提供者也参与其中。1.0.3版本是2003年6月发布的最新稳定版本。

Heartbeat 通过通信介质(通常是串行设备和以太网)监控节点的"健康"状况。最好有多个冗余介质,以便我们既可以使用串行线又可以使用以太网链接。每个节点运行一个 守护程序进程(称为"心跳")。主守护程序派生出读和写每个心跳介质的子进程,以及状态进程。当检测到某个节点发生故障时,Heartbeat 运行 shell 脚本来启动(或停止)辅助节点上的服务。按照设计,这些脚本使用与系统 init 脚本(通常位于 /etc/init.d 中)相同的语法。缺省脚本是为文件系统、Web 服务器和虚拟 IP 故障转移提供的。

1.2.2. Ldirectord

"ldirectord"(Linux Director Daemon)是Jacob Rief编程实现的一个独立进程,以实现对服务和物理服务器的监测,广泛地用于http和https等服务, Ldirectord与mon相比,优点如下:

  1. ldirectord是专门为LVS 监控而编写的。
  2. ldirectored可以方便地被heartbeat管理启动和停止。
  3. 它能从heartbeat的配置文件/etc/ha.d/xxx.cf中读取所有有关IPVS路由表配置的信息。当 ldirectord 运行后,IPVS路由表将被适当地配置。你也可以将不同的虚拟服务器配置保存在不同的配置文件里, 所以你可以单独修改某种服务的参数而不用停止其它的服务
  4. 另外,ldirectord安装简便,可以手工地启动和停止。你可以在没有备份负载均衡器的LVS集群上使用。

1.2.3. ldirectord+heartbeat的绝妙组合

ldirectord+heartbeat方案前端负载调度器采用双机热备份方式,双机均安装双网卡,一个网卡用于连接集群系统,另一个作为冗余心 跳线路连接双机。采用串口线 + 以太网口做为冗余心跳线路,以确保双机热备份的可靠性,消除由于主负载调度器或心跳线故障带来的集群单点故障。

在主负载调度器及备份负载调度器同时安装ldirectord及heartbeat,并同时运行Heartbeat,相互监视"健康"状况,一旦备 份负载调度器监测到主负载调度器发生故障,备份服务器通过运行shell脚本来启动备份调度器上服务来完成虚拟 IP 故障转移,通过ipvsadm启动LVS及ldirectord,完成负载调度器的整体接管。一旦主负载调度器恢复正常工作,备份负载将通过脚本停掉备份 负载调度器上的LVS及ldirectord,同时完成虚拟 IP 故障转移,主负载调度器重新恢复接管LVS及ldirectord监控服务。这样负载调度器就完成了一个标准的接管及恢复过程。

该方案结构清晰明了,安装简便,并且ldirectord是专门为LVS所开发,针对性强,无缝衔接,配合默契,堪称绝妙组合。

2.1. 实现目标:

实现以常用、效率最高的LVS-DR IP负载技术为基础,以高可用性(HA)+ 高性能 + 高性能/价格比 + 高可伸缩性为最终目的。负载均衡器采用HA技术构架,采用Heartbeat软件包,heartbeat采用串口、网络口冗余线路,保证24X7不间断运 行。结构如图:

Setup LVS using LVS-DR forwarding



________
| |
| client |
|________|
CIP= SGW =192.168.7.254/24 (eth0)
|
|
eth1 __________ |
192.168.0.1 | director | |
--------| primiary |---| DIP=192.168.7.9/24 (eth0)
| |__________| |
| ttyS0| |
|heartbeat | |
|backup | | VIP=192.168.7.110/32 (eth0:0)*
| ttyS0| |
| _____|____ |
| | director | |
--------| backup |---| DIP=192.168.7.10/24 (eth0)
eth1 |__________| |
192.168.0.2 |
|
|
|
|
-----------------------------------
| |
| |
RIP=192.168.7.11/24 (eth0) RIP=192.168.7.12/24 (eth0)
VIP=192.168.7.110/32 (lo:0) VIP=192.168.7.110/32 (lo:0)
____________ ____________
| | | |
| realserver | ----------- | realserver |
|____________| |____________|



2.2. 设备要求:

因为负载均衡器和真实服务器节点均有软硬件冗余保障,所以硬件设备可以根据具体资金情况及提供服务规模而定。当然最好采用支持RAID,SCSI, 内存ECC校验,热插拔等技术的专用服务器,以提供稳定高效的服务。对于非关键业务服务,也可以考虑采用最新支持IDE RAID(0,1,0+1,1.5,5)的服务器,可以获得一个良好的性能/价格比。当然,如果你是一个对硬件技术细节非常熟悉,说话又有分量,对自己非 常有信心,敢冒风险,崇尚节约、实用性的人,那么DIY一组高性价比的服务器集群,也是一件非常有意义而且充满乐趣的工作。

2.3.原始软件环境:

Red Hat 9.0 完全安装
Red Hat 9.0 (kernel-2.4.20-8 ) gcc -3.2.2-5

如果你使用的是Red Hat 8 ,那么你很幸运。Red Hat 8 (kernel-2.4.18-14)已经预先打了ipvs的补丁,在预安装的内核中已将ipvs编译成模块,可以通过检查 /lib/modules/2.4.18-14/kernel/net/ipv4/ipvs 是否存在来判断。可以直接安装ipvsadm。从Red Hat 9 (kernel-2.4.20-8),Red Hat 取消了ipvs的补丁及预编译ipvs为模块的内核,且Red Hat 9 自带的kernel-2.4.20-8的内核无法通过ipvs补丁linux-2.4.20-ipvs-1.0.9 .patch.gz的编译,至少在我的两台P4的机器上都没有通过编译。标准内核linux-2.4.20.tar.gz则可以通过编译。所以我们将采用 上的标准内核kernel-2.4.20.tar.gz来构造我们的集群系统。

2.4.需下载软件包:

# Linux kernel

# ipvs patch

# ipvs tar ball

# hidden patch(已经包括在ipvs-1.0.9.tar.gz,可不用下载)
(解决arp 问题 for LVS-DR/LVS-Tun)

# ipvsadm (已包含在ipvs-1.0.9.tar.gz包中, 可不用下载)

# Ldirectord

# heartbeat





2.5. 安装要求:

2.5.1 Director:

  • 内核打non-arp的补丁hidden-2.4.20pre10-1.diff (解决arp problem for LVS-DR/LVS-Tun,虽然在Directors上运行时并不需要,但硬件环境如果和Realserver类似,内核可以直接放到 RealServer上运行,不用再为realServer重新编译内核,当然也可不打该补丁。)
  • 内核打ipvs的补丁linux-2.4.20-ipvs-1.0.9.patch.gz,重新编译新内核。
  • 运行新内核后编译安装ipvsadm。(LVS-NAT (network address translation); LVS-DR (direct routing) and LVS-Tun (tunneling). 真实服务器 realserver/service 的转发方式由ipvsadm来设置。)

2.5.2 RealServes: (在LVS-NAT方式下,不需要打任何补丁)

内核打arp的补丁hidden-2.4.20pre10-1.diff (arp problem for LVS-DR/LVS-Tun)编译新内核。

  • 解决Non-arp problem
  • 设置缺省网关(gw)
    • LVS-NAT: director(DIP)
    • LVS-DR, LVS-Tun: 对外路由 (不是director的IP).

如果你不知道你的内核源代码是否已经预打过ipvs的补丁, 可以询问你的Linux发行版的制造商或查看相关ipvs 文件,文件名类似于 /usr/src/linux-2.4/net/ipv4/ip_vs_*.c。

2.6. 安装步骤:

2.6.1 Director或RealServer上内核的安装:


export D=/tmp/download
mkdir $D
cd $D
wget http:///pub/linux/kernel/v2.4/linux-2.4.20.tar.gz
wget .patch.gz
wget

tar zxvf linux-2.4.20.tar.gz
tar zxvf ipvs-1.0.9.tar.gz
gunzip linux-2.4.20-ipvs-1.0.9.patch.gz
mv linux-2.4.20 /usr/src/linux-2.4.20
cd /usr/src
rm -f linux-2.4
ln -s linux-2.4.20 linux-2.4
cd linux-2.4
patch -p1 < $D/ipvs-1.0.9/contrib/patches/hidden-2.4.20pre10-1.diff (arp for LVS-DR/LVS-Tun)
patch -p1 < $D/linux-2.4.20-ipvs-1.0.9.patch (仅在编译Director内核时打补丁)
make mrproper
cp /boot/config-2.4.20-8 .config (使用Red Hat 9自带的config内核配置文件或使用/usr/src/linux-2.4.7-10/configs下的配置文件)

make menuconfig(参照相关ipvs及内核配置)
或在图形界面运行: make xconfig


相关网络内核选项:

相关LVS内核选项:



make dep
make clean
make bzImage
make modules
make modules_install
cp arch/i386/boot/bzImage /boot/ vmlinuz-2.4.20-lvs (rs)
cp System.map /boot/System.map.2.4.20-lvs (rs)
cp vmlinux /boot/vmlinux-2.4.20-lvs (rs)
cd /boot
rm -f System map
ln -s System.map.2.4.20-lvs (rs) System.map

vi /boot/grub/grub.conf:
title 2.4.20-lvs
root (hd0,0)
kernel /boot/vmlinuz-2.4.20-lvs (rs) ro root=/dev/xxx




如果要安装该内核在其它机器上:


tar czf linux-2.4.20-dir.tgz /usr/src/linux-2.4.20/

在其它机器上解压tar zxvf linux-2.4.20-dir.tgz 放置到/usr/src
rm -f linux-2.4
ln -s linux-2.4.20 linux-2.4
cd linux-2.4
make modules_install
cp arch/i386/boot/bzImage /boot/ vmlinuz-2.4.20-lvs (rs)
cp System.map /boot/System.map.2.4.20-lvs (rs)
cd /boot
rm -f System map
ln -s System.map.2.4.20-lvs (rs) System.map

vi /boot/grub/grub.conf:
title 2.4.20-lvs
root (hd0,0)
kernel /boot/vmlinuz-2.4.20-lvs (rs) ro root=/dev/xxx

2.6.2 Director上ipvsadm 的安装:

用打过ipvs和hidden(for LVS-DR/LVS-Tun)补丁的新内核启动linux


cd / tmp/download/ipvs-1.0.9/ipvs/ipvsadm
make install

检查ipvsadm 探测到内核的ipvs的补丁可以运行


ipvsadm

如果成功你会看到类似于如下内容:


director: /usr/src# ipvsadm
IP Virtual Server version 0.2.7 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn


说明安装成功

运行lsmod | grep ip_vs 可以看到ip_vs模块已经被插入内核运行。

2.6.3. 运行脚本( Run Scripts )

以下以最常用的LVS-DR模式来介绍相关的脚本设置

( 以Telnet服务, 轮叫(rr)策略为例 )

2.6.3.1 Director上:


#!/bin/bash
#---------------mini-rc.lvs_dr-director------------------------
#set ip_forward OFF for vs-dr director (1 on, 0 off)
cat /proc/sys/net/ipv4/ip_forward
echo 0 >/proc/sys/net/ipv4/ip_forward

#director is not gw for realservers: leave icmp redirects on
echo 'setting icmp redirects (1 on, 0 off) '
echo 1 >/proc/sys/net/ipv4/conf/all/send_redirects
cat /proc/sys/net/ipv4/conf/all/send_redirects
echo 1 >/proc/sys/net/ipv4/conf/default/send_redirects
cat /proc/sys/net/ipv4/conf/default/send_redirects
echo 1 >/proc/sys/net/ipv4/conf/eth0/send_redirects
cat /proc/sys/net/ipv4/conf/eth0/send_redirects

#add ethernet device and routing for VIP 192.168.7.110
#if use backup director ,pay any attention about bellow
/sbin/ifconfig eth0:0 192.168.7.110 broadcast 192.168.7.110 netmask 255.255.255.255 up
/sbin/route add -host 192.168.7.110 dev eth0:0
#listing ifconfig info for VIP 192.168.7.110
/sbin/ifconfig eth0:0

#check VIP 192.168.7.110 is reachable from self (director)
/bin/ping -c 1 192.168.7.110
#listing routing info for VIP 192.168.7.110
/bin/netstat -rn

#setup_ipvsadm_table
#clear ipvsadm table
/sbin/ipvsadm -C
#installing LVS services with ipvsadm
#add telnet to VIP with round robin scheduling
/sbin/ipvsadm -A -t 192.168.7.110:telnet -s rr

#forward telnet to realserver using direct routing with weight 1
/sbin/ipvsadm -a -t 192.168.7.110:telnet -r 192.168.7.11 -g -w 1
#check realserver reachable from director
ping -c 1 192.168.7.11

#forward telnet to realserver using direct routing with weight 1
/sbin/ipvsadm -a -t 192.168.7.110:telnet -r 192.168.7.12 -g -w 1
#check realserver reachable from director
ping -c 1 192.168.7.12

#displaying ipvsadm settings
/sbin/ipvsadm

#not installing a default gw for LVS_TYPE vs-dr
#---------------mini-rc.lvs_dr-director------------------------

该段运行脚本对于熟悉Linux网络配置的读者来说应该很容易理解。由于LVS是通过对标准内核打补丁,在内核级提供支持,所以在LVS-DR模式 下,首先是进行内核的相关设置。要关闭标准内核下的ip_forward转发方式,即置为0。同时因为LVS-DR模式下,集群的网关是外部网关,而不是 负载均衡器。所以要打开icmp包的重定向设置send_redirects 置为1。接着就是绑定集群的虚拟服务器的IP地址,并添加一条到该IP地址的主机路由。然后对该虚拟IP做一些必要的自我检测,同时列出路由表。最后是有 关ipvasdm的设置,首先清空ipvasdm表,然后添加需要提供负载均衡的服务及调度策略,这里例举的是telnet服务,也可以直接使用端口号, 调度策略为轮叫(rr)策略。最后添加转发到真实服务器的直接路由,如果有多台RealServer或需要提供多种服务的负载均衡,依次添加。再做一些到 RealServer的网络测试(也可不要),最后显示ipvasdm所有的设置信息。

注意:

ipvs-1.0.9.tar.gz中包含的ipvsadm是1.21版,安装后在/etc/rc.d/init.d/目录下自动生成了标准的 init服务脚本,如果你的Director没有安装备份服务器,你可以通过服务管理工具让它在相应的运行级里自动运行,如果Director是HA系 统,则由heartbeat控制运行。

另外该服务脚本提供了配置保存功能。配置文件为:/etc/sysconfig/ipvsadm 你必须手工建立。然后在其中输入规则和策略:

例如:


-A -t 192.168.7.110:telnet -s rr
-A -t 192.168.7.110:http -s rr
-a -t 192.168.7.110:telnet -r 192.168.7.11 -g -w 1
-a -t 192.168.7.110:http -r 192.168.7.11 -g -w 1

然后存盘。

或直接运行:


/sbin/ipvsadm -A -t 192.168.7.110:telnet -s rr
/sbin/ipvsadm -A -t 192.168.7.110:http - rr
/sbin/ipvsadm -a -t 192.168.7.110:telnet -r 192.168.7.11 -g -w 1
/sbin/ipvsadm -a -t 192.168.7.110:http -r 192.168.7.11 -g -w 1


然后运行:/etc/rc.d/init.d/ipvsadm save

就可以保存当前配置到/etc/sysconfig/ipvsadm文件中。

在具有HA系统的Director上,ipvsadm可以方便地被Heartbeat管理-启动、停止。Director上的VIP(虚拟)服务器地址由Heartbeat负责设置和切换。

做法如下:

在Heartbeat的配置文件haresources中加类似入如下一行:

linuxha1 IPaddr::192.168.7.110/24/192.168.7.255 ipvsadm ldirectord::www ldirectord::mail

2.6.3.2. RealServers上:


#!/bin/bash
#----------mini-rc.lvs_dr-realserver------------------
#installing default gw 192.168.7.254 for vs-dr
/sbin/route add default gw 192.168.7.254
#showing routing table
/bin/netstat -rn
#checking if DEFAULT_GW 192.168.1.254 is reachable
ping -c 1 192.168.7.254

#set_realserver_ip_forwarding to OFF (1 on, 0 off).
echo 0 >/proc/sys/net/ipv4/ip_forward
cat /proc/sys/net/ipv4/ip_forward

#looking for DIP 192.168.7.9
ping -c 1 192.168.7.9

#looking for VIP (will be on director)
ping -c 1 192.168.7.110

#install_realserver_vip
/sbin/ifconfig lo:0 192.168.7.110 broadcast 192.168.7.110 netmask 255.255.255.255 up
#ifconfig output
/sbin/ifconfig lo:0
#installing route for VIP 192.168.1.110 on device lo:0
/sbin/route add -host 192.168.7.110 dev lo:0
#listing routing info for VIP 192.168.7.110
/bin/netstat -rn

#hiding interface lo:110, will not arp
echo 1 >/proc/sys/net/ipv4/conf/all/hidden
cat /proc/sys/net/ipv4/conf/all/hidden
echo 1 >/proc/sys/net/ipv4/conf/lo/hidden
cat /proc/sys/net/ipv4/conf/lo/hidden

#----------mini-rc.lvs_dr-realserver------------------


该段脚本和上面的脚本比较类似,相信不用再多做介绍了。需要注意的是:LVS-DR模式下,缺省网关的设置。集群的网关是外部网关,而不是负载均衡 器。还有就是RealServer上绑定的VIP地址的设备lo:0。另外不要忘了开启not arp补丁的设置开关。相信你已经很清楚了。

你也可以把以上脚本改写成符合init语法的标准脚本,放到/etc/rc.d/init.d/下面运行,或直接加到/etc/init.d/rc.local下运行。

改写为标准init语法脚本如下:



#!/bin/bash
#
# hidden This shell script takes care of starting and stopping
# the ipvs-hidden subsystem (hiddend).
#
# chkconfig: 2345 78 12
# description: ipvs-hidden
# processname: hiddend

prog="hidden"

start(){

echo 0 >/proc/sys/net/ipv4/ip_forward
/sbin/ifconfig lo:0 192.168.7.110 broadcast 192.168.7.110 netmask 255.255.255.255 up
# installing route for VIP 192.168.1.110 on device lo:0
/sbin/route add -host 192.168.7.110 dev lo:0
# listing routing info for VIP 192.168.7.110
/bin/netstat -rn
# hiding interface lo:0, will not arp
# echo 1 >/proc/sys/net/ipv4/conf/all/hidden
echo 1 >/proc/sys/net/ipv4/conf/lo/hidden

}

stop(){

echo 1 >/proc/sys/net/ipv4/ip_forward
/sbin/ifconfig lo:0 192.168.7.110 broadcast 192.168.7.110 netmask 255.255.255.255 down
/sbin/route del -host 192.168.7.110 dev lo:0
# echo 0 >/proc/sys/net/ipv4/conf/all/hidden
echo 0 >/proc/sys/net/ipv4/conf/lo/hidden
}

restart(){
stop
start
}

condrestart(){
[ -e /var/lock/subsys/hiddend ] && restart || :
}

# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo $"Usage: $0 {start|stop|restart}"
exit 1
esac

exit $?

然后:


cp rc.lvs /etc/rc.d/init.d/hiddend
chmod 755 /etc/rc.d/init/d/hiddend
chkconfig - -add hiddend


阅读(1670) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~