LVS简介
LVS是Linux Virtual Server的简称,也叫Linux虚拟服务器, 也就是现在常说的四层负载均衡。 它是一个由章文嵩博士发起的自由软件项目 。
现在LVS已经是 Linux标准内核的一部分,在Linux2.4内核以前,使用LVS时必须要重新编译内核以支持LVS功能模块,但是从Linux2.4内核以后,已经完全内置了LVS的各个功能模块,无需给内核打任何补丁,可以直接使用LVS提供的各种功能。
为什么要用 LVS?
那为什么还需要用 LVS 呢?随着 Internet 的爆炸性增长以及日常生活中的日益重要的作用,Internet 上的流量速度增长,以每年 100% 以上的速度增长。
服务器上的工作负载压力也迅速增加,因此服务器在短时间内将会过载,尤其是对于受欢迎的网站而言。
为了克服服务器的过载压力问题,有两种解决方案:
• 一种是:单服务器解决方案,即将服务器升级到性能更高的服务器,但是当请求增加时,将很快过载,因此必须再次对其进行升级,升级过程复杂且成本高;
• 另一个是:多服务器解决方案,即在服务器集群上构建可扩展的网络服务系统。当负载增加时,可以简单地在群集中添加新服务器或更多服务器以满足不断增长的需求,而商用服务器具有最高的性能/成本比。因此,构建用于网络服务的服务器群集系统更具可伸缩性,并且更具成本效益。
LVS和nginx都可以做负载均衡,那么他们又什么区别呢?
LVS比nginx具有更强的抗负载能力,性能更高,对内存和cpu资源消耗低
LVS工作在网络,具体流量由操作系统内核进行处理,nginx工作在应用层,可针对http应用实施一些分流策略
LVS安装配置比较复杂点,网络依赖性较大,稳定性高,lvs不支持正则表达式,不能实现动静分离操作,
LVS使用的协议范围广, Nginx 仅支持 HTTP、HTTPS、Email 协议,适用范围小。
负载均衡LVS基本介绍
LB集群的架构和原理很简单,就是当用户的请求过来时,会直接分发到Director Server上,然后它把用户的请求根据设置好的调度算法,智能均衡地分发到后端真正服务器(real server)上。为了避免不同机器上用户请求得到的数据不一样,需要用到了共享存储,这样保证所有用户请求的数据是一样的。
LVS是 Linux Virtual Server 的简称,也就是Linux虚拟服务器。这是一个由章文嵩博士发起的一个开源项目,它的官方网是 http://www.linuxvirtualserver.org 现在 LVS 已经是 Linux 内核标准的一部分。使用 LVS 可以达到的技术目标是:通过 LVS 达到的负载均衡技术和 Linux 操作系统实现一个高性能高可用的 Linux 服务器集群,它具有良好的可靠性、可扩展性和可操作性。从而以低廉的成本实现最优的性能。LVS 是一个实现负载均衡集群的开源软件项目,LVS架构从逻辑上可分为调度层、Server集群层和共享存储。
LVS的组成
LVS 由2部分程序组成,包括 ipvs 和 ipvsadm。
-
ipvs(ip virtual server):一段代码工作在内核空间,叫ipvs,是真正生效实现调度的代码。
-
ipvsadm:另外一段是工作在用户空间,叫ipvsadm,负责为ipvs内核框架编写规则,定义谁是集群服务,而谁是后端真实的服务器(Real Server)
LVS相关术语
- DS:Director Server。指的是前端负载均衡器节点。
- RS:Real Server。后端真实的工作服务器。
- VIP:Virtual IP 向外部直接面向用户请求,作为用户请求的目标的IP地址。
- DIP:Director Server IP,主要用于和内部主机通讯的IP地址。
- RIP:Real Server IP,后端服务器的IP地址。
- CIP:Client IP,访问客户端的IP地址。
三种LVS工作模式详细
基于NAT的LVS模式负载均衡
NAT(network address translation) 网络地址转换,其主要原理是修改数据报头,使得位于企业内部的私有ip地址可以访问外网,以及外部用户可以访问位于公司内部的私有的ip主机。
LVS调度器中有一个连接Hash表,该表会记录连接请求及其转发信息,当同一个连接下一个数据包发送给调度器时,该Hash’表可以直接找到之前连接的记录,并根据记录信息选出相同真实服务器及其端口信息。
工作原理
- 当用户的请求到达调度器时,请求报文会先到内核空间的PREROUTING链上。此时报文的源IP为CIP,目标IP为VIP
- PREROUTING检查发现数据包的目标IP是本机,就将数据包送至INPUT链。
- IPVS工作在INPUT链上,当数据包抵达INPUT链后,IPVS会检查数据包所请求的服务是否为集群服务,若是,修改数据包的目标IP地址为后端服务器RIP,然后将数据包送往POSTROUTING链。此时报文的源IP为CIP,目标IP为RIP。
- POSTROUTING链通过选路,将数据包转发给Real Server
- Real Server对比发现目标IP是自己,就会接受这个请求报文,开始构建响应报文发回给调度器。源IP为RIP,目标IP为CIP
- 调度器在响应客户端前,会将报文的源IP地址修改为自己的VIP,然后响应给客户端。此时报文的源IP为VIP,目标IP为CIP
LVS-NAT模型的特性
- RS应该使用私有地址,RS的网关必须指向DIP
- DIP和RIP必须要在同一网段中
- 请求报文和响应报文都需要经过调度器,高负载场景中,调度器容易成为性能瓶颈。
- 支持端口映射
- RS可以使用任意操作系统
NAT的优点:
集群中的物理服务器可以使用任何支持TCP/IP操作系统它只需要一个 IP 地址配置在调度器上,服务器组可以用私有的 IP 地址。
NAT的缺点:
时伸缩能力有限,当服务器节点(普通PC服务器)增长过多时,负载均衡器将成为整个系统的瓶颈,因为所有的请求包和应答包的流向都经过负载均衡器。当服务器节点过多时,大量的数据包都交汇在负载均衡器那,速度就会变慢。
基于TUN的LVS负载均衡
LVS(NAT)模式的集群环境中,所有数据包的请求的回应的哦欧需要经过调度器处理,但是在TUN模式中,将NAT模式中的问题有所解决。因为数据包的请求包往往远远小于响应数据包的大小。因为响应数据包中有包含客户需要的具体数据所以,TUN的原理就是将请求与响应数据分离。,让调度器仅仅处理数据请求,让真实的服务器响应数据包直接返回给客户。
IP(隧道)是一种数据包分装技术,他可以经原始的数据包分装并添加新的包头(内容包括新的源地址及端口、目标地址及端口),从而实现将一个目标为调度器的vip地址的数据包分装,通过隧道转发给真实的后端服务器,通过将客户端发往调度器的原始数据包分装,并在其基础上添加新的数据包头(修改目标地址为调度器选择出来的真实服务的ip地址以及对应端口),lLVS(Tun)模式要求真实的服务器可以与外部网络连接,真实服务器在受到请求数据包后直接给客户端返回响应数据。
LVS(Tun)技术对服务器有要求,即所有服务器必须支持"IP Tunneling"或者IP Encapsulation”协议。目前,VS/TUN 的后端服务器主要运行 Linux 操作系统。
原理说明:
- 当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。此时报文的源IP为CIP,目标IP为VIP 。
- PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链
- IPVS比对数据包请求的服务是否为集群服务,若是,在请求报文的首部再次封装一层IP报文,封装源IP为为DIP,目标IP为RIP。然后发至POSTROUTING链。此时源IP为DIP,目标IP为RIP
- POSTROUTING链根据最新封装的IP报文,将数据包发至RS(因为在外层封装多了一层IP首部,所以可以理解为此时通过隧道传输)。此时源IP为DIP,目标IP为RIP
- RS接收到报文后发现是自己的IP地址,就将报文接收下来,拆除掉最外层的IP后,会发现里面还有一层IP首部,而且目标是自己的lo接口VIP,那么此时RS开始处理此请求,处理完成之后,通过lo接口送给eth0网卡,然后向外传递。此时的源IP地址为VIP,目标IP为CIP
- 响应报文最终送达至客户端
LVS-Tun模型特性
- RIP、VIP、DIP全是公网地址
- RS的网关不会也不可能指向DIP
- 所有的请求报文经由Director Server,但响应报文必须不能进过Director Server不支持端口映射
- RS的系统必须支持隧道
LVS(DR)负载均衡
在LVS(TUN)模式中,需要LVS调度器与真实的服务器之间创建隧道连接,这样就会增加服务器的负担。DR模式也叫路由模式,该模式中LVS依然仅承担数据的请求以及根据算法调度出合理的后端服务器,最终由后端真实服务器负责响应数据包发送返回给客户端。与隧道模式不同的是,DR模式要求调度器与后端服务器必须在统一个局域网内u,VIP地址需要在调度器与后端所有服务器之间共享,因为最终的真实服务器会给客户端回应数据包时需要设置源IP为VIP,目标IP为客户端IP,这样客户端访问的时调度器VIP地址,回应的源地址也是VIP,这样客户端是感觉不到后端服务器的存在。由于多台计算机都设置了同样的VIP地址,所以在直接路由模式中要求调度器的VIP是对外可见的,客户端将请求数据包发送到调度器主机,而所有的真实服务器的VIP必须配置在Non-ARP的网络上ARP是一个协议。调度器根据算法在选出真实的服务器后,在不修改数据报文的情况下,将数据帧的MAC地址修改为选出的真实的MAC地址,通过交换机将该数据帧发给真实的服务器。
配置lvs-nat模式的httpd负载集群—http
环境说明:
主机名称 网卡信息(ens33为Nat、ens38为仅主机) 安装应用 系统
Client客户端 192.168.91.145(ens33) 无 centos8
DR DIP:192.168.91.129(ens33)—VIP:192.168.237.10(ens38) ipvsadm centos8
RS1 RIP:192.168.91.134(ens33)—gw:192.168.91.129 httpd centos8
RS2 RIP:192.168.91.139(ens33)—gw:192.168.91.129 httpd centos8
给DR主机添加一个仅主机的网卡
[root@DR ~]# ifconfig //查看到仅主机网卡的名字为 ens38
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.91.129 netmask 255.255.255.0 broadcast 192.168.91.255
inet6 fe80::20c:29ff:feb8:3224 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b8:32:24 txqueuelen 1000 (Ethernet)
RX packets 299161 bytes 120054672 (114.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 382902 bytes 85603867 (81.6 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens38: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 00:0c:29:b8:32:2e txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
//查看虚拟网络编辑器种仅主机的网段为192.168.237.0
[root@DR ~]# nmcli connection add con-name ens38 ifname ens38 type ethernet
Connection 'ens38' (9b003222-efb6-4d19-8043-a625b3a9c154) successfully added.
[root@DR ~]# nmcli connection
NAME UUID TYPE DEVICE
ens33 af4d3903-2150-4bda-9723-f37666535088 ethernet ens33
ens38 9b003222-efb6-4d19-8043-a625b3a9c154 ethernet ens38
virbr0 95dd368f-e449-44b6-8fb2-cd0cbbb50c2f bridge virbr0
[root@DR ~]# nmcli connection modify ens38 ipv4.addresses 192.168.237.10/24 ipv4.method manual autoconnect yes
[root@DR ~]# systemctl restart NetworkManager
[root@DR ~]# nmcli connection up ens38
Connection successfully activated (D-Bus active path:/org/freedesktop/NetworkManager/ActiveConnection/5)
DR、RS1、RS2三台主机都关闭防火墙和selinux
[root@DR ~]# systemctl stop firewalld
[root@DR ~]# systemctl disable firewalld
[root@DR ~]# sed -i s/SELINUX=enforcing/SELINUX=disabled/g /etc/selinux/config
[root@DR ~]# setenforce 0
[root@RS1 ~]# systemctl stop firewalld
[root@RS1 ~]# systemctl disable firewalld
[root@RS1 ~]# sed -i s/SELINUX=enforcing/SELINUX=disabled/g /etc/selinux/config
[root@RS1 ~]# setenforce 0
[root@RS2 ~]# systemctl stop firewalld
[root@RS2 ~]# systemctl disable firewalld
[root@RS2 ~]# sed -i s/SELINUX=enforcing/SELINUX=disabled/g /etc/selinux/config
[root@RS2 ~]# setenforce 0
配置ip信息
//DR:
[root@DR ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
IPADDR=192.168.91.129
PREFIX=24
GATEWAY=192.168.91.2
DNS1=8.8.8.8
//RS1:
[root@RS1 ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
.....
IPADDR=192.168.91.134
PREFIX=24
GATEWAY=192.168.91.129
DNS1=8.8.8.8
//RS2:
[root@RS2 ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
IPADDR=192.168.91.139
PREFIX=24
GATEWAY=192.168.91.129
DNS1=8.8.8.8
//后端RS1和RS2部署WEB服务器
RS1:
[root@RS1 ~]# yum -y install httpd
[root@RS1 ~]# echo RS1 > /var/www/html/index.html
[root@RS1 ~]# systemctl restart httpd
[root@RS1 ~]# systemctl enable httpd
//RS2:
[root@RS2 ~]# yum -y install httpd
[root@RS2 ~]# echo RS2 > /var/www/html/index.html
[root@RS2 ~]# systemctl restart httpd
[root@RS2 ~]# systemctl enable httpd
//配置DR
(1)开启IP转发功能
[root@DR ~]# vim /etc/sysctl.con
net.ipv4.ip_forward = 1
[root@DR ~]# sysctl -p
net.ipv4.ip_forward = 1
//安装ipvsadm并添加规则
[root@DR ~]# yum -y install ipvsadm
[root@DR ~]# ipvsadm -A -t 192.168.237.10:80 -s rr
[root@DR ~]# ipvsadm -a -t 192.168.237.10:80 -r 192.168.91.134:80 -m
[root@DR ~]# ipvsadm -a -t 192.168.237.10:80 -r 192.168.91.139:80 -m
[root@DR ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.237.10:80 rr
-> 192.168.91.134:80 Masq 1 0 0
-> 192.168.91.139:80 Masq 1 0 0
[root@DR ~]# ipvsadm -Sn > /etc/sysconfig/ipvsadm
[root@DR ~]# systemctl restart ipvsadm.service
[root@DR ~]# systemctl enable ipvsadm.service
//客户端测试
[root@Client ~]# curl http://192.168.237.10
RS2
[root@Client ~]# curl http://192.168.237.10
RS1
[root@Client ~]# curl http://192.168.237.10
RS2
[root@Client ~]# curl http://192.168.237.10
RS1
配置lvs-nat模式的httpd负载集群—https
//在DR中生成一对密钥
[root@DR ~]# mkdir -p /etc/pki/CA/private
[root@DR ~]# cd /etc/pki/CA/
[root@DR CA]# (umask 077;openssl genrsa -out private/cakey.pem 2048)
Generating RSA private key, 2048 bit long modulus (2 primes)
........................................................................................+++++
..........+++++
e is 65537 (0x010001)
[root@DR CA]# openssl rsa -in private/cakey.pem -pubout
writing RSA key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwzoaJdd6iyCTOe97L7jg
sd3I7TKZuADMwRWKYYwyt5x2QuBuI7FaJ0gtP6sSRn9UmOpxixXDKOX2wpv27Ld+
N0L45eX/cDcMNJtMLCm4eVxzFegJagiE60gt6paTn6JX70AK6RM8iIClAwQMPbc3
lUooeSDcRoWW7LU85+QU36p3RpNIKcNOow5GNvuHe/GQhqArA50gxXsKqkFDsZVm
7xLZVWyBJ5WImhHgjV9wEhjk+/fM+8i05KOS3+WPf01I58zmehh3REohMi1X4Knz
RAS25s4pU6Shs2XAj6nHRLrxPUslEE5ZS9Uc9hKLUizLUeWDTo37yv4CJkVi50XV
TwIDAQAB
-----END PUBLIC KEY-----
[root@DR CA]# openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 1024
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:hubei
Locality Name (eg, city) [Default City]:wuhan
Organization Name (eg, company) [Default Company Ltd]:runtime
Organizational Unit Name (eg, section) []:linux
Common Name (eg, your name or your server's hostname) []:dr
Email Address []:dr@1314.com
[root@DR CA]# touch index.txt && echo 01 > serial
在RS1中生成证书签署请求,并发送给CA
[root@RS1 ~]# yum -y install mod_ssl
[root@RS1 ~]# mkdir /etc/httpd/ssl
[root@RS1 ~]# cd /etc/httpd/ssl/
[root@RS1 ssl]# (umask 077;openssl genrsa -out httpd.key 2048)
Generating RSA private key, 2048 bit long modulus (2 primes)
..................................+++++
............................................................................+++++
e is 65537 (0x010001)
[root@RS1 ssl]# openssl req -new -key httpd.key -days 1024 -out httpd.csr
Ignoring -days; not generating a certificate
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:hubei
Locality Name (eg, city) [Default City]:wuhan
Organization Name (eg, company) [Default Company Ltd]:runtime
Organizational Unit Name (eg, section) []:linux
Common Name (eg, your name or your server's hostname) []:dr
Email Address []:dr@1314.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@RS1 ssl]#
[root@RS1 ssl]# ls
httpd.csr httpd.key
[root@RS1 ssl]# scp httpd.csr root@192.168.91.129:/root/
The authenticity of host '192.168.91.129 (192.168.91.129)' can't be established.
ECDSA key fingerprint is SHA256:Z3HMzqS6THCLCxpluX/FENh3Ag0hppqEQar7Klpf2LU.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.91.129' (ECDSA) to the list of known hosts.
root@192.168.91.129's password:
httpd.csr 100% 1025 280.9KB/s 00:00
//在DR中查看
[root@DR ~]# ls
anaconda-ks.cfg cmake Desktop Documents Downloads httpd.csr initial-setup-ks.cfg
//CA签署证书并发给RS1
[root@DR ~]# mkdir /etc/pki/CA/newcerts
[root@DR ~]# touch /etc/pki/CA/index.txt
[root@DR ~]# echo "01" > /etc/pki/CA/serial
[root@DR ~]# openssl ca -in httpd.csr -out httpd.crt -days 1024
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 1 (0x1)
Validity
Not Before: Sep 27 06:57:45 2022 GMT
Not After : Jul 17 06:57:45 2025 GMT
Subject:
countryName = CN
stateOrProvinceName = hubei
organizationName = runtime
organizationalUnitName = linux
commonName = dr
emailAddress = dr@1314.com
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
2F:0E:AD:05:5C:72:ED:18:44:EF:9B:CC:D4:8A:FA:98:E7:5E:9A:43
X509v3 Authority Key Identifier:
keyid:BC:33:75:57:47:33:5A:3E:EB:17:8E:7B:37:E2:80:B1:BB:B2:4D:5E
Certificate is to be certified until Jul 17 06:57:45 2025 GMT (1024 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
[root@DR ~]# ls
anaconda-ks.cfg Desktop Downloads httpd.csr Music Public Videos
cmake Documents httpd.crt initial-setup-ks.cfg Pictures Templates
//将CA签署的证书httpd.crt和服务器的证书cacert.pem发送给RS1
[root@DR ~]# scp httpd.crt root@192.168.91.134:/etc/httpd/ssl
[root@DR ~]# scp /etc/pki/CA/cacert.pem root@192.168.91.134:/etc/httpd/ssl
//RS2配置https
[root@RS2 ~]# yum -y install mod_ssl
[root@RS2 ~]# mkdir /etc/httpd/ssl
//RS1中把RS1的证书和密钥发送给RS2
[root@RS1 ~]# cd /etc/httpd/ssl/
[root@RS1 ssl]# scp cacert.pem httpd.crt httpd.key root@192.168.91.139:/etc/httpd/ssl
//在RS1中修改https的配置文件
[root@RS1 ssl]# vim /etc/httpd/conf.d/ssl.conf
SSLCertificateFile /etc/httpd/ssl/httpd.crt
SSLCertificateKeyFile /etc/httpd/ssl/httpd.key
SSLCACertificateFile /etc/httpd/ssl/cacert.pem
[root@RS1 ssl]# systemctl restart httpd.service
[root@RS1 ssl]# ss -anlt |grep 443
LISTEN 0 128 *:443 *:*
//在RS2中修改https的配置文件
[root@RS2 ~]# vim /etc/httpd/conf.d/ssl.conf
SSLCertificateFile /etc/httpd/ssl/httpd.crt
SSLCertificateKeyFile /etc/httpd/ssl/httpd.key
SSLCACertificateFile /etc/httpd/ssl/cacert.pem
[root@RS2 ~]# systemctl restart httpd.service
[root@RS2 ~]# ss -anlt|grep 443
LISTEN 0 128 *:443 *:*
//在DR中添加规则
[root@DR ~]# ipvsadm -A -t 192.168.237.10:443 -s rr
[root@DR ~]# ipvsadm -a -t 192.168.237.10:443 -r 192.168.91.134 -m
[root@DR ~]# ipvsadm -a -t 192.168.237.10:443 -r 192.168.91.139 -m
[root@DR ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.237.10:80 rr
-> 192.168.91.134:80 Masq 1 0 0
-> 192.168.91.139:80 Masq 1 0 0
TCP 192.168.237.10:443 rr
-> 192.168.91.134:443 Masq 1 0 0
-> 192.168.91.139:443 Masq 1 0 0
//客户端测试
[root@Client ~]# curl -k https://192.168.237.10:443
RS1
[root@Client ~]# curl -k https://192.168.237.10:443
RS2
[root@Client ~]# curl -k https://192.168.237.10:443
RS1
[root@Client ~]# curl -k https://192.168.237.10:443
RS2
配置lvs-dr模式的httpd负载集群
Lvs服务器(DR) DIP 192.168.91.129 VIP 192.168.91.100
Apache服务器(RS1) RIP 192.168.91.134 VIP 192.168.91.100
Apache服务器(RS2) RIP 192.168.91.139 VIP 192.168.91.100
client客户端 IP 192.168.91.145
//配置httpd
RS1:
关闭防火墙和selinux
[root@rs1 ~]# systemctl stop firewalld
[root@rs1 ~]# systemctl disable firewalld
[root@rs1 ~]# sed -i s/SELINUX=enforcing/SELINUX=disabled/g /etc/selinux/config
安装httpd
[root@rs1 ~]# yum -y install httpd
[root@rs1 ~]# echo "RS1" > /var/www/html/index.html
[root@rs1 ~]# systemctl restart httpd
[root@rs1 ~]# systemctl enable httpd
RS2:
关闭防火墙和selinux
[root@RS2 ~]# systemctl stop firewalld
[root@RS2 ~]# systemctl disable firewalld
[root@RS2 ~]# sed -i s/SELINUX=enforcing/SELINUX=disabled/g /etc/selinux/config
安装httpd
[root@RS2 ~]# yum -y install httpd
[root@RS2 ~]# echo "RS2" > /var/www/html/index.html
[root@RS2 ~]# systemctl restart httpd
[root@RS2 ~]# systemctl enable httpd
LVS上配置ip:
DR:
//关闭防火墙和selinux
[root@DR ~]# systemctl stop firewalld
[root@DR ~]# systemctl disable firewalld
[root@DR ~]# sed -i s/SELINUX=enforcing/SELINUX=disabled/g /etc/selinux/config
//临时生效
[root@DR ~]# ifconfig lo 192.168.91.100 broadcast 192.168.91.100 netmask 255.255.255.255 up
//永久生效
[root@DR ~]# vim /etc/rc.d/rc.local
ifconfig lo 192.168.91.100 broadcast 192.168.91.100 netmask 255.255.255.255 up
[root@DR ~]# chmod +x /etc/rc.d/rc.local
[root@DR ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 192.168.91.100/32 brd 192.168.91.100 scope global lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:b8:32:24 brd ff:ff:ff:ff:ff:ff
inet 192.168.91.129/24 brd 192.168.91.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:feb8:3224/64 scope link noprefixroute
valid_lft forever preferred_lft forever
//RS上配置arp内核参数
RS1和RS2上都需要操作
vim /etc/sysctl.conf
#将对应网卡设置为只回应目标IP为自身接口地址的ARP请求
net.ipv4.conf.all.arp_ignore = 1
#将ARP请求的源IP设置为所有接口的IP,也就是RIP
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
//RS1
[root@RS1 ~]# vim /etc/sysctl.conf
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
[root@RS1 ~]# sysctl -p
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
//RS2
[root@RS2 ~]# vim /etc/sysctl.conf
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
[root@RS2 ~]# sysctl -p
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
//RS上配置VIP
一定要先配置好内核参数,再配置VIP,如果先配置VIP,VIP配置好后会立即通告给所有人,而修改内核参数就是为了不通告。
//LVS服务器的ens33网卡的ip:192.168.91.100作为VIP
两台RS都要做
RS1:
[root@RS1 ~]# ifconfig lo 192.168.91.100 broadcast 192.168.91.100 netmask 255.255.255.255 up
[root@RS1 ~]# ip a
[root@RS1 ~]# ifconfig lo 192.168.91.100 broadcast 192.168.91.100 netmask 255.255.255.255 up
[root@RS1 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 192.168.91.100/32 brd 192.168.91.100 scope global lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:70:9e:3b brd ff:ff:ff:ff:ff:ff
inet 192.168.91.134/24 brd 192.168.91.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe70:9e3b/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@RS2 ~]# ifconfig lo 192.168.91.100 broadcast 192.168.91.100 netmask 255.255.255.255 up
[root@RS2 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 192.168.91.100/32 brd 192.168.91.100 scope global lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:33:c1:e3 brd ff:ff:ff:ff:ff:ff
inet 192.168.91.139/24 brd 192.168.91.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe33:c1e3/64 scope link noprefixroute
valid_lft forever preferred_lft forever
//添加路由信息
RS1:
[root@RS1 ~]# route add -host 192.168.100.100/32 dev lo
RS2:
[root@RS2 ~]# route add -host 192.168.100.100/32 dev lo
//添加并保存规则
[root@DR ~]# ipvsadm -A -t 192.168.91.100:80 -s rr
[root@DR ~]# ipvsadm -a -t 192.168.91.100:80 -r 192.168.91.134:80 -g
[root@DR ~]# ipvsadm -a -t 192.168.91.100:80 -r 192.168.91.139:80 -g
[root@DR ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.91.100:80 rr
-> 192.168.91.134:80 Route 1 0 0
-> 192.168.91.139:80 Route 1 0 0
[root@DR ~]# ipvsadm -Sn > /etc/sysconfig/ipvsadm
[root@DR ~]# cat /etc/sysconfig/ipvsadm
-A -t 192.168.91.100:80 -s rr
-a -t 192.168.91.100:80 -r 192.168.91.134:80 -g -w 1
-a -t 192.168.91.100:80 -r 192.168.91.139:80 -g -w 1
[root@DR ~]# systemctl restart ipvsadm.service
[root@DR ~]# systemctl enable ipvsadm.service
//客户端验证
[root@Client ~]# curl http://192.168.91.100
RS1
[root@Client ~]# curl http://192.168.91.100
RS2
[root@Client ~]# curl http://192.168.91.100
RS1
[root@Client ~]# curl http://192.168.91.100
RS2
TUN模式
DR:
//关闭防火墙和selinux
修改内核参数,开启IP转发
[root@DR ~]# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
[root@DR ~]# sysctl -p
net.ipv4.ip_forward = 1
[root@DR ~]# yum -y install ipvsadm
[root@DR ~]# ifconfig tunl0 192.168.91.55 broadcast 192.168.91.55 netmask 255.255.255.255 up
[root@DR ~]# ip a
.....
4: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN group default qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
inet 192.168.91.55/32 brd 192.168.91.55 scope global tunl0
valid_lft forever preferred_lft forever
//RS1和RS2(两台主机操作一样)
关闭防火墙和selinux,部署httpd
//启用ipip模块
RS1
[root@rs1 ~]# modprobe ipip
[root@rs1 ~]# ifconfig tunl0 192.168.91.55 broadcast 192.168.91.55 netmask 255.255.255.255 up
RS2
[root@rs2 ~]# modprobe ipip
[root@rs2 ~]# ifconfig tunl0 192.168.91.55 broadcast 192.168.91.55 netmask 255.255.255.255 up
//修改内核参数为
RS1:
[root@RS1 ~]# vim /etc/sysctl.conf
[root@RS1 ~]# sysctl -p
net.ipv4.conf.tunl0.arp_ignore = 1
net.ipv4.conf.tunl0.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.tunl0.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
RS2:
[root@RS2 ~]# vim /etc/sysctl.conf
[root@RS2 ~]# sysctl -p
net.ipv4.conf.tunl0.arp_ignore = 1
net.ipv4.conf.tunl0.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.tunl0.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
//DR上添加规则:
[root@DR ~]# ipvsadm -A -t 192.168.91.55:80 -s rr
[root@DR ~]# ipvsadm -a -t 192.168.91.55:80 -r 192.168.91.134 -i
[root@DR ~]# ipvsadm -a -t 192.168.91.55:80 -r 192.168.91.139 -i
[root@DR ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.91.55:80 rr
-> 192.168.91.134:80 Tunnel 1 0 0
-> 192.168.91.139:80 Tunnel 1 0 0
[root@DR ~]# ipvsadm -Sn > /etc/sysconfig/ipvsadm
[root@DR ~]# systemctl restart ipvsadm.service
//客户端验证:
[root@Client ~]# curl http://192.168.91.55
RS1
[root@Client ~]# curl http://192.168.91.55
RS2
[root@Client ~]# curl http://192.168.91.55
RS1
[root@Client ~]# curl http://192.168.91.55
RS2