k8s集群中ipvs负载详解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了k8s集群中ipvs负载详解相关的知识,希望对你有一定的参考价值。

参考技术A

目录:

IPVS简介:

尽管 Kubernetes 在版本v1.6中已经支持5000个节点,但使用 iptables 的 kube-proxy 实
际上是将集群扩展到5000个节点的瓶颈。 在5000节点集群中使用 NodePort 服务,如
果有2000个服务并且每个服务有10个 pod,这将在每个工作节点上至少产生20000个
iptable 记录,这可能使内核非常繁忙。

ipvs (IP Virtual Server) 实现了传输层负载均衡,也就是我们常说的4层LAN交换,作为
Linux 内核的一部分。ipvs运行在主机上,在真实服务器集群前充当负载均衡器。ipvs
可以将基于TCP和UDP的服务请求转发到真实服务器上,并使真实服务器的服务在单个
IP 地址上显示为虚拟服务。

我们知道kube-proxy支持 iptables 和 ipvs 两种模式, 在kubernetes v1.8 中引入了 ipvs
模式,在 v1.9 中处于 beta 阶段,在 v1.11 中已经正式可用了。iptables 模式在 v1.1 中
就添加支持了,从 v1.2版本开始 iptables 就是 kube-proxy 默认的操作模式,ipvs 和
iptables 都是基于netfilter的。ipvs 会使用 iptables 进行包过滤、SNAT、masquared。
具体来说,ipvs 将使用ipset来存储需要DROP或masquared的流量的源或目标地址,
以确保 iptables 规则的数量是恒定的,这样我们就不需要关心我们有多少服务了。

启动ipvs的要求:

先前基于iptables规则表的DNAT->SNAT方式来处理外部客户端到k8s集群pod内的流量
和集群内部流量(cluster-ip到pod ip),无需在宿主机上管理cluster-ip都由iptables来进行
管理。

使用IPVS后是需要对vs(虚拟服务也就是vip)进行管理,由于IPVS的DNAT钩子挂在
INPUT链上,因此必须要让内核识别 VIP(cluster-ip) 是本机的 IP。k8s 通过设置将
service cluster ip 绑定到虚拟网卡kube-ipvs0,其中下面的10.96.x.x都是VIP,也就
是cluster-ip。如下图:

ipvs 会使用 iptables 进行包过滤、SNAT、masquared(伪装)。具体来说,ipvs 将使用
ipset来存储需要DROP或masquared的流量的源或目标地址,以确保 iptables 规则的
数量是恒定的,这样我们就不需要关心我们有多少服务了。

这里访问cluster ip为10.96.0.10,k8s集群内部的dns服务

1)、入口流量匹配:
数据包是通过本地协议发出的,在宿主机本地通过访问cluster-ip到后端真是的pod那
么就要伪装所有访问 Service Cluster IP 的外部流量,k8s只能在OUTPUT这个链上
来做相应的规则:
$iptables -S -tnat | grep OUTPUT

2)、入口流量引流到全局链KUBE-SERVICES中:
ipset list KUBE-CLUSTER-IP
iptables -S -tnat | grep KUBE-SERVICES

第一步中上面的数据包流入到KUBE-SERVICES该规则中目的就是让源地址不是
10.244.0.0/16,目的地址match 到 KUBE-CLUSTER-IP 的数据包打上标签。

3)、入口流量标签化处理:
将上面KUBE-SERVICES链中的流量进行打标签处理:
$iptables -S -tnat | grep KUBE-MARK-MASQ

4)、入口流量SNAT处理:
那么数据包在出去的时候一定是要经过POSTROUTING链进行SNAT即将所有来源外部
流量转换成该cluster ip的源地址。
$iptables -S -tnat | grep POSTROUTING

然后通过内部的lvs进行流量转发到后端pod上。如下图:
$ipvsadm -Ln

这里创建一个service为NodePort的nginx应用对应为nodeip:port(192.168.100.100:30080),
clusterip:port(10.101.19.237:80)
$ip ad| grep ipvs

$kubectl get svc

