6. Service就是iptables规则
introduction
上一节里我们都只简单讲讲有什么组件, 这些组件大概都是干什么的, 但感觉不稳, 里面的流量走向感觉没理清楚, 感觉还是不清爽. 这一节里就想要把这些事情全都讲清楚了. 在k8s的service工作原理里, 主要涉及的组件包含有:
service controller(sc)
enpoint controller(ec): 当用户创建service以及对应的后端pod的时候, ec负责监控pod的状态变化, pod状态为就绪的时候就创建一个endpoint并指向这组pod
kube-proxy(proxy): 这家伙运行在每个节点上
监控service以及endpoints的状态更新 → "监控"
并调用proxy下的load-balancer模块在宿主机上刷新路由转发规则 → "刷新路由表"
这一节我们主要讲讲这个刷新路由表是怎么回事, 因为这事关流量能不能被正确的指引到后端pod上, 目前可能的实现方式包含: iptables / ipvs / userspace 三种
userspace模式
这种模式其实已经很少使用了, 因为按照他的做法, 流量的转发发生在 用户态 , 故而效率不仅不高而且还容易产生丢包, 时髦的玩法下转发都是在内核态里, 但相对应的对内核版本也有一定要求, 想象一下, 仅仅因为你版本不够高, 连k8s的service都用不了了这可还行? 因此这种模式倒也一直存在着
在userspace的玩法中, 访问服务的请求先是到达了从节点, 然后进入内核iptables, 然后又回到用户态下, 由proxy完成后端Pod的选择, 并建立一条通往pod的连接. 这是一套比较古老(也可以认为是经典) 的玩法, 假设我们现在有一个service(按照userspace模式运行中)
service 为cluser ip + port →
10.254.132.107:2222
NodePort 为宿主机ip + port →
10.0.0.5:30239
从上面的内容有两点很有意思, 任何一个流量到达宿主机以后会先经过iptables判断接下来往哪儿走,
我们看看这个流量是从哪里出发的, 如果是从pod出发的, 就 REDIRECT, 如果是宿主机出发的, 就 DNAT, 这两种做法很有意思, 首先我不知道你是怎么判断出 source 的, 还有就是为什么一个 redirect 另一个 dnat
接下来我们发现无论你是谁, 最后都去 36463, 这个端口跟service无关, 纯kube-proxy自己干的事, 自己监听这个端口, 然后把流量转发到后端Pod上
我们对着iptables找规则 → 在内核态
找到规则转发给proxy由proxy负责转发 → 又回去用户态里了
iptables模式
总结: 那么相比于userspace, 我们现在直接在内核空间里(iptables直接搞定)就能转发, 不需要去用户空间里要求kube-proxy来帮你转发了, 效率确实提升了不少
ipvs模式
IPVS是LVS的一个组件, 负责负载均衡的组件, 也是基于netfilter实现的, 为什么需要它呢? 明明上面才把iptable模式吹的很牛逼呢~ 你想想, Linux中的iptable本身是拿来干什么用的, 人家是拿来搭防火墙的, 写几条就行了, 你呢? 把它当路由器用, 几百条规则咔咔往上整, 而且iptable的规则底层实现是链表啊是链表, 架得住你这么遍历? 仔细想想这么玩还是挺搞笑的.
Last updated
Was this helpful?