Linux 必学:简单指南帮助你完成 IPVS 安装 (linux 安装ipvs)

在现代云计算和容器化技术的背景下,负载均衡已经成为了互联网应用中必不可少的组成部分。而在 Linux 平台上,IPVS 则是更受欢迎的负载均衡技术之一,它能够为应用提供高效的流量转发和连接控制功能。本文将从 IPVS 的安装及配置入手,为大家提供一份简单易懂的指南,帮助大家完成 IPVS 的安装和配置过程。

什么是 IPVS?

IPVS 全称为 IP Virtual Server,最早是由 Wensong Zhang 在 1999 年开发的。它是一个核心层负载均衡器,在 Linux 内核代码内置的 Netfilter 框架中实现了高效的四层负载均衡和七层负载均衡功能,支持多种运行模式和转发算法。由于 IPVS 位于 Linux 内核中并发操作,性能出众,成为了众多互联网公司使用的主流负载均衡技术之一。

IPVS 的优势

与其它负载均衡方案相比 IPVS 具有下列优点:

1. 高性能:由于 IPVS 的代码位于 Linux 内核中,因此它的性能非常出色。

2. 稳定: IPVS 相比于其它的负载均衡方案,它的稳定性是非常好的。

3. 功能强大:在 IPVS 中,支持多种转发方式和算法, 提供了比较丰富的配置选项,可以灵活的适应不同场景的需求。

IPVS 的安装和配置

下面我们将来介绍一下如何在 Linux 系统上安装和配置 IPVS。

1. 安装相关软件

在安装 IPVS 之前,需要先将所需的软件包安装到系统上。这里我们以 Debian 系统为例。

通过以下命令安装所需的软件包:

“`

sudo apt-get update

sudo apt-get install -y libnl-3-dev libnl-genl-3-dev libssl-dev ipset ipvsadm

“`

/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs/ip_vs_rr.ko

依次安装 libnl-3-dev、libnl-genl-3-dev、libssl-dev、ipset 和 ipvsadm 五个软件包。

2. 配置 kernel 模块

在安装完必要的软件包之后,需要开启 IPVS 模块。这里我们使用 modprobe 命令完成这个过程:

“`

sudo modprobe ip_vs

sudo modprobe ip_vs_rr

sudo modprobe ip_vs_wrr

sudo modprobe ip_vs_sh

“`

这里,我们加载了四个 kernel 模块,分别是 ip_vs、ip_vs_rr、ip_vs_wrr 和 ip_vs_sh。在使用 IPVS 进行负载均衡之前,需要使用以上命令分别对四个核心模块进行加载。其中,ip_vs 模块是必须的,其它三个模块则会根据负载均衡方式的不同而选择加载。

3. 配置 IPVS

在加载了 kernel 模块之后,就可以开始配置 IPVS 了。需要创建一个配置文件 /etc/ipvsadm.conf,将需要负载均衡的一些服务存储到该配置文件中。

下面是一个 /etc/ipvsadm.conf 的示例配置文件:

“`

# /etc/sysconfig/ipvsadm

# Load various modules

modprobe ip_vs

modprobe ip_vs_rr

modprobe ip_vs_wrr

modprobe ip_vs_sh

# Clear out previous setup

ipvsadm -C

# Add virtual server

ipvsadm -A -t 192.168.1.100:80 -s rr

ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.10:80 -g

ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.11:80 -g

“`

该配置文件使用了 ipvsadm 命令,通过该命令可以配置一些虚拟服务,IPVS 会分发请求到指定的实际服务器上。在上述示例配置文件中,-A 参数用于添加一个虚拟服务,并指定负载均衡算法为 rr(轮询),而 -a 参数则用于添加实际的服务器地址(以 IP 地址和端口号的形式提供)。

通过以上方法,我们就成功的完成了 IPVS 的安装和配置。现在,你已经可以使用 IPVS 在自己的服务器上实现负载均衡。当然,IPVS 还有很多高级用法和配置技巧,但是在最基本的使用上,以上方法已经可以满足我们的需求了。通过学习这篇文章,相信你已经掌握了 Linux 平台上 IPVS 的安装和配置方法。