1)、入口流量匹配:
集群外部通过node ip 访问到后端pod服务,流量肯定是先在PREROUTING链中处理:
$iptables -S -tnat | grep PREROUTING

匹配到倒数第二条就是,将流量引入到KUBE-SERVICES规则中处理。

2)、入口流量引流到全局链KUBE-SERVICES中:
$ipset list KUBE-CLUSTER-IP

$iptables -S -tnat | grep KUBE-SERVICES

第一步中上面的数据包流入到KUBE-SERVICES该规则中目的就是让源地址不是10.244.0.0/16,目的地址match 到 KUBE-CLUSTER-IP 的数据包打上标签

3)、入口流量标签化处理:
$iptables -S -tnat | grep KUBE-MARK-MASQ

4)、入口流量SNAT处理:
那么数据包在出去的时候一定是要经过POSTROUTING链进行SNAT即将所有来源外部流量转换成该cluster ip的源地址。
$iptables -S -tnat | grep POSTROUTING

iptables中POSTROUTING链最先将流量引流到KUBE-POSTROUTING中做进一步的SNAT处理
$iptables -S -tnat | grep KUBE-POSTROUTING

端口的转换
$iptables -S -tnat | grep KUBE-NODE-PORT

上面的流程进行SNAT后即将所有来源外部流量转换成该cluster ip的源地址的对应得端
口。然后通过内部的lvs进行流量转发到后端pod上。

这种的LB方式和之前分析的swarm集群中LB类似都是用lvs来直接进行负载,这比起原先使用iptables来进行负载在性能上要好的多,同时也比较清晰友好。总之一句话流量都是要先经过iptables清理一遍然后交给4层的lvs进行负载。

LVS负载均衡集群服务搭建详解

LVS概述

1.LVS:Linux Virtual Server
四层交换(路由):根据请求报文的目标IP和目标PORT将其转发至后端主机集群中的某台服务器(根据调度算法);
不能够实现应用层的负载均衡
lvs(又称ipvs)是基于内核中的防火墙netfilter实现

 

2.lvs集群术语:

vs:Virtual Server 虚拟服务,可称为Director、Dispatcher分发器、Balancer负载均衡器
rs:Real Server 真实服务器
CIP:Client IP 客户端IP
VIP:Director Virtual IP 等同于FIP(流动IP),负载均衡器虚拟IP
DIP:Director IP 调度IP(第二张网卡IP地址)
RIP:Real Server IP 真实服务器IP

 

3.LVS:ipvsadm/ipvs

(1)ipvsadm: CLI工具
用户空间的命令行工具,用于管理集群服务及集群服务上的RS等;# yum install -y ipvsadm

 

(2)ipvs:内核存在(CentOS默认支持)

工作于内核上的netfilterINPUT钩子之上的程序代码;其集群功能依赖于ipvsadm定义的集群服务器规则;
支持基于TCP、UDP、SCTP、AH、EST、AH_EST等协议的众多服务;

 

4.负载均衡集群中设计时的要点:

(1)session保持
session sticky (iphash):IP地址绑定,来源IP记录在ip hash表作统一调度
session cluster(multicast/broadcast/unicast):广播集群同步(复制)session,只适用于小规模场景
session server ():session服务器

(2)数据共享(提供一致性存储)
1) 共享存储;
NAS:Network Attached Storage (文件级别),网络附加存储,文件服务器
SAN:Storage Area Network (块级别),存储区域网络
DS:Distributed Storage,分布式春初
2) 数据同步:rsync … ...

LVS模型

1.lvs-nat:地址伪装模型
多目标的DNAT:通过将请求报文的目标地址和目标端口修改为挑选出某RS的RIP和PORT来实现;
客户端主机发起请求报文CIP指向VIP,通过内核的核心网卡间转发功能,VIP会将请求交给DIP进行调度,DIP根据设定的算法进行负载均衡给后端的RS主机的RIP,在这个过程中DIP调度功能会将目标IP地址重写为RIP。请求和返回请求读要调度DIP来进行转换操作。
技术分享
(1)RIP和DIP应该使用私网地址,RS的网状应该指向DIP;
(2)请求和响应报文都要经由director转发;极高负载的场景中,Director可能会成为系统瓶颈(响应报文大);
(3) 支持端口映射(转发);
(4) VS必须为Linux,RS可以为任意操作系统;
(5)RS的RIP与Director的DIP必须在同一IP网络;

 

