站点图标 兰玉磊的个人博客

一文让你深入理解 Kubernetes 中的 Service 资源对象

介绍

在Kubernetes 集群中, Service是一个抽象的概念。它通过一个虚拟的IP的形式(VIPs),映射出来指定的端口,通过代理客户端发来的请求转发到后端一组Pods中的一台(也就是endpoint)。这样的好处呢?显而易见,在Kubernetes中用到的管理微服务的常用的到的类型就是deployment, 里面有个参数replicas 来管理整个deployment里面Pod的生命周期,因为有容器的销毁和生成导致Pod IP也就是动态变化的。而Service做为客户端和Pod(backends)中间的代理层,并抽象一个clusterIP的虚拟IP ,集群内部都可以通过这个IP访访问到具体Pod的服务。

Service在 Kubernetes 版本迭代中,有过几次变更。

在 Kubernetes v1.0 中开始使用 user space proxy mode (用户空间代理态代理模式)。

Kubernetes v1.1 增加了iptables 代理模式。

Kubernetes v1.2 默认把IPtables 当成kube-proxy 的代理模式。

在 Kubernetes v1.8 增加了性能更强劲的ipvs proxy mode。

kube-proxy作用

在Kubernetes中,Service的Cluster IP实现数据报文请求的转发,都离不开在node上部署的比较重要的一个组件kube-proxy。

总结来说kube-proxy实现的主要有几点作用。

Userspace 和 Kernelspace

说到kube-proxy 能操作iptables 和 netfilter 进行路由的变更和包的转发操作。

我们需要弄清楚两个概念:Userspace(用户空间) 和 Kernelspace(内核空间)。

在Linux 系统中,内存被分成两个不同的区域:Userspace、Kernelspace。

Userspace值得是,在操作系统中,用户安装的所有的软件和并启动的进程的服务。

Kernelspace是值得是在操作系统中,能执行命令,提供操作系统的底层服务的能力。

Userspace 需要操作系统的资源时,例如为计算指令需要请求占用CPU time 、操作磁盘的I/O,或者fork一个程序进程等。都需要call   Kernel 请求资源服务。

通常,Kernelspace模块和进程比Userspace进程快得多,因为它们直接与系统硬件交互。如果了解更深入,这里有redhat的的一篇文章。 

service 三种类型

kube-proxy三种模式

在K8s中,kube-proxy有三种模式在实现虚拟IP、路由信息和报文转发。

我们分别对着三种模式进入细节的讨论。

Userspace Proxy Mode

在userspace 模式下,kube-proxy 就是一个反向代理的功能,对userspace 的报文封装往 kernelspace 转发,主要是处理路由规则下发、包转发规则、负载均衡功能,所以kube-proxy会在网络流量比较高时,数据报文传输比较高的情况下,kube-proxy会频繁在userspace和kernelspace来回进行上下文切换。 

在这个模式下,kube-proxy 主要有这么几步来实现实现报文转发:

从VIP转发流量重定向到到node上的随机端口,进行netfilter 包过滤;再回Userspace进行负载均衡转发;在这个Userspace这个模式下,没有用到iptables的路由规则,kube-proxy在这个过程中多次进行 Userspace 和kernelspace 的切换,因此Userspace 模式对性能损耗比其它两个方式要大。 

当clusetr iP建立的时候,kube-proxy 就在本地node物理网卡上,生成一个随机端口,并建立了一条从 VIPs到node物理网卡IP上随机端口的netfiters规则。有请求包文转发到这个端口上的时候,kube-proxy 选择一个Pod并转发报文。

Iptables Proxy Mode 

基于userspace 模块性能原因,在 Kubernetes v1.2 以后,Iptables模式为Services的默认代理模式。在iptables 代理模式中,kube-proxy不在作为反向代理的在VIPs 和backend Pods之间进行负载均衡的分发。这个工作放给工作在四层的iptables来实现。iptables 和netfilter紧密集成,密切合作,都在kernelspace 就实现了包的转发。

在这个模式下,kube-proxy 主要有这么几步来实现实现报文转发:

在iptables模式中,kube-proxy把流量转发和负载均衡的策略完全委托给iptables/netfiter 来做,这些转发操作都是在kernelspace 来实现,比userspace 快很多。  

在iptables 中kube-proxy 只做好watching API 同步最新的数据信息这个角色。路由规则信息和转发都放在了kernelspace 的iptables 和netfiter 来做了。但是,这个这个模式不如userspace模式的一点是,在usersapce模式下,kube-proxy做了负载均衡,如果选择的backend 一台Pod没有想要,kube-proxy可以重试,在iptables模式下,就是一条条路由规则,要转发的backend Pod 没有响应,且没有被K8S 摘除,可能会导致转发到此Pod请求超时,需要配合K8S探针一起使用。

IPVS proxy mode

IPVS是LVS一个组件,提供高性能、高可靠性的四层负载均衡器。IPVS 是IP Virtual Server的简写。IPVS构建在netfilter上,作为Linux 内核的一部分,从传输层实现了负载均衡。IPVS能直接转发 基于Services的TCP 和UDP到真实服务器。IPVS能直接构建一个VIPs 并通过负载均衡算法,把请求转发到backend Pod。可能会将IPVS视为Linux内核负载平衡器,类似于kube-proxy在用户空间模式下所做的工作。

我们都知道,在Linux 中iptables设计是用于防火墙服务的,对于比较少规则的来说,没有太多的性能影响。但是对于,一个K8S集群来说,会有上千个Services服务,当然也会转发到Pods,每个都是一条iptables规则,对集群来说,每个node上会有大量的iptables规则,简直是噩梦。

同样IPVS可以解决可能也会遇见这样大规模的网络转发需求,但是IPVS用hash tabels来存储网络转发规则,比iptables 在这上面更有优势,而且它主要工作在kernelspace,减少了上下文切换带来的开销。 

kube-proxy和IPVS在配置网络转发中,有这么几步:

IPVS支持的负载均衡算法有这么几种:

在node上通过 “–ipvs-scheduler”参数,指定kube-proxy的启动算法。 

总的来说,Kubernets的Service组件,越来越完善,性能也越来越高。至少现在,我们看到已经加入了四层的转发策略,在实际运用中,很多公司都有自己的接入层和中间API的网关,可以解决转发和流量调度;Pod服务注册通过调用服务中心也解决了对于后端Pod异常的监控检查功能。当然我们也希望尽量复用Kubernets技术和组件,降低服务的可维护性。

参考

https://www.cnblogs.com/xiangsikai/p/11413913.html

退出移动版