[16] LVS+KeepAlived

发布时间 2023-12-12 14:21:32作者: tree6x7

1. 构建高可用集群

1.1 高可用集群

什么是高可用集群

高可用集群(High Availability Cluster,简称 HA Cluster),是指以减少服务中断时间为目的的服务器集群技术。它通过保护用户的业务程序对外部不间断的提供服务,把因为软件、硬件造成的故障对业务的影响降低到最小程度。总而言之就是保证公司业务 7*24 小时不宕机。

高可用衡量标准

衡量集群的可用性(HA)高低,可以从 MTTF(平均无故障时间)和 MTTR(平均故障维修时间)进行考量,公式为:HA=MTTF/(MTTF+MTTR)*100%,具体衡量标准可以参考下表:

可用性高低 9 % 年度宕机时间
基本可用性 2个9 99% 87.6H
较高可用性 3个9 99.9% 8.8H
具有故障自动恢复 4个9 99.99% 53min
极高可用性 5个9 99.999% 5min

1.2 高可用保障

对集群中的服务器进行负载均衡、健康监测,并在服务器出现故障时能进行故障转移,自动切换到正常服务器是高可用保障的必要手段。

a. 负载均衡

常见的负载均衡手段如下:

  • 硬件负载均衡,如 F5
  • 软件负载均衡,如 Nginx、HA Proxy、LVS

几种软件负载均衡技术比较:

技术 优点 缺点
Nginx 可以针对 http 应用做一些分流的策略;对网络稳定性的依赖非常小。安装和配置简单,测试方便,能支撑几万的并发量,可作为静态网页和图片服务器。 仅支持 http、https 和 email 协议,只支持通过端口进行健康检测。
HA Proxy 支持通过 URL 进行健康检测,单纯做负载均衡,效率高于 Nginx 支持 TCP 的负载均衡,可以对 MySQL 集群负载。 不支持 POP/SMTP 协议,不支持 HTTP cache 功能,多进程模式支持不够好,重载配置需要重启进程。
LVS 抗负载能力强,工作在网络层,性能最好。配置性比较低,工作稳定,只分发请求,无流量产生,保证 IO 性能。应用范围比较广 不支持正则表达式处理,不能做动静分离。大型网站实施复杂,没有专门用于 windows 的版本。

关于“4层负载”和“7层负载”

LVS(Linux Virtual Server)是一种基于 Linux 的负载均衡技术,它在网络层(第四层,即传输层)进行负载均衡。而 Nginx 是一种开源的高性能 Web 服务器和反向代理服务器,它在应用层(第七层,即应用层)进行负载均衡。

在计算机网络中,负载均衡是指将网络流量(如请求、连接)分发到多个服务器,以使服务器资源得到充分利用并提高系统的可扩展性和可靠性。

负载均衡可以在不同的层级上进行,常见的有 4 层负载均衡和 7 层负载均衡:

  1. 4 层负载均衡(也称为传输层负载均衡):在传输层(第 4 层)对网络流量进行负载均衡,主要基于 IP 地址和端口号。LVS 就是一种 4 层负载均衡技术,它可以根据 IP 地址和端口来将请求转发到不同的后端服务器。4 层负载均衡通常用于处理大量的网络连接和数据转发。
  2. 7 层负载均衡(也称为应用层负载均衡):在应用层(第 7 层)对网络流量进行负载均衡,主要基于应用协议(如 HTTP、HTTPS)。Nginx 就是一种 7 层负载均衡服务器,它可以根据请求的内容(如 URL、HTTP 头部信息)来决定将请求发送到哪个后端服务器。7 层负载均衡通常用于 Web 服务器、反向代理和请求处理等任务。

通过在不同的层级上进行负载均衡,可以根据具体的需求选择适合的技术,并灵活地实现高性能、高可用性的系统架构。

b. 健康监测和自动切换

常见的健康监测和自动切换软件有 Keepalived 和 Heartbeat,其二者对比如下:

  • Keepalived 使用更简单:从安装、配置、使用、维护等角度上对比,Keepalived 都比 Heartbeat 要简单;
  • Heartbeat 功能更强大:Heartbeat 虽然复杂,但功能更强大,配套工具更全,适合做大型集群管理,而 Keepalived 主要用于集群倒换,基本没有管理功能。

1.3 高可用拓扑

2. LVS

2.1 LVS 简介

LVS 是 Linux Virtual Server 的简写,在 1998 年 5 月由章文嵩博士成立。

工作在 OSI 模型的四层,基于 IP 进行负载均衡。

在 Linux2.2 内核时,IPVS 就已经以内核补丁的形式出现。从 2.4 版本以后,IPVS 已经成为 Linux 官方标准内核的一部分。

针对高可伸缩、高可用网络服务的需求,我们给出了基于 IP 层和基于内容请求分发的负载平衡调度解决方法,并在 Linux 内核中实现了这些方法,将一组服务器构成一个实现可伸缩的、高可用网络服务的虚拟服务器。

