LVS FULLNAT 实战
前面我们已经学习了 LVS 的 3 种转发模式
- DR 模式
- NAT 模式
- TUN 模式
我们来回顾一下这几种模型的劣势
DR 模式
- LVS - RS 间必须在同一个 VLAN/网段 内
- RS 绑定 VIP,风险大
- RS 都要公网 IP
NAT 模式
- RS 的 默认网关必须要指向 LVS
- LVS - RS 间必须在同一个 VLAN/网段 内
TUN 模式
- 配置隧道模块 (IPIP 等),配置复杂
- RS 绑定 VIP,风险大
当集群规模较小时,使用 NAT、DR 模式都是没有问题的,当集群内有几十台以上时,那么这些服务器通常都不在同一个 VLAN/网段 内了。这时,必须再研发出一种能支持跨 VLAN/网段 通信的模式,FULLNAT 模式就是为了解决这个问题而生的。
1. FULLNAT 模型
在 FULLNAT 模式中,LVS 会同时修改源 IP 和目标 IP。
与 NAT 模式不同之处:
NAT 模式
- 目标 IP -> RIP
- 源 IP -> 客户端 IP
FULLNAT 模式
- 目标 IP -> RIP
- 源 IP -> LVS IP
这一修改,使得 RS 和 LVS 可以不在同一个 VLAN/网段 下。
同时,也带来了一个问题,源 IP 改成了 LVS 的 IP了,RS 怎么获取客户端的真实 IP 呢?
为了使 RS 能获得客户端的真实 IP,LVS 团队采用了修改内核网络栈的实现,扩展了网络栈,加了一个 TOA 字段。把客户端真实 IP 写到了 TOA 字段中,这样,RS 就能取得客户端的真实 IP 了。
这样,意味着每台 RS 都需要安装打了 TOA 补丁的内核。并且,也要配套使用 FULLNAT 专用的 keepalived 和 ipvsadm。
2. 编译
2.1 编译 LVS 内核 - 打 FULLNAT 补丁
# 1. 下载内核源码,注意,必须是 2.6.32-220.23.1 这个版本的
wget ftp://ftp.redhat.com/pub/redhat/linux/enterprise/6Server/en/os/SRPMS/kernel-2.6.32-220.23.1.el6.src.rpm
# 2. 安装内核源码
rpm -ivh kernel-2.6.32-220.23.1.el6.src.rpm
cd ~/rpmbuild/SPECS
rpmbuild -bp kernel.spec
# 3. 打 LVS 补丁
wget http://kb.linuxvirtualserver.org/images/a/a5/Lvs-fullnat-synproxy.tar.gz
tar xf Lvs-fullnat-synproxy.tar.gz -C /usr/local/src
cp /usr/local/src/lvs-fullnat-synproxy/lvs-2.6.32-220.23.1.el6.patch ~/rpmbuid/BUILD
patch -p1<lvs-2.6.32-220.23.1.el6.patch
# 4. 编译安装
make -j8
make modules_install
make install
2.2 编译 RS 内核 - 打 TOA 补丁
# 1. 下载内核源码,注意,必须是 2.6.32-220.23.1 这个版本的
wget ftp://ftp.redhat.com/pub/redhat/linux/enterprise/6Server/en/os/SRPMS/kernel-2.6.32-220.23.1.el6.src.rpm
# 2. 安装内核源码
rpm -ivh kernel-2.6.32-220.23.1.el6.src.rpm
cd ~/rpmbuild/SPECS
rpmbuild -bp kernel.spec
# 3. 打 TOA 补丁
wget http://kb.linuxvirtualserver.org/images/a/a5/Lvs-fullnat-synproxy.tar.gz
tar xf Lvs-fullnat-synproxy.tar.gz -C /usr/local/src
cp /usr/local/src/lvs-fullnat-synproxy/toa-2.6.32-220.23.1.el6.patch ~/rpmbuid/BUILD
patch -p1<lvs-2.6.32-220.23.1.el6.patch
# 4. 编译安装
make -j8
make modules_install
make install
2.3 编译 keepalived
cd /usr/local/src/lvs-fullnat-synproxy
tar xf lvs-tools.tar.gz
cd tools/keepalived
./configure --with-kernel-dir="/lib/modules/`uname -r`/build"
make
make install
2.4 编译 ipvsadm
cd /usr/local/src/lvs-fullnat-synproxy/tools/ipvsadm;
make
make install
3. 安装已经编译好的 RPM 包
鉴于编译安装的复杂和非常的耗时,我将上面的 4 个包已经打包成 RPM 包,只需要安装几个就可以了。
# 卸载已安装的 keepalived 和 ipvsadm
yum remove keepalived ipvsadm
# 安装 FULLNAT 专用的 keepalived 和 ipvsadm
rpm -ivh ipvsadm-1.2.1-fnat.0.x86_64.rpm keepalived-1.2.2-fnat.0.x86_64.rpm
# 安装 FULLNAT 内核
rpm -Uvh --force kernel-2.6.32-220.23.1.el6.x86_64.rpm kernel-devel-2.6.32-220.23.1.el6.x86_64.rpm kernel-headers-2.6.32-220.23.1.el6.x86_64.rpm
4. 配置
拓扑:
┌────────────┐
│ client |
└──────┬─────┘
| CIP=192.168.192.1
|
| VIP=192.168.192.10 (eth0)
┌──────┴─────┐
│ director |
└──────┬─────┘
| DIP=192.168.1.1 (eth1)
|
┌────────┴───────┐
│ switch |
└────┬───────┬───┘
192.168.1.10 | | 192.168.1.11
┌────────────┴┐ ┌┴────────────┐
│ realserver1 | │ realserver2 |
└─────────────┘ └─────────────┘
RS Nginx 端口:8080
ipvsadm 配置
ipvsadm -A -t 192.168.192.10:80 -s wrr
ipvsadm -a -t 192.168.192.10:80 -r 192.168.1.10:8080 -b -w 2
ipvsadm -a -t 192.168.192.10:80 -r 192.168.1.11:8080 -b -w 1
ipvsadm -P -t 192.168.192.10:80 -z 192.168.1.1
keepalived 配置
! Configuration File for keepalived
global_defs {
notification_email {
[email protected]
}
notification_email_from [email protected]
smtp_connect_timeout 3
smtp_server 127.0.0.1
router_id LVS_DEVEL
}
vrrp_script chk_schedown {
script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"
interval 2
weight -2
}
local_address_group laddr_g1 {
192.168.1.1
}
virtual_server_group group1 {
192.168.192.10 80
}
vrrp_instance VI_1 {
interface eth0
state MASTER
priority 101
virtual_router_id 51
garp_master_delay 1
authentication {
auth_type PASS
auth_pass password
}
track_interface {
eth0
}
virtual_ipaddress {
192.168.192.10/24 dev eth0 label eth0:0
}
track_script {
chk_schedown
}
}
virtual_server 192.168.192.10 80 {
delay_loop 6
lb_algo wrr
lb_kind FNAT
#persistence_timeout 50
protocol TCP
laddr_group_name laddr_g1
# sorry_server 192.168.192.200 80
real_server 192.168.1.10 8080 {
weight 2
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
# 后端服务器健康检查有4种方式:HTTP_GET、SSL_GET、TCP_CHECK、MISC_CHECK
#SSL_GET {
# url {
# path /login.jsp
# digest 1a512ae2cb4eb9564856d0fa0df58a50
# }
# connect_timeout 3
# nb_get_retry 3
# delay_before_retry 3
#}
#TCP_CHECK {
# connect_port num
# connect_timeout num
#}
#MISC_CHECK {
# misc_path /path_to_script/script.sh
# (or misc_path “ /path_to_script/script.sh <arg_list>”)
#}
}
real_server 192.168.1.11 8080 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
不严谨,打 toa patch 那段,补丁包名字都复制错了
666