相关问题拓展阅读:

Linux如何在系统启动时自动加载模块

rc.sysinit中有这样的一段代码:

# Load other user-defined modules

for file in /etc/sysconfig/modules/*.modules ; do

&& $file

done

# Load modules (for backward compatibility with VARs)

if ; then

/隐谈etc/rc.modules

fi

可见只需要配置两个地方的任何一个就可以了(以加载fuse内核模块为例)

(1) 在/etc/sysconfig/modules/下面创建*.modules文件,参考裂茄已经肆携察有的*.modules文件,例如我写创建文件my.modules,内容为modprobe fuse

记得最后chmod 755 my.modules

(2) 或者在/etc/rc.modules里面加上modprobe fuse,没有的话创建该文件。

然后reboot,lod | grep fuse验证一下就OK了。

为搞清楚如何在系统启动时自动加载模块,搜索了好久,网上有很多人提出这个问题,但都没有正确的答案。大家的回答都没有讲到点子上,无非是围绕modprobe.conf、modprobe讲来讲去的,要不就是针对特定问题尝试不同的方法。有的还建议把modprobe modulename写入rc.local,却不曾想rc.local的执行被放在整个启动顺序的很后面,而启动init.d下面定义的服务却在rc.local前面,那么如果某个服务要用这个模块,就不行了。 在测试LVS时,因为我的Fedora7的Kernel(2.6.21-1)缺省没有加载ip_vs模块,而内核中已经包含编译好的IPVS相关的模块了,放在:/lib/modules/2.6.21-1.3194.fc7/kernel/net/ipv4/ipvs/下面,有: /lib/modules/2.6.21-1.3194.fc7/kernel/net/ipv4/ipvs/ip_vs.ko /lib/modules/2.6.21-1.3194.fc7/kernel/net/ipv4/ipvs/ip_vs_dh.ko /lib/modules/2.6.21-1.3194.fc7/kernel/net/ipv4/ipvs/ip_vs_ftp.ko /lib/modules/2.6.21-1.3194.fc7/kernel/net/ipv4/ipvs/ip_vs_lblc.ko /lib/modules/2.6.21-1.3194.fc7/kernel/net/ipv4/ipvs/ip_vs_lblcr.ko /lib/modules/2.6.21-1.3194.fc7/kernel/net/ipv4/ipvs/ip_vs_lc.ko /lib/modules/2.6.21-1.3194.fc7/kernel/net/ipv4/ipvs/ip_vs_nq.ko /lib/modules/2.6.21-1.3194.fc7/kernel/net/ipv4/ipvs/ip_vs_rr.ko /lib/modules/2.6.21-1.3194.fc7/kernel/net/ipv4/ipvs/ip_vs_sed.ko /lib/modules/2.6.21-1.3194.fc7/kernel/net/ipv4/ipvs/ip_vs_sh.ko /lib/modules/2.6.21-1.3194.fc7/kernel/net/ipv4/ipvs/ip_vs_wlc.ko /lib/modules/2.6.21-1.3194.fc7/kernel/net/ipv4/ipvs/ip_vs_wrr.ko 其中ip_vs.ko是IPVS的基本模块,不加载IPVS就不能工作(运行ipvsadm会报错的),而其他的都是IPVS的调度算法或特定协议的辅助模块,需要时则须加则蔽载。 要了解如何在系统启动时自动加载模块(Automatically load kernel modules),就得先了解系统是如何启动的,启动的过程中按什么顺序做了什么,怎么做的,这些启动操作都有那些文件和脚本控制。整个开机流程是: (1) 载入BIOS的硬件信息,并取得之一个开机装置的代号 (2)读取之一个开机装置的MBR的boot Loader (grub)的开机信息 (3)载入OS Kernel信息,解压Kernel,尝试驱动硬件 (4) Kernel执行init程序并获得run-lebel信息(如3或5) (5) init执行/etc/rc.d/rc.sysinit (6)启动内核外挂模块(/etc/modprobe.conf) (7) init执行run-level的各孙粗州种Scripts,启动服务 (8) init执行/etc/rc.d/rc.local (9)执行/bin/login,等待用户Login (10)Login后进入Shell看来正确的方式是把需要加载的模块放在(5)或(6),我修改了/etc/rc.d/rc.sysinit就成功加载了。初步尝试在rc.sysinit最后增加 modprobe.conf ip_vs,重启后lod | grep ip_vs,发现成功自动加载了。于是仿效rc.sysinit中其他模块的加载方法,扩展凳卖改脚本文件,在最后增加下来一段: # load LVS IPVS modules if ; then for module in /lib/modules/$unamer/kernel/net/ipv4/ipvs/* ; do module=${module##*/} module=${module%.ko} modprobe $module >/dev/null 2>&1 done fi就把/lib/modules/2.6.21-1.3194.fc7/kernel/net/ipv4/ipvs/下的所有模块都自动加载。

