1. 简介
LVS 主要由两部分组成:
- ipvs:ip virtual server,是工作在内核空间上的一段代码,主要是实现调度的代码,它是实现传输层负载均衡的核心。
- ipvsadm:工作在用户空间,负责为ipvs内核框架编写规则,用于定义谁是集群服务,谁是后端真实服务器
IPVS 基于 Netfilter, Netfilter 的数据包有五个挂载点Hook Point:PRE_ROUTING、INPUT、OUTPUT、FORWARD、POST_ROUTING。IPVS工作在其中的INPUT链上
专有名词:
DS:Director Server,指的是前端负载均衡器。
RS:Real Server,指的是后端工作的服务器。
VIP:Virtual IP,用户请求的目标IP地址。
DIP:Director Server IP,前端负载均衡器的IP地址。
RIP:Real Server IP,后端服务器的IP地址。
CIP:Client IP,访问客户端的IP地址。
三种工作模式:
NAT: Network Address Translate
NAT模式下,请求包和响应包都需要经过LB处理。当客户端请求到达虚拟服务后,LB会对请求包做目的地址转换DNAT,将请求包的目的IP改为RS的IP;当收到RS的响应后,LB会对响应做源地址转换SNAT,将响应包的源IP改为LB的IP
DR: Direct Routing
DR 模式下,客户端请求包到达LB的虚拟服务IP端口后,LB不会改写请求包的IP和端口,但会改下请求包的MAC地址(源MAC地址是DIP所在接口的MAC,目的MAC是RS所在RIP接口所在的MAC,IP首部不会发生变化),然后将数据包转发;
数据包送到真实服务器后,判断请求报文的MAC地址是否自己的MAC地址,接收此报文,拆了MAC首部,发现目的地址是VIP后,向
lo:0
转发此报文 (每个RS主机上都有VIP,并且RIP配置在物理接口上,VIP配置在内置接口lo:0
上), 最终达到用户空间进程.真实服务器用户空间进行构建响应报文,将响应报文通过
lo:0
接口传给物理网卡处理请求后,响应包直接回给客户端,不再经过LB
FULLNAT:
FULLNAT模式,客户端感知不到RS, RS也感知不到客户端, 它们都只能看到LB. LB会对请求包和响应包都做SNAT和DNAT
三种工作模式比较:
- 转发效率:
DR > NAT > FULLNAT
- 组网要求:
- NAT: LB 和 RS 必须在同一个子网, 且客户端不能与LB/RS在同一子网
- DR: LB 和 RS 必须同一子网
- FULLNAT: 无要求
- 端口映射:
- NAT: 支持
- DR: 不支持
- FULLNAT: 不支持
负载均衡算法:
轮询(Round Robin)
加权轮询(Weighted Round Robin)
源地址哈希(Source Hash)
目标地址哈希(Destination Hash)
最小连接数(Least Connections)
加权最小连接数(Weighted Least Connections)
最小期望延迟( Shortest Expection Delay)
2. 内核支持
1 | lsmod|grep ip_vs |
3. ipvsadm
1 | apt install ipvsadm ipset -y |
管理命令:
1 | ipvsadm command [protocol] service-address |
ipvs 支持三种负载均衡方式:
- NAT
- TUN
- DR
NAT 模式:
1 | # 添加虚拟服务器,指定调度算法为 rr |
ipvs 和 iptables区别:
- 底层数据结构:iptables 使用链表,ipvs 使用哈希表
- 负载均衡算法:iptables 只支持随机、轮询两种负载均衡算法而 ipvs 支持的多达 8 种;
- 操作工具:iptables 需要使用 iptables 命令行工作来定义规则,ipvs 需要使用 ipvsadm 来定义规则。
此外 ipvs 还支持 realserver 运行状况检查、连接重试、端口映射、会话保持等功能。
4. kube-proxy
通过参数--ipvs-scheduler
配置负载均衡算法,默认为轮询(Round Robin):
- rr:round robin
- lc:least connection
- dh:destination hashing
- sh:source hashing
- sed:shortest expected delay
- nq:never queue
1 | # 1. 修改配置 |
5. Dummy Interface
1 | $ ip addr |
6. 总结
kube-proxy 启用 ipvs 模式,将在所有节点做三件事:
创建一个dummy类型虚拟网卡
kube-ipvs0
把 ClusterIP 地址添加到
kube-ipvs0
,同时添加到ipset中创建 ipvs service,其地址为ClusterIP:Port,ipvs server为所有的Endpoint地址,即Pod IP及端口
7. 问题
7.1 flannel 不正常
1 | # 无法访问 kube-apiserver |