虚拟服务器的体系结构如图所示,一组服务器通过高速的局域网或者地理分布的广域网相互连接,在它们的前端有一个负载调度器(Load Balancer)。负载调度器能无缝地将网络请求调度到真实服务器上,从而使得服务器集群的结构对客户是透明的,客户访问集群系统提供的网络服务就像访问一台高性能、高可用的服务器一样。

目前,LVS 项目已提供了一个实现可伸缩网络服务的 Linux Virtual Server 框架,如图所示。在 LVS 框架中,提供了含有 3 种 IP 负载均衡技术的 IP 虚拟服务器软件 IPVS、基于内容请求分发的内核 Layer-7 交换机 KTCPVS 和集群管理软件。可以利用 LVS 框架实现高可伸缩的、高可用的 Web、Cache、Mail 和 Media 等网络服务。

在调度器的实现技术中,IP 负载均衡技术是效率最高的。在已有的 IP 负载均衡技术中有通过网络地址转换(Network Address Translation)将一组服务器构成一个高性能的、高可用的虚拟服务器,我们称之为 VS/NAT 技术(Virtual Server via Network Address Translation)。在分析 VS/NAT 的缺点和网络服务的非对称性的基础上,我们提出通过 IP 隧道实现虚拟服务器的方法 VS/TUN (Virtual Server via IP Tunneling),和通过直接路由实现虚拟服务器的方法 VS/DR(Virtual Server via Direct Routing),它们可以极大地提高系统的伸缩性。所以,IPVS 软件实现了这三种 IP 负载均衡技术,它们的大致原理如下:

  1. Virtual Server via Network Address Translation(VS/NAT)
    通过网络地址转换,调度器重写请求报文的目标地址,根据预设的调度算法,将请求分派给后端的真实服务器;真实服务器的响应报文通过调度器时,报文的源地址被重写,再返回给客户,完成整个负载调度过程。
  2. Virtual Server via IP Tunneling(VS/TUN)
    采用 NAT 技术时,由于请求和响应报文都必须经过调度器地址重写,当客户请求越来越多时,调度器的处理能力将成为瓶颈。为了解决这个问题,调度器把请求报文通过IP隧道转发至真实服务器,而真实服务器将响应直接返回给客户,所以调度器只处理请求报文。由于一般网络服务应答比请求报文大许多,采用 VS/TUN 技术后,集群系统的最大吞吐量可以提高 10 倍。
  3. Virtual Server via Direct Routing(VS/DR)
    VS/DR 通过改写请求报文的 MAC 地址,将请求发送到真实服务器,而真实服务器将响应直接返回给客户。同 VS/TUN 技术一样,VS/DR 技术可极大地 提高集群系统的伸缩性。这种方法没有 IP 隧道的开销,对集群中的真实服务器也没有必须支持 IP 隧道协议的要求,但是要求调度器与真实服务器都有一块网卡连在同一物理网段上。

2.2 LVS 拓扑

术语(缩写) 说明
LVS 服务器(DS) /
集群中节点服务器(RS) /
虚拟 IP 地址(VIP) 用于向客户端提供服务的 IP 地址(配置于负载均衡器上)
真实服务器的 IP 地址(RIP) 集群中节点服务器的 IP 地址
负载均衡器 IP 地址(DIP) 负载均衡器的物理网卡上的 IP 地址
客户端主机 IP 地址(CIP) 终端请求用户的主机 IP 地址

LVS 负载均衡调度技术是在 Linux 内核中实现的,使用配置 LVS 时,不是直接配置内核中的 IPVS,而是通过 IPVS 的管理工具 IPVSADM 来管理配置,LVS 集群负载均衡器接受所有入站客户端的请求,并根据算法来决定由哪个集群的节点来处理请求。

2.3 三种工作模式

实现虚拟服务的相关方法

在网络服务中,一端是客户程序,另一端是服务程序,在中间可能有代理程序。由此看来,可以在不同的层次上实现多台服务器的负载均衡。用集群解决网络服务性能问题的现有方法主要分为以下四类。

  1. 基于RR-DNS的解决方法
  2. 基于客户端的解决方法
  3. 基于应用层负载均衡调度的解决方法
  4. 基于 IP 层负载均衡调度的解决方法

LVS 集群中实现的三种 IP 负载均衡技术(VS/NAT、VS/TUN、VS/DR)的工作原理。

a. NAT 模式

由于 IPv4 中 IP 地址空间的日益紧张和安全方面的原因,很多网络使用保留 IP 地址(10.0.0.0/255.0.0.0、 172.16.0.0/255.128.0.0 和 192.168.0.0/255.255.0.0)[64, 65, 66]。这些地址不在 Internet 上使用,而是专门为内部网络预留的。当内部网络中的主机要访问 Internet 或被 Internet 访问时,就需要采用网络地址转换(Network Address Translation,以下简称 NAT),将内部地址转化为 Internets 上可用的外部地址。NAT 的工作原理是报文头(目标地址、源地址和端口等)被正确改写后,客户相信它们连接一个 IP 地址,而不同 IP 地址的服务器组也认为它们是与客户直接相连的。由此,可以用 NAT 方法将不同 IP 地址的并行网络服务变成在一个 IP 地址上的一个虚拟服务。