k8s网络原理-ipvs

一、背景知识

  本文主要介绍k8s网络中service 的两种模式(clusterIp、nodeport),数据是如何通过ipvs&iptables流转的。在学习上述知识的同时,还需要了解一下ipset、conntrack的相关知识。

往期回顾文章

1.1、ipset

  ipset是什么?ipset其实是iptables的扩展,可以定义一些列地址的。拿黑名单来举例,我想让黑名单里面的ip拒绝访问网站(黑名单有很多个),按照传统iptables做法,需要渣谈在filter表添加很多规则匹配时一条一条匹配效率很低(严重影响性能),而有了ipset,则只用添加一条规则即可,使用hash结构效率很高。

而使用ipset命令如下

  当然,ipset还支持 hash:ip,hash:ip,port,ip等多种hash key的组成,具体可以通过拍神 ipset -h 查看。接下来说明一下 -m set 后面 src 和 dst 两个的含义。src 指来源,dst 指目标,此规则的意思是来自192.178.113.100 ip 访问本机8410端口的流量给DROP掉。

ipset使用hash结构,比iptables的链表遍历效率要高很多。ipset还有很多如贺碰更加高级的玩法,本文就不在阐述了。

1.2、ipvs

  lvs是什么?全称是Linux Virtual Server,是由章文嵩博士主导的开源负载均衡项目,目前已经集成到linux内核中。lvs提供了丰富的负载均衡能力,接收到用户请求后根据具体的负载均衡算法在内核态把请求转发到后端的某个server上,也就是说lvs不需要监听具体的端口。接下来我们看一下lvs的一些基本概念。

  ipvs的原理如下。ipvs工作在iptables 的 input链上,VIP一般定义在DS节点上的一个虚拟ip,拿nat模式举例如下。

① : 当请求数据包到DS上更先经过iptables 的PREROUTING链,判断目标ip (VIP) 是本机的ip,于是把请求转发到INPUT链上。

② : 因为lvs工作在INPUT链上,数据到达INPUT链上后lvs会将用户请求和定义的后端服务做对比,如果是请求的后端服务,则使用某种负载均衡算法找到一个后端RIP,修改数据包的目的ip和端口为某个RIP的(DNAT转换)。

③ : 此时数据到达POSTROUTING链(不会做SNAT),数据包的源ip 为CIP,目的ip为RIP,数据包发往RIP上。

lvs提供了三种包转发模式,如下所示

由于k8s使用的是NAT模式,接下来看下

NAT模式下的数据包流向

。如下图所示

①:请求数据包到达DS,数据包经过PREROUTING链,此时ip 包 src ip为CIP,dst ip 为VIP

②:由于请求的VIP是DS上的虚拟ip,数据包发往INPUT链。

③:数据包到INPUT链上后,ipvs发现数据包请求是定义的集群服务,于是使用定义好的负载均衡算法找到一个具体的RS节点,做DNAT,修改数据包dst ip为RIP,数据包到达POSTROUTING链,发送给RS。

④:RS收到数据包后对比dst ip 发现是自己,接收数据包做处理,处理完成后ip 数据包 src ip 为RIP,dst ip 为CIP,把数据包发给DS。