2.lvs-dr(direct routing直接路由):网关模型
通过修改请求报文的MAC地址进行转发;IP首部不会发生变化(源IP为CIP,目标IP始终为VIP)
客户端发起请求,经过层层路由到达离VS服务器最近的交换机,通过交换机转发给VS服务器,由VS服务器负载均衡转发请求给RS服务器。在此过程中VIP修改MAC地址调度请求给真实主机。在此过程中通过ARP协议在一个局域网中广播寻找真实主机的MAC地址。每个RS真实主机的网卡会一个别名地址VIP,实现全过程源地址为CIP,目标地址为VIP不变。调度基于寻找MAC。网关模型中的所有主机均要能与外网通信。这样RS主机就能够直接响应客户机。
技术分享

(1)确保前端路由器将目标IP为VIP的请求报文一定会发送给Director;
解决方案:
1)静态绑定;
2)禁止RS响应VIP的ARP请求;
a) arptables上定义;
b) 修改各RS的内核参数,并把VIP配置在特定的接口上实现禁止其响应;

(2)RS的RIP可以使用私有地址,也可以使用公网地址;
RIP使用私有地址可以通过在之前加一个路由器的方式和外网通信,直接响应客户机
(3)RS跟Director必须在同一物理网络中;
(4)请求报文必须由Director调度,但响应报文必须不能经由Director;
(5) 不支持端口映射;
(6) 各RS可以使用大多数的操作系统;

 

3.lvs-tun(ip tunneling):IP隧道模型
转发方式:不修改请求报文的IP首部(源IP为CIP,目标IP为VIP),而是在原有的IP首部这外再次封装一个IP首部(源IP为DIP,目标IP为RIP);
(1)RIP,DIP,VIP全得是公网地址;
(2)RS的网关不能也不可能指向DIP;
(3)请求报文经由Director调度,但响应报文将直接发给CIP;
(4) 不支持端口映射;
(5)RS的OS必须支持IP隧道功能;

 

4.lvs-fullnat:完整模型(同时改变请求报文的源IP和目标IP)
通过同时修改请求报文的源IP地址(cip-->dip)和目标IP地址(vip--> rip)实现转发;
注意:前三种为标准类型,第四种为后添加类型,内核默认可能不支持,需自编译内核
(1)VIP是公网地址;RIP和DIP是私网地址,且可以不在同一IP网络中,但需要通过路由互相通信;
(2)RS收到的请求报文的源IP为DIP,因此其响应报文将发送给DIP;
(3)请求报文和响应报文都必须经由director;
(4) 支持端口映射;
(5) RS可使用任意OS;

LVS scheduler调度算法

1.静态方法:仅根据算法本身进行调度
(1)RR :round robin,轮询机制,依次分配请求,方式简单但时负载均衡的效果一般
(2)WRR :weighted rr,加权轮询,权重越大承担负载越大
(3)SH :source ip hash,源地址哈希,将来自同一个ip请求通过记录在ip hsash表中绑定在同一个服务器,实现session保持
缺点:调度粒度大,对负载均衡效果差;session黏性不同,连接时长保持不同
(4)DH :desination ip hash,目标地址哈希。能实现连接追踪,但不考虑负载均衡效果
正向web代理,负载均衡内网用户对互联网的请求;
Client--> Director --> Web Cache Server(正向代理)

 

2.动态方法:根据算法及各RS当前的负载状态进行评估

Overhead 负载值,VS转发时记录每个RS的Active和Inactive数量(甚至权重)进行算法计算
Active 活动链接值,当发起新请求后保持在ESTABLISHED状态时,仍有请求响应
Inactive 非活动链接值,在ESTABLISHED状态时,尚未断开保持空闲等待状态