VS/NAT 的体系结构如图所示。在一组服务器前有一个调度器,它们是通过 Switch/HUB 相连接的。这些服务器提供相同的网络服务、相同的内容,即不管请求被发送到哪一台服务器,执行结果是一样的。服务的内容可以复制到每台服务器的本地硬盘上,可以通过网络文件系统(如 NFS)共享,也可以通过一个分布式文件系统来提供。

客户通过 Virtual IP Address(虚拟服务的 IP 地址)访问网络服务时,请求报文到达调度器,调度器根据连接调度算法从一组真实服务器中选出一台服务器,将报文的目标地址 Virtual IP Address 改写成选定服务器的地址,报文的目标端口改写成选定服务器的相应端口,最后将修改后的报文发送给选出的服务器。同时,调度器在连接 Hash 表中记录这个连接,当这个连接的下一个报文到达时,从连接 Hash 表中可以得到原选定服务器的地址和端口,进行同样的改写操作,并将报文传给原选定的服务器。当来自真实服务器的响应报文经过调度器时,调度器将报文的源地址和源端口改为 Virtual IP Address 和相应的端口,再把报文发给用户。

下面,举个例子来进一步说明 VS/NAT,如图所示:

b. TUN 模式

在 VS/NAT 的集群系统中,请求和响应的数据报文都需要通过负载调度器,则负载调度器将成为整个集群系统的新瓶颈。大多数 Internet 服务都有这样的特点:请求报文较短而响应报文往往包含大量的数据。如果能将请求和响应分开处理,即在负载调度器中只负责调度请求而响应直 接返回给客户,将极大地提高整个集群系统的吞吐量。

IP 隧道(IP tunneling)是将一个 IP 报文封装在另一个 IP 报文的技术,这可以使得目标为一个 IP 地址的数据报文能被封装和转发到另一个 IP 地址。IP 隧道技术亦称为 IP 封装技术(IP encapsulation)。IP 隧道主要用于移动主机和虚拟私有网络(Virtual Private Network),在其中隧道都是静态建立的,隧道一端有一个 IP 地址,另一端也有唯一的 IP 地址。

我们利用 IP 隧道技术将请求报文封装转发给后端服务器,响应报文能从后端服务器直接返回给客户。但在这里,后端服务器有一组而非一个,所以我们不可能静态地建立一一对应的隧道,而是动态地选择一台服务器,将请求报文封装和转发给选出的服务器。这样,我们可以利用 IP 隧道的原理将一组服务器上的网络服务组成在一个 IP 地址上的虚拟网络服务。VS/TUN 的体系结构如图所示,各个服务器将 VIP 地址配置在自己的 IP 隧道设备上。

VS/TUN 的工作流程如下图所示:它的连接调度和管理与 VS/NAT 中的一样,只是它的报文转发方法不同。调度器根据各个服务器的负载情况,动态地选择一台服务器,将请求报文封装在另一个 IP 报文中,再将封装后的 IP 报文转发给选出的服务器;服务器收到报文后,先将报文解封获得原来目标地址为 VIP 的报文,服务器发现 VIP 地址被配置在本地的 IP 隧道设备上,所以就处理这个请求,然后根据路由表将响应报文直接返回给客户。

c. DR 模式

跟 VS/TUN 方法相同,VS/DR 利用大多数 Internet 服务的非对称特点,负载调度器中只负责调度请求,而服务器直接将响应返回给客户,可以极大地提高整个集群 系统的吞吐量。该方法与 IBM 的 NetDispatcher 产品中使用的方法类似(其中服务器上的 IP 地址配置方法是相似的),但 IBM 的 NetDispatcher 是非常昂贵的商品化产品,我们也不知道它内部所使用的机制,其中有些是 IBM 的专利。

VS/DR 的体系结构如图所示:调度器和服务器组都必须在物理上有一个网卡通过不分断的局域网相连,如通过高速的交换机或 HUB 相连。VIP 地址为调度器和服务器组共享,调度器配置的 VIP 地址是对外可见的,用于接收虚拟服务的请求报文;所有的服务器把 VIP 地址配置在各自的 Non-ARP 网络设备上,它对外面是不可见的,只是用于处理目标地址为 VIP 的网络请求。

VS/DR 的工作流程如图8所示:它的连接调度和管理与 VS/NAT 和 VS/TUN 中的一样,它的报文转发方法又有不同,将报文直接路由给目标服务器。在 VS/DR 中,调度器根据各个服务器的负载情况,动态地选择一台服务器,不修改也不封装 IP 报文,而是将数据帧的 MAC 地址改为选出服务器的 MAC 地址,再将修改后的数据帧在与服务器组的局域网上发送。因为数据帧的 MAC 地址是选出的服务器,所以服务器肯定可以收到这个数据帧,从中可以获得该 IP 报文。当服务器发现报文的目标地址 VIP 是在本地的网络设备上,服务器处理这个报文,然后根据路由表将响应报文直接返回给客户。

在 VS/DR 中,根据缺省的 TCP/IP 协议栈处理,请求报文的目标地址为 VIP,响应报文的源地址肯定也为 VIP,所以响应报文不需要作任何修改,可以直接返回给客户,客户认为得到正常的服务,而不会知道是哪一台服务器处理的。

