LVS的FULLNAT模式
fullnat模式原理:
fullnat模式和nat模式比较类似,客户端的请求和响应都会经过lvs,不同的是nat模式下转换仅存在于目的方向,也就是说客户端的发来的请求经过lvs后,请求的目的ip会转化成rs的ip地址,目的端口会转化成rs的目的端口,而在fullnat模式下,客户端发来的请求的源ip和源端口都会被转换成lvs的内网ip地址和端口,同理对于rs回复的响应,nat模式下,响应的目的ip和目的端口均为客户端的,而fullnat模式下,响应的目的ip和目的端口均为lvs内网的,这样lvs收到这个响应后会将源ip和源端口转换成vip的地址和端口,目的ip和目的端口会被转换成客户端的ip地址和端口,也就是说在nat模式下对于客户端的请求仅发生DNAT转换,对于RS的响应仅发生SNAT转换,而fullnat模式下,在请求和响应上都会发生SNAT和DNAT转换;另一点不同是nat模式下要求lvs的内网ip和rs的ip地址在同一网段,lvs和rs之间需要二层交换设备,而fullnat对于请求和响应都会发生DNAT和SNAT所以lvs的内网ip地址可以和rs不再同一网段,这样lvs和rs之间就需要三层交换设备,所以相对于nat模式,fullnat的部署会更加灵活,它不要求lvs的内网ip和rs的ip在同一网段,下边做实验来模拟一下fullnat模式的过程:
安装过程:
fullnat模式的内核版本比较低,所以安装最好在centos6下进行,这里不能使用原来的通过yum安装的ipvsadm,而是需要编译安装经过阿里改造后的,所以需要卸载原来的ipvsadm
1. 下载内核rpm包
wget ftp://ftp.redhat.com/pub/redhat/linux/enterprise/6Server/en/os/SRPMS/kernel-2.6.32-220.23.1.el6.src.rpm |
2. 在root目录下
vim ~/.rpmmacros; 并添加 %_topdir /home/pukong/rpms %_tmppath /home/pukong/rpms/tmp %_sourcedir /home/pukong/rpms/SOURCES %_specdir /home/pukong/rpms/SPECS %_srcrpmdir /home/pukong/rpms/SRPMS %_rpmdir /home/pukong/rpms/RPMS %_builddir /home/pukong/rpms/BUILD |
这样可以把rpm安装到/home/pukong路径下
3. 安装rpm包,安装rpm-build
rpm -ivh kernel-2.6.32-220.23.1.el6.src.rpm cd /home/pukong/rpms/SPECS yum install rpm-build rpmbuild -bp kernel.spec |
这样就可以在/home/pukong/rpms/BUILD目录里看到内核的源码了
4. 安装lvs补丁
从http://kb.linuxvirtualserver.org/images/a/a5/Lvs-fullnat-synproxy.tar.gz下载Lvs-fullnat-synproxy.tar.gz然后解压,将解压后的里边的lvs-2.6.32-220.23.1.el6.patch补丁拷贝到/home/pukong/rpms/BUILD/路径下,并执行patch -p1<lvs-2.6.32-220.23.1.el6.patch命令
5. 安装依赖并在/home/pukong/rpms/BUILD目录里编译安装内核
yum install -y xmlto gcc-c++ rpm-build patchutils asciidoc elfutils-libelf-devel zlib-devel binutils-devel newt-devel python-devel hmaccalc perl\(ExtUtils::Embed\) rng-tools lrzsz openssl-devel popt-devel make make modules_install |
6. 重启切换内核然后再切换到/home/pukong/rpms/BUILD目录里执行make install命令,这样lvs内核模块就安装完成了
7. 切换到Lvs-fullnat-synproxy.tar.gz文件里,解压lvs-tools.tar.gz,编译安装lvs的各种工具
keepalived
./configure --with-kernel-dir="/lib/modules/`uname -r`/build" make make install |
ipvsadm
make; make install; |
quaage
./configure --disable-ripd --disable-ripngd --disable-bgpd --disable-watchquagga --disable-doc --enable-user=root --enable-vty-group=root --enable-group=root --enable-zebra --localstatedir=/var/run/quagga make make install |
实验拓扑:
实验步骤:
1. 配置各虚拟机IP地址以及路由
centos7各网卡的ip直接用ifconfig配置即可,但是centos6虚拟机里没有网卡的配置文件,所以使用ifconfig配置网卡的ip地址的时候过一段时间就失效了,所以需要手动添加网卡的配置文件
文件放在/etc/sysconfig/network-scripts里,文件创建完成后要重启网络服务,然后需要配置路由器端口的ip地址以及路由表,这里记录一下路由器一个端口的ip地址的配置过程和配置rip协议的过程
然后需要在lvs和两个rs上配置路由,首先在lvs虚拟机上配置
两个RS在两个子网中,所以要添加两条路由,然后在RS上添加一条路由即可
这样整个网络就打通了
2. 用ipvsadm添加lvs服务,并在两个RS上开启http服务
首先清空ipvsadm已有的服务,然后用-A选项添加一个服务,然后添加两个RS,-b代表开启fullnat模式,最后一条命令是指SNAT转换的IP地址,也就是客户端的请求经过lvs的转换后源ip地址转换成10.0.3.1也就是lvs的eth1的ip地址,这里为了体现端口转换的效果,将两个RS的http的服务开启在8080端口上
3. 在客户端上用curl命令即可看到效果
抓包分析过程(以请求到web1为例):
首先在client与lvs之间的链路抓包
这是一个完整的http的请求过程,来看第一个syn数据包
可以看到,这个数据包的源ip是客户端的ip,目的ip是lvs的eth0的ip地址(vip),源端口是50026,目的端口是vip的端口,这个数据包经过lvs转换后,会变成这样
可以看到这个syn数据包的源ip是lvs的eth1的ip地址,目的ip转换成了web1的ip地址,并且源端口从客户端发来的50026端口转换成了5014端口,目的端口也转换成了web1的http服务的端口,所以从这里就可以看到了fullnat和nat模式的区别了,nat模式的转换仅仅存在于目的方向,也就是可以实现对目的ip和目的端口的转换,但是源ip和源端口一直都是客户端的源ip和端口,并且转换后的目的ip可以和lvs的ip地址不在同一个子网中,所以和nat模式相比fullnat不能使用二层交换设备来实现负载均衡了,而是需要三层交换设备,并且对于源ip和源端口的转换,也能够让RS的响应通过路由器回复给lvs,这样就增加了灵活性,不要求lvs和RS必须在同一个网段中,转换后的这个数据包会被路由器转发到web1上,web1收到这个数据包后会产生syn,ack数据包
可以看到这个数据包的源ip是web1的ip,源端口是8080,目的ip是lvs的ip地址,目的端口也是lvs的5014端口,这个处理逻辑和nat模式也是一样的,RS上不会对数据包做出什么改变,而是仅仅将发来的请求的数据包的源ip和源端口作为响应的目的ip和目的端口返回回去,只不过这个请求的源ip和源端口已经被lvs转换了,这样这个响应包会经过路由器转发给lvs,并且会被lvs转换,转换后的syn,ack数据包为
可以看到源ip被转换成vip,源端口也从8080端口转化为80端口,目的ip从lvs的ip地址转化成了客户端的ip地址,目的端口从lvs的5014端口转换成了客户端最初的syn请求的源端口50026这样,客户端就能够收到这个数据包并建立连接,后边的数据包的处理过程和这个过程是一样的。