service的概念 kubernetes的serivce定义了这样一种抽象:一个pod的逻辑分组,一种可以访问它的策略[通常称为微服务]。这一组Pod能够被service访问,通常是通过label Selector. service 能够提供负载均衡的能力,但是在使用上有如下的限制: 只能提供4层负载均衡能力,而没有7层功能,但有时我们可能需要更多的匹配规则来转发请求,这点上4层负载均衡是不支持的。 说明:此处补充4层和7层负载均衡的说明 四层和七层做的负载所基于的协议是不同的,四层是基于TCP/UDP的传输协议,而七层是基于应用协议(如proxy,http/https等)。 service 的类型: service在k8s中有如下四种类型: service代理访问过程图示 VIP和service代理 在k8s集群中,每个node运行一个kube-proxy进程。kube-proxy负责为service提供vip而不是external ip形式。在k8s 1.0 proxy实现在用户态(userspace),1.1新增了iptables代理,在1.2版本成为默认运行模式。1.8版本加入了ipvs,并且于1.14版本将其调整为默认项。 k8s 1.1版本新增了Ingress api,用来表示7层服务。 补充:为啥不使用roud robin dns: 代理模式的分类 userspace是Linux操作系统的用户空间。 这种模式下,kube-proxy负责跟踪API Server上Service和Endpoints对象的变动(创建或移除),并据此调整Service资源的定义。对于每个Service对象,它会随机打开一个本地端口(运行于用户控件的kube-proxy进程负责监听),任何到达此端口的连接请求都将代理至当前Service资源后端的各Pod对象上,至于会挑选中哪个Pod对象则取决于当前Service资源的调度方式(通过Service的SessionAffinity来确定),默认的调度算法是轮循(round-robin)。 ? 其代理的过程是:请求到达service后,其被转发至内核空间,经由套接字送往用户空间的kube-proxy,而后再由它送回内核空间,并调度至后端Pod。其传输效率太低,在1.1版本前是默认的转发策略。 iptables代理模式中,kube-proxy负责跟踪API Server上Service和Endpoints对象的变动(创建或移除),并据此作出Service资源定义的变动。同时,对于每个Service对象,它都会创建iptables规则直接捕获到达Cluster IP(虚拟IP)和Port的流量,并将其重定向至当前Service的后端。对于每个Endpoints对象,Service资源会为其创建iptables规则并关联至挑选的后端Pod资源,默认的调度算法是随机调度(random)。实现基于客户端IP的会话亲和性(来自同一个用户的请求始终调度到后端固定的一个Pod),可将service.spec.sessionAffinity的值设置为“ClientIP”(默认值为“None”)。 ? 其代理过程是:请求到达service后,其请求被相关service上的iptables规则进行调度和目标地址转换(DNAT)后再转发至集群内的Pod对象之上。 相对userspace模式来说,iptables模式无须将流量在用户空间和内核空间来回切换,因而更加高效和可靠。其缺点是iptables代理模型不会在被挑中的Pod资源无响应时自动进行重定向;而userspace模式则可以。 ? kube-proxy跟踪API Server上Service的Endpoints对象的变动,据此来调用netlink接口创建ipvs规则,并确保与API Server中的变动保持同步,其请求流量的调度功能由ipvs实现,其余的功能由iptables实现。ipvs支持众多调度算法,如rr、lc、dh、sh、sed和nq等。 ipvs使用哈希表作为底层数据结构并在内核空间工作,可以更快的重定向流量,并且在同步代理规则时具有更好的性能。 clusterip clusterip主要在每个node节点使用iptables,将发向clusterip对应端口的数据,转发到kube-proxy中。然后kube-proxy自己内部实现有负载均衡的方法,并可以查询到这个service下对应pod的地址和端口,进而把数据转发给对应的pod的地址和端口。 为了实现上图的功能,需要以下几个组件的协同工作 headless service 如果不需要负载均衡以及单独的service ip。遇到这种情况,可以通过指定clusterip的值为none来创建headless service。这类service不会分配cluster ip,kubeproxy也不会处理它们,而且平台也不会为它们进行负载均衡和路由。 nodeport nodeport的原理在于在node上开了一个端口,将该端口的流量导入到kube-proxy,然后由kube-proxy进一步给到对应的pod。 loadBalancer: loadbalancer和nodeport其实是同一种方式。区别在于loadbanlancer比nodeport多了一步,就是可以调用 云厂商 去创建lb来向节点导流。 ExternalName externalname是service的特例,其没有selector,也没有定义任何的端口和endpoint。相反的,对于运行在集群外部的服务,其通过返回该外部服务器的别名这种方式来提供服务。 实际使用场景有:不同的namespace的pod服务互相通信,pod引用或者调用集群外部服务,如:数据库,redis等。
用一个寻址机制来标识一个特定的应用程序(端口号)
网络服务与使用者应用程序间的一个接口