d. 小结

NAT(Network Address Translation)模式是基于 NAT 技术实现的。在此模式中,LVS 服务器既要处理请求的接入,又要处理请求的响应。因此存在较大的性能瓶颈。

DR(Direct Routing)模式是 LVS 的默认工作模式,也叫直接路由模式。只处理请求的接入,不处理请求的响应。因此性能高,瓶颈小。

TUN(Tunneling)模式需要服务器支持 IP 隧道(IP Tunneling,是路由器把一种网络层协议封装到另一个协议中以跨过网络传送到另一个路由器的处理过程)技术,限制较大,一般不用。

2.4 LVS 调度算法

(1)静态调度算法

调度算法 说 明
RR RoundRobin 轮询调度
WRR Weighted RR 加权轮询调度
SH Soure Hashing 源地址哈希调度
DH Destination Hashing 目标地址哈希调度

(2)动态调度算法

调度算法 说 明
LC Least Connections 最小连接数调度
WLC Weighted LC 加权最小连接数调度(默认
SED Shortest Expection Delay 初始连接高权重优先
NQ Nerver Queue 第一轮平均分配,后续 SED
LBLC Locality-Based LC 动态的 DH 算法
LBLCR LBLC with Replication 带复制功能的 LBLC
FO Weighted Fail Over,Linux 内核 4.15 后新增的调度算法
OVF Overflow-connection,Linux 内核 4.15 后新增的调度算法

2.5 LVS 基本命令

【LVS 安装】yum install ipvsadm

对于 LVS 的操作,主要是通过 ipvsadm 软件实现,常用的 LVS 操作命令如下:

(1)集群服务管理

命令 说 明
ipvsadm -A -t [IP] -s [调度算法] 此命令用来添加一个 lvs 策略,IP 指 VIP,调度算法是 12 种调度算法的一种
ipvsadm -C 此命令用来清除一个 lvs 策略
ipvsadm -S 此命令用来保存一个 lvs 策略
ipvsadm -R 此命令用来加载一个 lvs 策略
ipvsadm -L 此命令用来查看策略

(2)集群 RS 管理

$ ipvsadm -a -t [IP1] -r [IP2] -m|g|i

-a:添加一个新的虚拟服务器。
-t:指定虚拟服务器的 IP 地址。IP1 表示要代理的虚拟服务器 IP 地址。
-r:指定实际后端服务器的 IP 地址。IP2 表示实际后端服务器的 IP 地址。
-m|g|i:指定调度算法,用于在多个实际后端服务器之间分配流量。
  -m 表示使用 NAT 调度算法(Masquerading)
  -g 表示使用 LVS-TUN 调度算法(Tunneling)
  -i 表示使用 DR 调度算法(Direct Routing)
  
# 例如,以下命令将添加一个虚拟服务器,该服务器的 IP 地址为 192.168.10.100,将负载均衡到两个实际后端服务器的 IP 地址分别为 192.168.10.101 和 192.168.10.102,使用 DR 调度算法:ipvsadm -a -t 192.168.10.100 -r 192.168.10.101 -r 192.168.10.102 -i

$ ipvsadm -d -t [IP1] -r [IP2]

-d:删除一个虚拟服务器的实际后端服务器。
-t:指定虚拟服务器的 IP 地址。IP1 表示要删除实际后端服务器的虚拟服务器 IP 地址。
-r:指定要删除的实际后端服务器的 IP 地址。IP2 表示要删除的实际后端服务器的 IP 地址。

# 举个例子,假设我们要从虚拟服务器 192.168.1.100 中删除实际后端服务器 192.168.1.101,可以使用命令:ipvsadm -d -t 192.168.1.100 -r 192.168.1.101

2.6 LVS 实战

a. NAT 模式实战

RS1 和 RS2 配置

(1)配置网卡为 NAT 模式,RS1 设置静态 IP 为 192.168.10.31,RS2 设置静态 IP 为 192.168.10.32。

(2)下载安装 httpd 服务

$ yum install -y httpd

(3)设置首页内容 // RS2 把内容改为 'this is RS2'

$ echo this is RS01 > /var/www/html/index.html

(4)启动 httpd

$ systemctl start httpd

(5)在 RS1 和 RS2 上测试访问,能输出 this is RS01 或 this is RS02 即为成功

[root@rs01 ~]# curl localhost
this is RS01

(6)RS1 和 RS2 指定网关为 192.168.10.30,子网掩码 255.255.255.0

# 设置默认网关为 192.168.10.30
# ip route add default via ______ dev ______
$ ip route add default via 192.168.10.30 dev ens33

# 删除本条路由规则,仅需把 add 换成 del 即可

(7)查看网关是否生效

[root@linux31 network-scripts]# route -n
-bash: route: 未找到命令
[root@linux31 network-scripts]# yum install -y net-tools
[root@linux31 network-scripts]# systemctl restart network
[root@linux31 network-scripts]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.10.30   0.0.0.0         UG    100    0        0 ens33
192.168.10.0    0.0.0.0         255.255.255.0   U     100    0        0 ens33

LVS 服务器配置

(1)安装 ipvsadm

$ yum install -y ipvsadm

(2)设置双网卡

  • 仅主机网卡一块 ens37,IP 配置为 192.168.3.30,此 IP 是接收外部请求的 VIP
  • NAT 网卡一块 ens33,IP 配置为 192.168.10.30,此 IP 是与后端 RS 服务器通信的 DIP

(3)配置 ip_forward 转发

$ vi /etc/sysctl.conf
# ## 添加如下内容并保存退出 ##
# net.ipv4.ip_forward = 1
# ########################

# 执行如下命令使修改生效
$ sysctl -p

(4)使用 ipvsadm 进行负载均衡配置

# 指定负载80端口的VIP,并指定调度策略为轮询(RR)
$ ipvsadm -A -t 192.168.3.30:80 -s rr

# 添加两台RS,并指定负载均衡工作模式为 NAT
$ ipvsadm -a -t 192.168.3.30:80 -r 192.168.10.31 -m
$ ipvsadm -a -t 192.168.3.30:80 -r 192.168.10.32 -m

# 查看上述配置是否生效
$ 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.10.30:80 rr
  -> 192.168.10.31:80             Masq    1      0          0
  -> 192.168.10.32:80             Masq    1      0          0

client 测试

配置网卡为仅主机模式,IP 为 192.168.3.31,网关无需配置即可。

在 client 上测试负载均衡效果:

[root@localhost ~]# curl 192.168.3.30
this is RS02
[root@localhost ~]# curl 192.168.3.30
this is RS01
[root@localhost ~]# curl 192.168.3.30
this is RS02
[root@localhost ~]# curl 192.168.3.30
this is RS01

NAT 模式存在的问题 => LVS 性能瓶颈

b. DR 模式实战

ARP(Address Resolution Protocol)地址解析协议,是根据 IP 地址获取物理地址(MAC)的一个 TCP/IP 协议。主机发送信息时将包含目标 IP 地址的 ARP 请求广播到局域网络上的所有主机,并接收返回消息,以此确定目标的物理地址;收到返回消息后将该 IP 地址和物理地址存入本机 ARP 缓存中并保留一定时间,下次请求时直接查询 ARP 缓存以节约资源。

通过对比 NAT 模式和 DR 模式的拓扑图可以发现,需要让 LVS 和 RS 在同一个网段,并且在两个 RS 服务器上也需要绑定 VIP。所以 DR 模式实验可以在刚才的基础上进行,步骤如下:

(1)在 RS1 和 RS2 上进行 ARP 抑制操作,并配置 VIP 到 lo 网卡上:

# [1] rs1,rs2 上都配置ARP抑制
# arp_ignore: default 0
$ echo 1 > /proc/sys/net/ipv4/conf/ens33/arp_ignore
$ echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
# arp_announce: default 0
$ echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
$ echo 2 > /proc/sys/net/ipv4/conf/ens33/arp_announce

# [2] rs1,rs2 都删掉NAT模式增加的网关配置,然后重启
$ ip route del default via 192.168.10.30 dev ens33
$ systemctl restart network

# [3] rs1,rs2 均配置VIP到lo网卡,这里的子网掩码需要 4 个 255
$ ifconfig lo:9 192.168.10.34 netmask 255.255.255.255
# 这个命令的作用是在回环接口 lo 上创建一个别名接口 lo:9,并为该别名接口分配 IP 地址 192.168.10.34,使用子网掩码 255.255.255.255。
# - ifconfig:网络接口配置工具的命令。
# - lo:9:表示要创建的别名接口名为 lo:9。lo 代表回环接口,而 :9 是别名的编号,可以是任意数字。
# - 192.168.10.34:指定别名接口 lo:9 的 IP 地址。
# - netmask 255.255.255.255:指定别名接口 lo:9 的子网掩码。
# 这个命令的效果是在回环接口上创建了一个额外的逻辑接口(别名接口),这个逻辑接口拥有独立的 IP 地址。
# 通常情况下,回环接口 lo 只有一个 IP 地址(127.0.0.1),用于本地回环通信。
# 通过创建别名接口,可以在同一个物理回环接口上绑定多个 IP 地址,从而实现更灵活的网络配置。
# 在这个例子中,创建的别名接口 lo:9 具有 IP 地址 192.168.10.34,子网掩码为 255.255.255.255。
# 子网掩码 255.255.255.255 表示这个别名接口是一个点对点连接,没有网络位,所有的地址位都是主机位。

$ ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.31  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 fe80::3b38:154b:fc3d:6269  prefixlen 64  scopeid 0x20<link>
        ether 00:50:56:2e:d2:bc  txqueuelen 1000  (Ethernet)
        RX packets 4124  bytes 4025075 (3.8 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2066  bytes 181284 (177.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 10  bytes 1062 (1.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 10  bytes 1062 (1.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo:9: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 192.168.10.34  netmask 255.255.255.255
        loop  txqueuelen 1000  (Local Loopback)

(2)在 LVS 的 ens33 网卡上绑定 VIP:192.168.10.34

# 在 LVS 服务器上关闭NAT测试的 ens37 网卡
$ ifdown ens37
$ ifconfig ens37 down

# ens33 绑定VIP
$ ifconfig ens33:9 192.168.10.34/24
$ ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.30  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 fe80::db30:9838:de0e:8127  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::6d7c:9692:c7a8:6320  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::3b38:154b:fc3d:6269  prefixlen 64  scopeid 0x20<link>
        ether 00:50:56:2d:6c:7f  txqueuelen 1000  (Ethernet)
        RX packets 1246  bytes 543590 (530.8 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 711  bytes 76124 (74.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33:9: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.34  netmask 255.255.255.0  broadcast 192.168.10.255
        ether 00:50:56:2d:6c:7f  txqueuelen 1000  (Ethernet)

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        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

(3)在 LVS 服务器上清空 LVS 策略,并重新设置 DR 模式策略。

# 查看策略
[root@linux30 ~]# 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.3.30:80 rr
  -> 192.168.10.31:80             Masq    1      0          0
  -> 192.168.10.32:80             Masq    1      0          0        
# 清空策略
[root@linux30 ~]# ipvsadm -C
# 再次查看策略
[root@linux30 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
# 设置规则
[root@linux30 ~]# ipvsadm -A -t 192.168.10.34:80 -s rr
# 添加 RS
[root@linux30 ~]# ipvsadm -a -t 192.168.10.34:80 -r 192.168.10.31 -g
[root@linux30 ~]# ipvsadm -a -t 192.168.10.34:80 -r 192.168.10.32 -g
# 查看策略
[root@linux30 ~]# 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.10.34:80 rr
  -> 192.168.10.31:80             Route   1      0          0
  -> 192.168.10.32:80             Route   1      0          0

(4)修改 client 服务器配置,更改使用 NAT 网卡,并设置 IP 为 192.168.10.33,并测试效果

[root@client ~]# curl 192.168.10.34
this is RS02
[root@client ~]# curl 192.168.10.34
this is RS01
[root@client ~]# curl 192.168.10.34
this is RS02
[root@client ~]# curl 192.168.10.34
this is RS01

(5)在 LVS 服务器上查看调度情况

[root@lvs01 ~]# ipvsadm -Lnc
IPVS connection entries
pro expire state       source             virtual            destination
TCP 01:30  FIN_WAIT    192.168.116.133:45810 192.168.116.134:80 192.168.116.131:80
TCP 01:31  FIN_WAIT    192.168.116.133:45812 192.168.116.134:80 192.168.116.132:80
TCP 01:32  FIN_WAIT    192.168.116.133:45814 192.168.116.134:80 192.168.116.131:80
TCP 01:30  FIN_WAIT    192.168.116.133:45808 192.168.116.134:80 192.168.116.132:80

3. KeepAlived

3.1 简介

Keepalived 的作用是检测服务器状态,如果有一台 web 服务器宕机,或工作出现故障,Keepalived 将检测到,并将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后 Keepalived 自动将服务器加入到服务器群中。

主要特点:

(1)健康检查

检查方式 说 明
tcp_check 工作在第 4 层,keepalived 向后端服务器发起一个 tcp 连接请求,如果后端服务器没有响应或超时,那么这个后端将从服务器池中移除。
http_get 工作在第 5 层,向指定的 URL 执行 http 请求,将得到的结果用 md5 加密并与指定的 md5 值比较看是否匹配,不匹配则从服务器池中移除;此外还可以指定 http 返回码来判断检测是否成功。HTTP_GET 可以指定多个 URL 用于检测,这个一台服务器有多个虚拟主机的情况下比较好用。
misc_check 用脚本来检测,脚本如果带有参数,需将脚本和参数放入双引号内
ssl_get 和 http_get 相似,不同的只是用 SSL 连接
smtp_check 主要用于邮件系统 SMTP 协议的检测

(2)故障迁移

VRRP 协议

在现实的网络环境中。主机之间的通信都是通过配置静态路由或默认网关来完成的,而主机之间的路由器一旦发生故障,通信就会失效,因此这种通信模式当中,路由器就成了一个单点瓶颈,为了解决这个问题,就引入了 VRRP 协议。

VRRP 协议是一种容错的主备模式的协议,保证当主机的下一跳路由出现故障时,由另一台路由器来代替出现故障的路由器进行工作,通过 VRRP 可以在网络发生故障时透明的进行设备切换而不影响主机之间的数据通信。

故障迁移原理

在 Keepalived 服务正常工作时,主 Master 节点会不断地向备节点发送(多播的方式)心跳消息,用以告诉备 Backup 节点自己还活着,当主 Master 节点发生故障时,就无法发送心跳消息,备节点也就因此无法继续检测到来自主 Master 节点的心跳了,于是调用自身的接管程序,接管主 Master 节点的 IP 资源及服务。而当主 Master 节点恢复时,备 Backup 节点又会释放主节点故障时自身接管的 IP 资源及服务,恢复到原来的备用角色。

3.2 原理

Keepalived 工作在 TCP/IP 参考模型的三层、四层、五层,其原理如下:

工作层 说 明
网络层 Keepalived 通过 ICMP 协议向服务器集群中的每一个节点发送一个 ICMP 数据包(有点类似于 Ping 的功能),如果某个节点没有返回响应数据包,那么认为该节点发生了故障,Keepalived 将报告这个节点失效,并从服务器集群中剔除故障节点。
传输层 Keepalived 在传输层里利用了 TCP 协议的端口连接和扫描技术来判断集群节点的端口是否正常。 比如对于常见的 WEB 服务器 80 端口。或者 SSH 服务 22 端口,Keepalived 一旦在传输层探测到这些端口号没有数据响应和数据返回,就认为这些端口发生异常,然后强制将这些端口所对应的节点从服务器集群中剔除掉。
应用 层 Keepalived 的运行方式更加全面化和复杂化,用户可以通过自定义 Keepalived 工作方式。例如:可以通过编写程序或者脚本来运行 Keepalived,而Keepalived 将根据用户的设定参数检测各种程序或者服务是否正常,如果 Keepalived 的检测结果和用户设定的不一致时,Keepalived 将把对应的服务器从服务器集群中剔除。

3.3 选主策略

仅设置 priority

在一个一主多备的 Keepalived 集群中,priority 值最大的将成为集群中的 MASTER 节点,而其他都是 BACKUP 节点。在 MASTER 节点发生故障后,BACKUP 节点之间将进行“民主选举”,通过对节点优先级值 priority 和 weight 的计算,选出新的 MASTER 节点接管集群服务。

设置 priority 和 weight

(1)weight 值为正数时

在 vrrp_script 中指定的脚本如果检测成功,那么 MASTER 节点的权值将是 weight 值与 priority 值之和;如果脚本检测失效,那么 MASTER 节点的权值保持为 priority 值。

MASTER 节点 vrrp_script 脚本检测失败时,如果 MASTER 节点 priority 值小于 BACKUP 节点 weight 值与 priority 值之和,将发生主、备切换。

MASTER 节点 vrrp_script 脚本检测成功时,如果 MASTER 节点 weight 值与 priority 值之和大于 BACKUP 节点 weight 值与 priority 值之和,主节点依然为主节点,不发生切换。

(2)weight值为负数时

在 vrrp_script 中指定的脚本如果检测成功,那么 MASTER 节点的权值仍为 priority 值;当脚本检测失败时,MASTER 节点的权值将是 priority 值与 weight 值之和。

MASTER 节点 vrrp_script 脚本检测失败时,如果 MASTER 节点 priority 值与 weight 值之和小于 BACKUP 节点 priority 值,将发生主、备切换。

MASTER 节点 vrrp_script 脚本检测成功时,如果 MASTER 节点 priority 值大于 BACKUP 节点 priority 值时,主节点依然为主节点,不发生切换。

weight 设置标准

对于 weight 值的设置,有一个简单的标准,即 weight 值的绝对值要大于 MASTER 和 BACKUP 节点 priority 值之差。由此可见,对于 weight 值的设置要非常谨慎,如果设置不好,主节点发生故障时将导致集群角色选举失败,使集群陷于瘫痪状态。

4. LVS+KeepAlived

4.1 KeepAlived 配置

(1)在两台 LVS 服务器上都需要安装 KeepAlived

$ yum install -y keepalived

(2)KeepAlived 安装完成后,在 /etc/keepalived 目录下有一个 keepalived.conf 配置文件。基于拓扑图及服务器规划,对两台 LVS 服务器分别修改。

LVS 主服务器

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   #vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.10.34/24 dev ens33 label ens33:9
    }
}

virtual_server 192.168.10.34 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 0
    protocol TCP

    real_server 192.168.10.31 80 {
        weight 1
        HTTP_GET {
            url {
              path /
              status 200 
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
    real_server 192.168.10.32 80 {
        weight 1
        HTTP_GET {
            url {
              path /
              status 200 
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

LVS 备份服务器

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   #vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.10.34/24 dev ens33 label ens33:9
    }
}

virtual_server 192.168.10.34 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 0
    protocol TCP

    real_server 192.168.10.31 80 {
        weight 1
        HTTP_GET {
            url {
              path /
              status 200 
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
    real_server 192.168.10.32 80 {
        weight 1
        HTTP_GET {
            url {
              path /
              status 200 
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

配置文件中的 key 和大括号之间一定要有空格

(3)在两台 LVS 服务器上分别启动 KeepAlived

$ service keepalived start

(4)上述步骤执行完毕后,可以在 LVS 主服务器和备份服务器分别执行 ifconfig 命令,可以查看到 VIP 被绑定到了主服务器

$ ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.30  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 fe80::db30:9838:de0e:8127  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::6d7c:9692:c7a8:6320  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::3b38:154b:fc3d:6269  prefixlen 64  scopeid 0x20<link>
        ether 00:50:56:2d:6c:7f  txqueuelen 1000  (Ethernet)
        RX packets 11864  bytes 14964468 (14.2 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6054  bytes 449187 (438.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33:9: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.34  netmask 255.255.255.0  broadcast 0.0.0.0
        ether 00:50:56:2d:6c:7f  txqueuelen 1000  (Ethernet)

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        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.10.34 来进行测试。

4.2 高可用测试

a. 测试环境检查

上述步骤执行完毕后,可以在 lvs 主服务器和备份服务器分别执行 ifconfig 命令,可以查看到 VIP 被绑定到了主服务器:

[root@lvs01 ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.30  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 fe80::db30:9838:de0e:8127  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::6d7c:9692:c7a8:6320  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::3b38:154b:fc3d:6269  prefixlen 64  scopeid 0x20<link>
        ether 00:50:56:2d:6c:7f  txqueuelen 1000  (Ethernet)
        RX packets 11864  bytes 14964468 (14.2 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6054  bytes 449187 (438.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33:9: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.34  netmask 255.255.255.0  broadcast 0.0.0.0
        ether 00:50:56:2d:6c:7f  txqueuelen 1000  (Ethernet)

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        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

这样,就可以在客户端请求 VIP192.168.10.34 来进行测试。

b. 测试负载均衡

[root@client ~]# curl 192.168.10.34
this is RS01
[root@client ~]# curl 192.168.10.34
this is RS02
[root@client ~]# curl 192.168.10.34
this is RS01
[root@client ~]# curl 192.168.10.34
this is RS02

c. 测试 RS 高可用

关闭一台 RS 后(这里可以使用 ifconfig 网卡名 down 暂时关闭网卡),客户端继续发起请求,查看是否可以正常访问:

[root@client ~]# curl 192.168.10.34
this is RS02
[root@client ~]# curl 192.168.10.34
this is RS02
[root@client ~]# curl 192.168.10.34
this is RS02
[root@client ~]# curl 192.168.10.34
this is RS02

会发现,此时客户端可以正常访问,但只有 RS2 在提供服务。这说明,KeepAlived 检测到了 RS1 服务器异常,将其剔除了。

此时再启动 RS1 服务器,客户端继续访问,会发现响应结果如下,KeepAlived 检测到 RS1 服务器恢复正常,又将其加入服务列表了。

[root@client ~]# curl 192.168.10.34
this is RS02
[root@client ~]# curl 192.168.10.34
this is RS01
[root@client ~]# curl 192.168.10.34
this is RS02
[root@client ~]# curl 192.168.10.34
this is RS01

d. 测试 LVS 高可用

(1)测试 LVS 主服务宕机

关闭主服务器网卡,此时主服务器不能提供服务。观察备份服务器是否将 VIP 绑定到自己,以及客户端是否可以继续正常访问。

[root@lvs01 keepalived]# ifconfig ens33 down

观察备份服务器,会发现 VIP 已经绑定过来了。这里实际是 KeepAlived 检测到了主服务器的异常,而做出的故障转移和自动切换。

[root@lvs02 ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.35  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 fe80::db30:9838:de0e:8127  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::6d7c:9692:c7a8:6320  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::3b38:154b:fc3d:6269  prefixlen 64  scopeid 0x20<link>
        ether 00:50:56:2e:ba:c0  txqueuelen 1000  (Ethernet)
        RX packets 24929  bytes 33887638 (32.3 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8458  bytes 590453 (576.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33:9: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.34  netmask 255.255.255.0  broadcast 0.0.0.0
        ether 00:50:56:2e:ba:c0  txqueuelen 1000  (Ethernet)

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 16  bytes 1392 (1.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 16  bytes 1392 (1.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

观察客户端是否可以继续正常访问:

[root@client ~]# curl 192.168.10.34
this is RS02
[root@client ~]# curl 192.168.10.34
this is RS01
[root@client ~]# curl 192.168.10.34
this is RS02
[root@client ~]# curl 192.168.10.34
this is RS01

(2)测试 LVS 主服务器恢复

上述测试通过后,可以开启主服务器网卡,让其能够提供服务,然后观察 VIP 是否会回到主服务器。

开启主服务器网卡:ifconfig ens33 up

查看主服务器和备份服务器会发现,VIP 重新绑定到了主服务器。

[root@lvs01 ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.30  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 fe80::db30:9838:de0e:8127  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::6d7c:9692:c7a8:6320  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::3b38:154b:fc3d:6269  prefixlen 64  scopeid 0x20<link>
        ether 00:50:56:2d:6c:7f  txqueuelen 1000  (Ethernet)
        RX packets 12942  bytes 15089760 (14.3 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7888  bytes 585418 (571.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33:9: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.34  netmask 255.255.255.0  broadcast 0.0.0.0
        ether 00:50:56:2d:6c:7f  txqueuelen 1000  (Ethernet)

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 7  bytes 616 (616.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7  bytes 616 (616.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
[root@lvs02 ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.35  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 fe80::db30:9838:de0e:8127  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::6d7c:9692:c7a8:6320  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::3b38:154b:fc3d:6269  prefixlen 64  scopeid 0x20<link>
        ether 00:50:56:2e:ba:c0  txqueuelen 1000  (Ethernet)
        RX packets 25287  bytes 33927783 (32.3 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8906  bytes 624556 (609.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 16  bytes 1392 (1.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 16  bytes 1392 (1.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0