`
tangay
  • 浏览: 94030 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

平民LVS_DR+Keepalived攻略(包含UDP服务)

阅读更多

系统环境: 
    CentOS 5.5 内核[2.6.18-194.el5]

平台结构:
    2台负载均衡器 ——
        LVS1: 172.19.1.13
        LVS2: 172.19.1.14
    虚拟IP(VIP,漂移地址)——
        172.19.1.19
    群集节点(RIP,真实服务器)——
        RealServer1: 172.19.1.15
        RealServer2:172.19.1.16

    提供服务:

        apache2(tcp 80)

        turnserver(udp 3478)

 

    每台host上iptables功能都打开

 

   公网IP地址: 61.147.xxx.xxx

 

   公网IP和虚拟IP地址会经过NAT转化。外部访问61.147.xxx.xxx会被NAT转换到172.19.1.19,同理172.19.1.19往外发数据包,源地址也会被设置为61.147.xxx.xxx。

 

 

1. 在LVS1和LVS2上安装ipvsadm,由于lvs已被继承在linux内核中,所以只需安装ipvsadm就可以了。不建议用源码make;make install 安装,会有莫名其妙的错误报出。直接:

 

yum install ipvsadm

 

2. 在LVS1和LVS2上安装keepalived. 步骤如下:

 

wget http://www.keepalived.org/software/keepalived-1.2.2.tar.gz

 

tar -xvf keepalived-1.2.2.tar.gz

 

cd keepalived-1.2.2/

 

./configure --prefix=/usr/local/keepalived --with-kernel-dir=/usr/src/kernels/2.6.18-194.el5-i686

 

注: 如果你/usr/src/kernels下没有2.6.18-194.el5-i686,你需要安装内核源码,安装很简单,运行

yum install kernel-devel

 

configure会产生以下效果:

 

Keepalived configuration
------------------------
Keepalived version       : 1.2.2
Compiler                 : gcc
Compiler flags           : -g -O2 -DETHERTYPE_IPV6=0x86dd
Extra Lib                : -lpopt -lssl -lcrypto
Use IPVS Framework       : Yes
IPVS sync daemon support : Yes
IPVS use libnl           : No
Use VRRP Framework       : Yes
Use Debug flags          : No

 

注意:

 

Use IPVS Framework       : Yes
IPVS sync daemon support : Yes


这2项一定要是yes的,如果不是的话,去看configure时缺少了什么导致这2个失败,一般是缺乏相关的package所致。

然后你看它少什么,你就yum install 什么即可。举例: 如果配置时提示OpenSSL的安装错误,则执行yum install openssl-devel openssl进行安装

 

configure后,下面就是:

 

make;

 

make install;

 

—— 注意:make步骤中若出现fd_set、blkcnt_t类型冲突之类的错误,可以修改./keepalived/libipvs-2.6 /ip_vs.h文件,将#include linux/types.h行移到#include sys/types.h行之后,然后重新执行make进行编译即可。
[root@localhost keepalived-1.2.2]# vi keepalived/libipvs-2.6/ip_vs.h
……
#include sys/types.h
#include linux/types.h

……

 

查找keepalived的安装位置:

# find / -name keepalived

 

/usr/local/keepalived/etc/sysconfig/keepalived
/usr/local /keepalived/ etc/rc.d/init.d/keepalived
/usr/local /keepalived/ etc/keepalived
/usr/local /keepalived/ sbin/keepalived

 

拷贝keepalived的配置文件到/etc目录下

 

# 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

 

将keepalived作为服务添加到chkconfig中,并设置开机启动

 

# chkconfig --add keepalived
# chkconfig --level 35 keepalived on
# chkconfig --list keepalived

 

keepalived      0:off   1:off   2:off   3:on    4:off   5:on    6:off

 

3. 配置Keepalived

 

在LVS1上:

 

vi /etc/keepalived/keepalived.conf

 

内容配置如下:

 

global_defs {
   router_id LVS_STUN
}

vrrp_sync_group VGM {
   group {
       VI_1
   }
}

vrrp_instance VI_1 {
    state MASTER     #//负载均衡器的角色
    interface eth0   #//承载VIP地址的物理接口
    lvs_sync_daemon_inteface eth0  #//虚拟路由器的ID号,每个热备组保持相同
    virtual_router_id 51 
    priority 200   #//竞选优先级,数字越大优先级越高
    advert_int 5     #//通告间隔秒数(心跳频率)
    authentication {  #//本VRRP组的认证信息
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.19.1.19    #//热备所针对的虚拟地址(VIP),可以有多个
    }
}

virtual_server 172.19.1.19 80 { #//虚拟服务器的IP地址、端口
    delay_loop 2 #//健康检查的间隔时间
    lb_algo wrr   #//负载调度算法(wrr为根据权重轮询,其他参见ipvsadm手册)
    lb_kind DR     #//负载均衡类型,常用的为DR、NAT方式
#    persistence_timeout 1  #//连接保持时间,适用于动态Web站点、FTP站点等情况
    protocol TCP  #//协议类型

    real_server 172.19.1.15 80 { #//真实服务器的IP地址、端口
        weight 1   #//节点权重
        TCP_CHECK {
            connect_timeout 10  #//连接超时
            nb_get_retry 3          #//重试次数
            delay_before_retry 3  #//重试间隔
        }
    }
    real_server 172.19.1.16 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}
virtual_server 172.19.1.19 3478 {
    delay_loop 2
    lb_algo wrr
    lb_kind DR
    persistence_timeout 10
    protocol UDP

    real_server 172.19.1.15 3478 {
        weight 1
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
        }
    }
    real_server 172.19.1.16 3478 {
        weight 1
    TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

 

同理LVS2上的也需要配置这个文件:

 

global_defs {
   router_id LVS_STUN
}

vrrp_sync_group VGM {
   group {
       VI_1
   }
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    lvs_sync_daemon_inteface eth0
    virtual_router_id 51
    priority 150
    advert_int 5
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.19.1.19
    }
}

virtual_server 172.19.1.19 80 {
    delay_loop 2
    lb_algo wrr
    lb_kind DR
#    persistence_timeout 1
    protocol TCP

    real_server 172.19.1.15 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
        }
    }
    real_server 172.19.1.16 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}
virtual_server 172.19.1.19 3478 {
    delay_loop 2
    lb_algo wrr
    lb_kind DR
#    persistence_timeout 1
    protocol UDP

    real_server 172.19.1.15 3478 {
        weight 1
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
        }
    }
    real_server 172.19.1.16 3478 {
        weight 1
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

 

这2个文件的差别只有2个地方,一个是vrrp_instance.state, 一个是vrrp_instance.priority.

 

4 Real server配置

 

4.1. 设置VIP接口、调整ARP响应参数等

 

[root]# vi /etc/init.d/lvsreal
#!/bin/bash
# chkconfig: 35 99 10
# description: tune lo:0 interface and arp response for lvs-real servers.
VIP="172.19.1.19"
VIP_MASK="255.255.255.255"
VIF="lo:0"
case "$1" in
start)
  echo "Start lvsreal server for $VIP"
  /sbin/ifconfig $VIF $VIP netmask $VIP_MASK up
  /sbin/route add -host $VIP dev $VIF
  /sbin/sysctl -w net.ipv4.conf.lo.arp_ignore=1 &> /dev/null
  /sbin/sysctl -w net.ipv4.conf.lo.arp_announce=2 &> /dev/null
  /sbin/sysctl -w net.ipv4.conf.all.arp_ignore=1 &> /dev/null
  /sbin/sysctl -w net.ipv4.conf.all.arp_announce=2 &> /dev/null
  ;;
stop)
  echo "Stop lvsreal server for $VIP"
  /sbin/ifconfig $VIF down
  /sbin/route del -host $VIP
  /sbin/sysctl -w net.ipv4.conf.lo.arp_ignore=0 &> /dev/null
  /sbin/sysctl -w net.ipv4.conf.lo.arp_announce=0 &> /dev/null
  /sbin/sysctl -w net.ipv4.conf.all.arp_ignore=0 &> /dev/null
  /sbin/sysctl -w net.ipv4.conf.all.arp_announce=0 &> /dev/null
  ;;
*)
  echo "Usage: $0 {start|stop}"
  exit 1
esac

 

[root]# chmod +x /etc/init.d/lvsreal
[root]# chkconfig --add lvsreal
[root]# /etc/init.d/lvsreal start

 

4.2 安装apache2和turnserver

 

[root]# yum install apache2

 

从http://turnserver.sourceforge.net/index.php?n=Main.Download下载turnserver源码包

 

 $ autoreconf -i
 $ ./configure
 $ make
 # make install

 

当然提示少什么package,你就yum install 相应的package即可。

 

4.3 apache2设置

 

修改RealServer1和RealServer2上的/var/www/index.html

 

比如RealServer1上的改成

 


<html><body><h1>my ip is 172.19.1.15!!</h1>
</body></html>

 

RealServer2上的改成


<html><body><h1>my ip is 172.19.1.16!!</h1>
</body></html>

 

4.4 turnserver配置

请参考:http://turnserver.sourceforge.net/index.php?n=Doc.Install,配置就是2个文件:

 

/etc/ turnserver.conf

/etc/turnusers.txt

 

5 iptables配置

我们考虑下4台host与外间和彼此交互需要的端口

 

TCP 80 http端口

UDP 3478 turnserver UDP 端口

TCP 3478 turnserver TCP 端口

 

还有一个重要的别忘了:

112 keepalived的master与backup之间需要保证心跳(vrrp)所需端口。

 

显然的,对于LVS server上,我们需要配置如下:

-A INPUT -p udp -m udp --dport 3478 -j ACCEPT

-A OUTPUT -p udp -m udp --sport 3478 -j ACCEPT

 

-A INPUT -p tcp -m tcp --dport 3478 -j ACCEPT

-A OUTPUT -p tcp -m tcp --sport 3478 -j ACCEPT

-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

-A OUTPUT -p tcp -m tcp --sport 80 -j ACCEPT

-I INPUT -i eth0 -d 224.0.0.0/8 -j ACCEPT
-A INPUT -i eth0 -p vrrp -j ACCEPT

-A OUTPUT -o eth0 -p vrrp -j ACCEPT

 

第一种颜色是为了接受和转发stun binding request的

第二种颜色是为了让keepalived通过tcp 3478端口检查turnserver是否正常使用。检查udp服务比价复杂,所以你开启一个udp服务的进程时,同时打开一个tcp端口让keepalived来检查你的服务是否正常也是可行的。

第三种颜色当然是为了转发http请求的

第四种颜色是为了keepalived的MASTER和BACKUP心跳通讯用的。 vrrp即112端口。

 

对于real server上,显然下面的是必须的:

-A INPUT -p udp -m udp --dport 3478 -j ACCEPT

-A OUTPUT -p udp -m udp --sport 3478 -j ACCEPT

 

-A INPUT -p tcp -m tcp --dport 3478 -j ACCEPT

-A OUTPUT -p tcp -m tcp --sport 3478 -j ACCEPT

-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

-A OUTPUT -p tcp -m tcp --sport 80 -j ACCEPT

 

颜色对应的条目解释同上。

 

6 现在我们可以检验我们的劳动成果了。

 

在real server上:

 

启动apache server: service apache2 start

启动turnserver:  turnserver &

启动lvsreal服务: service lvsreal start

 

执行ip add:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet 172.19.1.19/32 brd 172.19.1.19 scope global lo:0
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether d0:0d:31:a6:07:17 brd ff:ff:ff:ff:ff:ff
    inet 172.19.1.15/27 brd 172.19.1.31 scope global eth0
    inet6 fe80::d20d:31ff:fea6:717/64 scope link

 

可现在虚拟ip: 172.19.1.19被设置在lo:0上。

 

在LVS1和LVS2都运行:

 

keepalived -D

 

同时你可以开一个终端查看keepalived的日志

 

tail -f /var/log/messages

 

注意:

   把service avahi-daemon和avahi-dnsconfd关掉。不然一直刷log,很烦。

 

通过看日志,你可以发现一台lvs的keepalived会处于MASTER状态,一台处于BACKUP状态。而且通过

 

ip add

你可以发现MASTER上绑定了虚拟ip:172.19.1.19

 

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether d0:0d:34:8d:06:80 brd ff:ff:ff:ff:ff:ff
    inet 172.19.1.13/27 brd 172.19.1.31 scope global eth0
    inet 172.19.1.19/32 scope global eth0
    inet6 fe80::d20d:34ff:fe8d:680/64 scope link
       valid_lft forever preferred_lft forever
3: sit0: <NOARP> mtu 1480 qdisc noop
    link/sit 0.0.0.0 brd 0.0.0.0

 

而backup上并没有绑定虚拟ip。

 

 

在这4台host之外选择一台host,比如172.19.1.12 执行:

 

curl http://172.19.1.19 多次,可以发现

 

<html><body><h1>my ip is 172.19.1.15!!</h1>
</body></html>

 


<html><body><h1>my ip is 172.19.1.16!!</h1>
</body></html>

 

轮流出现,而且任意停止keepalived服务一台和apache2服务一台,都不会影响使用。

 

当然你也可以在浏览器中输入http://61.147.xxx.xxx,通过公网ip来访问。

 

好了, TCP的服务是好了。那么UDP的服务呢?

非常令人失望,客户端通过公网ip--61.147.xxx.xxx连接turnserver,并不能得到正确回应。

这是为什么呢?我们来分析一下过程:

 

经过wireshark和tcpdump,分析得出通讯的过程如下:

 

cleint--->Client NAT---61.147.xxx.xxx---->Server NAT---->VIP(172.19.1.19)----->RealServer----->Server NAT------>Client NAT--->Client

 

在NAT 地址映射中:

 

172.19.1.19<------>61.147.xxx.xxx

 

但是RealServer(172.19.1.15或者172.19.1.16)却是对应了别的公网ip。

 

所以客户端的NAT接受到一个非61.147.xxx.xxx发过来的UDP包时,会把它丢弃掉,这样client就收不到任何东西了。

 

解决方案:

用iptables的NAT和DNAT

 

在RealServer1(172.19.1.15)上用iptables添加

 

iptables -t nat -A PREROUTING -d 172.19.1.19/32 -p udp -m udp --dport 3478 -j DNAT --to-destination 172.19.1.15


iptables -t nat -A POSTROUTING -p udp -m udp --sport 3478 -j SNAT --to-source 172.19.1.19

 

意思就是:

1 收到目的端口为3478的udp,且目的地址为172.19.1.19的包,把目的地址改为172.19.1.15,以便应用程序turnserver处理,因为turnserver绑定的地址172.19.1.15。

2 往外发出源端口为3478的udp包,源地址都被改成172.19.1.19,这样server nat就会把地址映射为61.147.xxx.xxx,这样client NAT就会就收这个udp包了。

 

在RealServer2(172.19.1.16)上用iptables添加

 

iptables -t nat -A PREROUTING -d 172.19.1.19/32 -p udp -m udp --dport 3478 -j DNAT --to-destination 172.19.1.16


iptables -t nat -A POSTROUTING -p udp -m udp --sport 3478 -j SNAT --to-source 172.19.1.19

 

 

然后测试,发现udp服务可以正常使用啦。

 

当然有些UDP应用可以直接绑定在虚拟IP地址上,这种方法在www.linuxvirtualserver.org上有说过,不知有人部署成功过没有,如有人成功过,请不吝指教。

 

qq: 15520929

msn: hery1977@hotmail.com

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics