一、面临的问题
- 多个后端示例,如何做到负载均衡?
- 如何保持会话亲和性?
- 容器迁移,ip发生变化如何访问?
- 健康检查怎么做?
- 怎么通过域名访问?
二、userspace代理模型
1、工作原理
此处的userspace是指Linux操作系统的用户控件、这种模型中kuber-proxy负责跟踪API Server上service于endpoints对象变动(创建或移动)、并根据此调整service资源的定义
对于每个service对象,它会随机打开一个本地端口(运行于用户控件的kube-proxy进程负责监听)、任何到达此代理端口的连接请求都将被代理至当前service资源后端的各pod对象上
至少会挑选中一那个pod对象则取决于当前service资源调度方式默认调度算法是轮询其工作逻辑如图架构图所示
2、架构图
另外此类service对象还会创建iptables规则捕捉任何到达ClusterIP和端口的流量在 1.1版本之前userspace是默认代理模型
3、kubernetes 的service于endpoints
4、Service的内部逻辑
5、优缺点
这种代理模式中、请求流量到达内核空间后经由套接字送往用户空间的kuber-proxy、而后再由它送回内核空间,并调度至后端pod。
缺陷:这种方式中、请求内核空间和用户空间来回转发必然会导致效率不高
三、Iptables实现Service负载均衡
1、工作原理
用户空间应用程序、通过Netfilter规则表(Xtables)来构建Linux内核防火墙与网络包通过Netfilter全过程
2、架构图
3、Iptables实现流量转发与负载均衡
1、Iptables如何做流量转发?
DNAT实现IP地址和端口映射
iptables -t nat -A PREROUTING -d 1.2.3.4/32 --dport 80 -j DNAT --to-destination 10.20.30.40:8080
2、Iptables如何做负载均衡?
statistic模块为每个后端设置权重
iptables -t nat -A PREROUTING -d 1.2.3.4 --dport 80 -m statistic --mode random --probability .25 -j DNAT --to-destination 10.20.30.40:8080
3、Iptables如何做会话保持?
recent模块设置会话保持时间
iptables -t nat –A FOO -m recent --rcheck --seconds 3600 --reap --name BAR -j BAR
4、Iptables在Kubernetes的应用举例
Cluster IP: Port -> PREROUTING(OUTPUT) -> KUBE-SERVICES ->KUBE-SVC-XXX -> KUBE-SEP-XXX -> Pod IP: Target Port
5、优缺点
优点:相对于用户空间模型来说、Iptables模型无需将流量在用户空间和内核空间来回切换、因而更佳高效和可靠。
缺陷:不过、其缺点是代理模型不会在被挑中的后端pod资源无响应时自动进行重定向、而userspace模型则可以
四、当前Iptables实现存在的问题
1、规则线性匹配时延
- KUBE-SERVICES链挂了一长串KUBE-SVC-*链;访问每个service,要遍历每条链直到匹配,时间复杂度 O(N)
2、规则更新时延
1、时延出现在哪?
- - 非增 量式,即使加上 — no- - flush( iptables- - restore) 选项
- - Kube- - proxy 定期同步 iptables 状态:
* 拷贝所有规则: iptables-save * 在内存中更新规则 * 在内核中修改规则: iptables-restore * 规则更新期间存在kernel lock
2、5K service(40K 规则),增加一条iptables规则,耗时11min
3、 20K service(160K 规则),增加一条iptables规则,耗时5h
3、可扩展性
- 当系统存在大量iptables规则链时,增加/删除规则会出现kernel lock
kernel lock: Another app is currently holding the xtables lock. Perhaps you want to use the -w option?
4、可用性
- 后端实例扩容,服务会话保持时间更新等都会导致连接断开
5、Iptables优化
五、IPVS实现Service负载均衡
1、什么是IPVS(IP Virtual Server)
• Linux内核实现的L4 LB,LVS负载均衡的实现
• 基于netfilter, hash table
• 支持TCP, UDP, SCTP协议, IPV4, IPV6
• 支持多种负载均衡策略
- rr, wrr, lc, wlc, sh, dh, lblc…
• 支持会话保持
- persistent connection调度算法
2、IPVS三种转发模式
• 支持三种LB模式: Direct Routing(DR), Tunneling, NAT
1、DR模式工作在L2,最快,但不支持端口映射
2、Tunneling模式用IP包封装IP包,也称IPIP模式,不支持端口映射
DR和Tunneling模式,回程报文不会经过IPVS Director
3、NAT模式支持端口映射,回程报文经过IPVS Director
* 内核原生版本只做DNAT,不做SNAT
3、架构图及工作原理
4、IPVS做L4转发
1. 绑定VIP
- dummy 网卡
# ip link add dev dummy0 type dummy # ip addr add 192.168.2.2/32 dev dummy0
- 本地 路由表
# ip route add to local 192.168.2.2/32 dev eth0 proto kernel
- 网卡 别名
# ifconfig eth0:1 192.168.2.2 netmask 255.255.255.255 up
2. 创建IPVS Virtual Server
# ipvsadm -A -t 192.168.60.200:80 -s rr -p 600
3. 创建IPVS Real Server
# ipvsadm -a -t 192.168.60.200:80 -r 172.17.1.2:80 –m # ipvsadm -a -t 192.168.60.200:80 -r 172.17.2.3:80 –m
5、IPVS实现Kubernetes Service
6、Kubernetes支持IPVS模式
- 社区1.8 Alpha特性,Owner @m1093782566
- 社区1.9进beta,Owner @m1093782566
- 社区1.11进GA,广泛使用下一步成为默认模式
- 支持ClusterIP,NodePort,External IP,Load Balancer…类型Service、– iptables 模式的特性,IPVS 模式都支持!
- 兼容Network Policy
- 依赖iptables做SNAT和访问控制
六、Iptables VS. IPVS
1、Iptables VS. IPVS 规则刷新时延
观察结果:
- 增加一条Iptables的时延,随着规则数的增加“指数”上升
- 增加一条IPVS的时延,规则基数对其几乎没影响
2、Iptables VS. IPVS 网络带宽
观察结果:
- 增加一条Iptables的时延,随着规则数的增加“指数”上升
- 增加一条IPVS的时延,规则基数对其几乎没影响
Iptables VS. IPVS 资源消耗
Iptables VS. IPVS TPS与时延
Iptables VS. IPVS
Iptables
灵活,功能强大 在prerouting, postrouting, forward, input, output不同阶段都能对包进行操作
IPVS
更好的性能(hash vs. chain) 更多的负载均衡算法 - rr, wrr, lc, wlc, ip hash… 连接保持 - IPVS service更新期间,保持连接不断开 预先加载内核模 - nf_conntrack_ipv4, ip_vs, ip_vs_rr, ip_vs_wrr, ipvs_sh… # echo 1 > /proc/sys/net/ipv4/vs/conntrack
七、为什么还需要Iptables
1、因为我们访问了一层Service IP!
Node IP -> Service IP(Gateway) -> C
客户端:(Node IP, Service IP), 期望:(Service IP, Node IP)但实际,经过IPVS一层转发,包地址变成了(Node IP,C)
服务端发出:(C, Node IP) 这个包的源/目的地址与客户端期望的不一样!
故将被丢弃因此,需要一次SNAT(masquerade)!!(Node IP, Service IP) -> (IPVS director IP, C)
2、这也是为什么IPVS NAT模式要求回程报文必须经过director!
提问:为什么Container A -> Cluster IP -> Container B?
3、IPSet - 把O(N)的iptables规则降为O(1)
但,不想要太多iptables…
ipset create KUBE-LOOP-BACK hash:ip,port,ip ipset add KUBE-LOOP-BACK 192.168.1.1,udp:53,192.168.1.1 ipset add KUBE-LOOP-BACK 192.168.1.2,tcp:80,192.168.1.2
iptables -t nat -A POSTROUTING -m set --match-set KUBE-LOOP-BACK dst,dst,src -j MASQUERADEOUTING O(1)