Linux 虚拟服务器

网络协议原理

lvs

1
2
3
4
5
cd /proc/$$/fd
exec 8<> /dev/tcp/www.baidu.com/80
echo -e 'GET / HTTP/1.0\n' >& 8
cat <& 8
exec 8<&-

lvs

lvs

lvs

1
2
3
[root@localhost /]# ping www.baidu.com
PING www.a.shifen.com (14.215.177.39) 56(84) bytes of data.
64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=1 ttl=54 time=6.07 ms

通过PING百度的网络,能够看到百度的IP地址:14.215.177.39,那么我们的路由器是如何找到这个请求该往哪里发呢?

通过将百度的地址与路由表中的子网掩码(Genmask)进行按位与运算,计算出来的结果如果和目标地址(Destination)匹配,就会找到下一跳的路由地址(Gateway)。

最后匹配上的条目是 14.215.177.39 & 0.0.0.0 = 0.0.0.0 -> 192.168.8.2

通过计算得知,数据包想出局域网,最终它将会经过Gateway = 192.168.8.2

LVS

lvs

如Nginx,他是一个7层的反向代理服务器,它需要在中间层建立三次握手,效率会有损耗,而LVS是一个四层代理服务器,它将请求穿透到后台服务器。

lvs

lvs

D-NAT

lvs

DR

lvs

TUN

lvs

隐藏IP

lvs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
隐藏VIP方法:对外隐藏,对内可见 :

kernel parameter:
目标mac地址为全F,交换机触发广播
/proc/sys/net/ipv4/conf/*IF*/
arp_ignore: 定义接收到ARP请求时的响应级别;
0:只要本地配置的有相应地址,就给予响应;
**1:仅在请求的目标(MAC)地址配置请求**
到达的接口上的时候,才给予响应;

arp_announce:定义将自己地址向外通告时的通告级别;
0:将本地任何接口上的任何地址向外通告;
1:试图仅向目标网络通告与其网络匹配的地址;
**2:仅向与本地接口上地址匹配的网络进行通告;**

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
四种静态: 
rr:轮循
wrr:
dh:
sh:

动态调度方法:
lc: 最少连接
wlc: 加权最少连接
sed: 最短期望延迟
nq: never queue
LBLC: 基于本地的最少连接
DH:
LBLCR: 基于本地的带复制功能的最少连接

LVS怎么知道每一台Server有多少连接呢?

偷窥策略,每一个Client通过LVS发起TCP的三次握手,LVS最少能收到两次Client发送的ACK确认,这时候认为连接数+1,当TCP四次分手时收到FIN和ACK之后,认为连接数-1。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ipvs内核模块
yum install ipvsadm -y

管理集群服务
添加:-A -t|u|f service-address [-s scheduler]
-t: TCP协议的集群
-u: UDP协议的集群
service-address: IP:PORT
-f: FWM: 防火墙标记
service-address: Mark Number
修改:-E
删除:-D -t|u|f service-address

ipvsadm -A -t 192.168.9.100:80 -s rr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
管理集群服务中的RS
添加:-a -t|u|f service-address -r server-address [-g|i|m] [-w weight]
-t|u|f service-address:事先定义好的某集群服务
-r server-address: 某RS的地址,在NAT模型中,可使用IP:PORT实现端口映射;
[-g|i|m]: LVS类型
-g: DR
-i: TUN
-m: NAT
[-w weight]: 定义服务器权重
修改:-e
删除:-d -t|u|f service-address -r server-address
# ipvsadm -a -t 172.16.100.1:80 -r 192.168.10.8 –g
# ipvsadm -a -t 172.16.100.1:80 -r 192.168.10.9 -g
查看
-L|l
-n: 数字格式显示主机地址和端口
--stats:统计数据
--rate: 速率
--timeout: 显示tcp、tcpfin和udp的会话超时时长
-:c 显示当前的ipvs连接状况
删除所有集群服务
-C:清空ipvs规则
保存规则
-S
# ipvsadm -S > /path/to/somefile
载入此前的规则:
-R
# ipvsadm -R < /path/form/somefile