⑤:DS 接收到RS的响应包,修改src ip 为自身的VIP,dst ip 为CIP,把数据包发送给client端。

三种模式对比&优缺点

接下来在简单聊一下ipvs的负载均衡策略,简单介绍下面四种。

  上面介绍完了ipvs内核态的基本原理,接下来介绍一下如何使用 ipvsadm 用户态命令来操作ipvs。说明:此次试验是在四个虚拟机上,ipvs的模式使用的nat模式,RS的网关没有指向DS的ip(没办法做到)在DS节点上手动创建SNAT命令,下文有详细介绍。创建一个vip,在ip为192.168.113.101上

为vip添加RS

添加完成RS后,查看ipvs规则,如下图所示

client端的ip地址为192.168.113.102,client端要想直接访问vip的话,需要在client端添加静态路由,添加命令如下

添加完命令后,在client端curl 10.10.0.1:8410 发现不通,此时去某个RS上抓包如下

  上图抓包显示,client 直接访问的vip,而数据包的目的ip 变为了rs的ip,因此可以看出ipvs做了DNAT转换。因为做了DNAT,RS发送响应数据直接发给client,client收到RS的数据包。client给vip发的包却收到了RS的响应包(client 想我从来没有给RS发过数据),因此client端会把此数据包丢弃。

  因为ipvs没有做SNAT,接下来在DS上添加iptables规则自己实现SNAT的功能,添加完SNAT后,

RS就看不到真实的CIP了

  此时还是不通,查找资料后发现ipvs 的

conntrack

没有开,手动打开,后续文章介绍conntrack是什么,设置完成后可以愉快的访问了。

  总结:通过ipvs提供的DNAT功能和负载均衡功能,很容易实现外部用户访问内网的需求。但是还要考虑高可用层面,比如主DS宕机VIP要漂移到备DS上,后端RS重启或宕机,ipvs负载均衡列表中要及时把有问题的RS剔除,这样才能真正的实现高可用。

1.3、conntrack

  大家在家上网时用到的都是192.168.x.x的ip地址,这是私网ip地址。那么大家是如何能够成功的访问外网的呢?答案是路由器帮我们做了SNAT的功能,使我们发出的数据包的src ip变为路由器的公网ip,这样数据包就能在互联网上愉快的转发了。从而实现了对内网的保护。

  那么问题来了,既然做了SNAT转换,那响应数据包回来以后路由器怎么知道转到哪台PC上呢?路由器可能链接了很多PC,不可能都给每一个PC转发吧。。。答案就是conntrack实现的。

  接下来我拿上面ipvs的例子举例,我们手动实现了在DS上SNAT转换,在client上curl vip:8410,这时候查看DS上和client上的conntrack表如下

先从client上的连接跟踪分析起:主要看 src、dst、sport、dport这几个字段。

client发送数据包

client端发出数据包的src ip 为192.168.113.102,dst ip 为10.10.0.1 (VIP), sport 为35562这个端口,dport为8410(VIP 定义端口)。

client端接收响应数据包

期望src ip 为vip(10.10.0.1),dst ip 为CIP(192.168.113.102),sport为8410,dport为35562

DS接收数据包

DS接收到src ip 为CIP(192.168.113.102),dst ip 为vip(10.10.0.1),sport为35562,dport为8410的数据包

DS接收响应数据包

  由于在DS侧做了DNAT转换,根据负载均衡策略找到了一个RS(RIP 192.168.113.99),同时也做了SNAT转换(判断是否是VIP和端口),转换为DS的DIP。所以当DS收到src ip 为192.168.113.99(RIP),dst ip 为192.168.113.101(DIP),sport为8080,dport为35562,会根据连接跟踪表找到这个包是192.168.113.102这个client发过来的,因此把数据包在转发给192.168.113.102:35562 上。

conntrack各个字段的含义

总结:

  本文只是简单的说明了一下conntrack,并没有具体说明数据流经netfilter时何时创建记录,数据存储的数据结构啥样,底层比较复杂,感兴趣的大佬可以自行研究~

