前面我们已经学习了 LVS 的 3 种转发模式DR 模式NAT 模式TUN 模式我们来回顾一下这几种模型的劣势DR 模式LVS - RS 间必须在同一个 VLAN/网段 内RS 绑定 VIP，风险大RS 都要公网 IPNAT 模式RS 的 默认网关必须要指向 LVSLVS - RS 间必须在同一个 VLAN/网段 内TUN 模式配置隧道模块 （IPIP 等），配置复杂RS 绑定 VIP，风险大当集群规模较小时，使用 NAT、DR 模式都是没有问题的，当集群内有几十台以上时，那么这些服务器通常都不在同一个 VLAN/网段 内了。这时，必须再研发出一种能支持跨 VLAN/网段 通信的模式，FULLNAT 模式就是为了解决这个问题而生的。1. FULLNAT 模型在 FULLNAT 模式中，LVS 会同时修改源 IP 和目标 IP。与 NAT 模式不同之处：NAT 模式目标 IP -> RIP源 IP -> 客户端 IPFULLNAT 模式目标 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 install2.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 install2.3 编译 keepalivedcd /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 install2.4 编译 ipvsadmcd /usr/local/src/lvs-fullnat-synproxy/tools/ipvsadm; make make install3. 安装已经编译好的 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.rpm4. 配置拓扑： ┌────────────┐ │ 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 端口：8080ipvsadm 配置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.1keepalived 配置! Configuration File for keepalived global_defs { notification_email { rz-chen@mygzb.com } notification_email_from rz-chen@mygzb.com 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 } } }