(1)LC:least connection,最少连接
Overhead=Active*256+Inactive
后端的RS谁的连接少就分发请求至那台RS,若overhead一样则自上而下轮询列表中的RS

(2)WLC:weighted least connection,加权最小连接
Overhead=(Active*256+Inactive)/weight,计算结果小的将为选中的下一跳RS服务器
缺点:当Overhead一样时,自上而下轮询响应,权重小的若在列表上方则其会响应

(3)SED:Shortest Expection Delay,最短期望延迟
Overhead=(Active+1)*256/weight
缺点:解决WLC问题,但时无法确保权重小的主机一定响应

(4)NQ:never Queue,永不排队,SED算法改进
RS权重大小排列,每台RS服务器先分配一个请求,其余的按照权重大小计算分配

(5)LBLC:Locality-Based LC,基于本地的最少连接,动态的 DH连接算法

(6)LBLCR:LBLC with Replication,带复制功能的LBLC

ipvsadm命令

1.管理集群服务:

ipvsadm -A|E -t|u|f service-address [-s scheduler][-p [timeout]] ipvsadm -D -t|u|f service-address 
-A:添加 -E:修改 -D:删除 -t, tcp, vip:port TCP的ip和port -u, udp, vip:port UDP的ip和port -f, fwm, MARK 防火墙标记 -s scheduler:默认为WLC调度算法,可省; -p [timeout] :超出时长,持久连接相关,默认时长为300秒 

 

2.管理集群服务上的RS:

ipvsadm-a|e -t|u|f service-address -rserver-address [-g|i|m] [-w weight] ipvsadm -d -t|u|f service-address -rserver-address 
-a:添加一个RS -e:修改一个RS -d:删除一个RS server-address指的是rip[:port],端口可省表示与之前的service-address相同,只有nat模式支持端口映射才会使用 [-g|i|m] -g:GATEWAY (默认),lvs-dr模型 -i: IPIP, lvs-tun隧道模型 -m: MASQUERADE,lvs-nat模型 

 

3.查看

ipvsadm -L|l[options] -n:numeric,数字格式显示地址和端口; -c:connection,显示ipvs连接; --stats:显示统计数据; --rate:速率 --exact:精确值,不经过单位换算的数值 

 

4.清空规则:

ipvsadm -C 

 

5.数器清零:

ipvsadm -Z [-t|u|f service-address]

 

6.保存和重载:

保存:

ipvsadm-S > /PATH/TO/SOME_RULE_FILE ipvsadm-save > /PATH/TO/SOME_RULE_FILE 

 

重载:

ipvsadm -R < /PATH/FROM/SOME_RULE_FILE ipvsadm-restore< /PATH/FROM/SOME_RULE_FILE 

注意:需要结合重定向一起使用,从自定义的规则文件中导入导出

 

附录(ipvsadm -h):

ipvsadm-A|E -t|u|f service-address [-s scheduler] [-p[timeout]] [-M netmask] [-b sched-flags] ipvsadm-D -t|u|f service-address ipvsadm-C ipvsadm-R ipvsadm-S [-n] ipvsadm-a|e -t|u|f service-address -r server-address [-g|i|m][-w weight] [-x upper] [-y lower] ipvsadm-d -t|u|f service-address -r server-address ipvsadm-L|l [options] ipvsadm-Z [-t|u|f service-address] ipvsadm--set tcp tcpfin udp ipvsadm-h

本文转载自:http://www.linuxprobe.com/lvs-load-balancing...ervice-1.html

更多Linux干货请访问:http://www.linuxprobe.com/

以上是关于k8s集群中ipvs负载详解的主要内容,如果未能解决你的问题,请参考以下文章

k8s资源对象service-四层负载均衡详解

Linux企业运维——K8s高可用集群架构搭建详解

Linux企业运维——K8s高可用集群架构搭建详解

Linux企业运维——K8s高可用集群架构搭建详解

k8s入门教程详解

k8s入门教程详解