每台机器上都运行一个kube-proxy服务,它监听api-server 和endpoint变化情况,维护service和pod之间的一对多的关系,通过iptable或者ipvs为服务提供负载均衡的能力。通常kube-proxy作为deemonset运行在各种节点中。
kube-proxy 常支持以下二种:
1)iptables:iptable模式是目前的默认模式,可以看成是userspace模式的升级版,它将请求的代理转发规则全部写入iptable中,砍掉了kube-proxy转发的部分。整个过程全部发生在内核空间,提高了转发性能。但是,iptable的规则是基于链表实现的,规则数量随着Service数量的增加线性增加,查找时间复杂度为O(n)。当Service数量到达一定量级时,CPU消耗和延迟增加显著
2)ipvs:ipvs模式是基于章文嵩博士开发的LVS实现的,ipvs和iptables都是基于内核的netfilter框架实现的,不同的是iptable主攻防火墙,ipvs主攻内核态4层负载均衡。可以说先天上,ipvs就比iptable更适合做Service的实现。
下面重点说下iptables,下图是网上看到的一张图作为理解。
iptables其实不是真正的防火墙,我们可以把它理解成一个客户端代理,用户通过iptables这个代理,将用户的安全设定执行到对应的”安全框架”中,这个”安全框架”才是真正的防火墙,这个框架的名字叫netfilter。
netfilter才是防火墙真正的安全框架(framework),netfilter位于内核空间。
iptables其实是一个命令行工具,位于用户空间,我们用这个工具操作真正的框架。
netfilter 包括 5个hook(prerouting,input,foeward,output,poostrouting) 函数 和 4张表(filter, net,mangle, row).
filter表:负责过滤功能,防火墙;内核模块:iptables_filter
nat表:network address translation,网络地址转换功能;内核模块:iptable_nat
mangle表:拆解报文,做出修改,并重新封装 的功能;iptable_mangle
raw表:关闭nat表上启用的连接追踪机制;iptable_raw
下图是hook函数和各个表的对应关系,黄色代表的链式关系。
上图简单说明下,一个请求首先会进入prorouting,prorouting没有过滤的功能,会判断这个请求是流向,是外部还是内部的,如果是外部请求就会直接forward出去,如果是内部的请求就会走到input,然后到达应用层处理后会经过outoput 然后再发出去。中间会经过一系列的过滤规则,有一条不符合就会,reject或者drop掉。
通常使用来查看本机table名为TABLE_NAME的iptable规则
iptables -t TABLE_NAME -vnL
比如查看filter 表的规则信息,下图展示了input和forward规则信息。
tdp
、udp
、icmp
和 all
。anywhere
。anywhere
。还有一列没有表头,显示在最后,表示规则的选项,作为规则的扩展匹配条件,用来补充前面的几列中的配置。prot
、opt
、in
、out
、source
和 destination
和显示在 destination
后面的没有表头的一列扩展条件共同组成匹配规则。当流量匹配这些规则后就会执行 target
。
分析iptables:
上图展示k8s集群中nginx服务,cluster -ip 是 10.1.125.152.对主机暴露了30978端口,对应了二个后端pod分别是10.244.0.10,10.244.0.9。
1.iptables -t nat -L KUBE-SERVICES |egrep 'nginx'
可以看到来自cluster -ip为 10.1.125.152的流量都会转发到KUBE-SVC-27XJ54RMCFYE2CYL 链上处理,接下来看下KUBE-SVC-27XJ54RMCFYE2CYL上的规则。
2. iptables -t nat -L KUBE-SVC-27XJ54RMCFYE2CYL
可以看到 KUBE-SVC-27XJ54RMCFYE2CYL 有二条规则,第一条是50%的概率到KUBE-SEP-VSD6RSQTLEBJCSMF上,匹配不到就会落到下面的那条规则。
3.查看那边50%的概率到KUBE-SEP-VSD6RSQTLEBJCSMF。iptables -t nat -L KUBE-SEP-VSD6RSQTLEBJCSMF
可以清晰看到上面的规则就会路由到一个pod上了。另一个也是一样的规则只不过路由到另外一个pod上了,如下图:
完!