lvs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
LVS:

node01:
#创建对外提供的VIP地址 网卡eth0:8
ifconfig eth0:8 192.168.150.100/24
node02~node03:
1)修改内核:
echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
2)设置隐藏的vip:
ifconfig lo:3 192.168.150.100 netmask 255.255.255.255

RealServer中的服务:
node02~node03:
#部署一个简单版本的webServer
yum install httpd -y
service httpd start
vi /var/www/html/index.html
from 192.168.150.1x

LVS服务配置
node01:
yum install ipvsadm
# —A 设置他的负载均衡模式
ipvsadm -A -t 192.168.150.100:80 -s rr
# -a 设置VIP的下一跳路由规则和权重
ipvsadm -a -t 192.168.150.100:80 -r 192.168.150.12 -g -w 1
ipvsadm -a -t 192.168.150.100:80 -r 192.168.150.13 -g -w 1
ipvsadm -ln

验证:
浏览器访问 192.168.150.100 看到负载 疯狂F5
node01:
netstat -natp 结论看不到socket连接
node02~node03:
netstat -natp 结论看到很多的socket连接
node01:
ipvsadm -lnc 查看偷窥记录本
TCP 00:57 FIN_WAIT 192.168.150.1:51587 192.168.150.100:80 192.168.150.12:80
FIN_WAIT: 连接过,偷窥了所有的包
SYN_RECV: 基本上lvs都记录了,证明lvs没事,一定是后边网络层出问题

Keepalived

lvs

通过配置主备Keepalived,当主机Master挂了后,Keepalived会通过IP漂移技术,将192.168.150.100漂移到node04结点备机BackUp机器上,确保了LVS的单点故障问题。

并且在LVS中配置了健康检查,校验Real Server的健康状态,确保故障时LVS能够及时得把他从负载均衡列表中移除。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
keepalived实验:
主机: node01~node04

node01:
ipvsadm -C
ifconfig eth0:8 down

----------------------------
node01,node04:
yum install keepalived ipvsadm -y
配置:
cd /etc/keepalived/
cp keepalived.conf keepalived.conf.bak
vi keepalived.conf
node01:
vrrp:虚拟路由冗余协议!
vrrp_instance VI_1 {
state MASTER // node04 BACKUP
interface eth0
virtual_router_id 51
priority 100 // node04 50
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.150.100/24 dev eth0 label eth0:8
#等同于LVS的:ifconfig eth0:8 192.168.150.100/24
}
}

#vip配置
virtual_server 192.168.150.100 80 {
delay_loop 6
#轮训
lb_algo rr
#模式
lb_kind DR
nat_mask 255.255.255.0
#在多少秒内发送同一台RealServer
persistence_timeout 0
protocol TCP

real_server 192.168.150.12 80 {
weight 1
HTTP_GET {
url {
#健康检查URL
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.150.13 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
scp ./keepalived.conf root@node04:`pwd`
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#node1、node4 启动keepAlived
service keepalived start

验证:
#查看LVS的负载均衡配置
ipvsadm -ln

#查看主机和备机的偷窥记事本请求情况
ipvsadm -lnc

#node01 主动挂掉网卡,再查看node4的网卡配置,IP是否漂移,偷窥记事本是否有请求
ifconfig eth0 down
#node01 启动网卡,查看IP和请求是否漂移回主机
ifconfig eth0 up

如果Nnode01的KeepAlived挂了,就会导致导致Node04的KeepAlived无法接收到Node01的健康通知,就会抢过它的IP,这时候就会导致有两台机器有两个对外暴露的相同IP,会导致客户端发送的数据造成混乱。

通过ZooKeeper集群进行保证KeepAlived的存活。

最后更新: 2020年11月24日 21:42

原始链接: https://midkuro.gitee.io/2020/11/23/lvs-keepalived/

× 请我吃糖~
打赏二维码