二、k8s网络通信

  介绍完了ipset、ipvs、conntrack,接下来进入正题,看一下ipvs模式下k8s的网络通信。kube-proxy 的主要作用是watch apiserver,当监听到pod 或service变化时,修改本地的iptables规则或ipvs规则。

2.1、clusterIp模式

clusterIp模式为一个集群内部可访问的ip,集群外部没办法访问这个ip,试验环境如下:

创建完deployment和service后,查看一下service的ip如下。

接下来看下宿主机网卡、ipvs规则、ipset规则有什么变化

查看iptables 的nat表和filter表,看一下k8s创建了哪些规则以及经过哪些链

接下来分析一下curl 10.108.113.237 数据是如何走的,只讨论在nat表和filter表的流向,因为在mangle和raw都没有规则。

1、nat表PREROUTING链

①:数据首先进入PREROUTING链,所有请求都会进入KUBE-SERVICES链。

②:进入KUBE-SERVICES后,查看对应在此链上的规则,发现请求的目的ip和port在KUBE-CLUSTER-IP 对应的ipset里面(上面已有展示),匹配上了则跳往KUBE-MARK-MASQ链。

③:数据流向KUBE-MARK-MASQ链,主要做了mark 打标记的功能,iptables命令如下

④:之后走向KUBE-NODE-PORT链,因为没有定义nodepode 类型的service,此处先略过。

2、filter表的INPUT链

⑤:首先进入INPUT链,所有数据转向KUBE-FIREWALL链。

⑥:进入KUBE-FIREWALL链,如果发现数据包打了0x8000/0x8000,DROP掉。因为ipvs工作在INPUT链上,做完DNAT之后直接转发到POSTROUTING链上。

3、nat表POSTROUTING链

⑦:进入POSTROUTING链,所有数据转向KUBE-POSTROUTING链

⑧:进入KUBE-POSTROUTING链,对有0x4000/0x4000标记的数据包做SNAT转换,因为ipvs只有DNAT功能。

4、数据转发给flannel网卡,进行转发

⑨:flannel 根据具体的backend模式,对数据做封包等操作,然后发出去。flannel的网络模式比较复杂,之后会专门文章进行说明。

2.2、nodeport模式

  要想把集群内部的服务可以让集群外部访问,可以使用nodeport模式在物理机上开一个端口,这样外部就能访问集群内部的服务了。说明:还是使用上面创建的deployment。

查看创建service的信息,发现也创建了集群内部的一个ip。

iptables规则如下

接下来看下ipset规则有什么变化,发现KUBE-NODE-PORT-TCP下的一个成员是刚才我们指定的那个nodePort的值。

接下来看一下iptables规则,nat表和filter表

1、nat表PREROUTING链

①:数据首先进入PREROUTING链,所有请求都会进入KUBE-SERVICES链。

②:ip和port匹配不上KUBE-CLUSTER-IP 的ipset,判断是访问的本地地址,进入KUBE-NODE-PORT链。

③:进入KUBE-NODE-PORT链后,判断访问端口在 KUBE-NODE-PORT-TCP ipset规则中,因此进入KUBE-MARK-MASQ链。

④:进入KUBE-MARK-MASQ链,对数据做mark标记

后续流程跟clusterIp一样,此处就不在阐述。

2.3、dns相关

  k8s中的dns默认使用的是coredns,通过以下命令查看。k8s中定义的service是有域名的,访问域名要通过dns解析,此时coredns就发挥它的作用了。

  上面的试验时我们创建了一个my-service 的nodePort的service,此时查看一下此域名对应的ip,如下图所示,域名解析出来的ip与service对应的ip相同,大功告成。

参考:

以上相关内容介绍了k8s service ipvs的相关实现,如有错误欢迎指出~

linux 安装ipvs的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于linux 安装ipvs,Linux 必学:简单指南帮助你完成 IPVS 安装,Linux如何在系统启动时自动加载模块,k8s网络原理-ipvs的信息别忘了在本站进行查找喔。


数据运维技术 » Linux 必学:简单指南帮助你完成 IPVS 安装 (linux 安装ipvs)