玖叶教程网

前端编程开发入门

6、Kubernetes - Service(kubernetes认证)

service的概念

kubernetes的serivce定义了这样一种抽象:一个pod的逻辑分组,一种可以访问它的策略[通常称为微服务]。这一组Pod能够被service访问,通常是通过label Selector.


k8s的service示意图

service 能够提供负载均衡的能力,但是在使用上有如下的限制:

只能提供4层负载均衡能力,而没有7层功能,但有时我们可能需要更多的匹配规则来转发请求,这点上4层负载均衡是不支持的。

说明:此处补充4层和7层负载均衡的说明

  • 四层负载:理解四层负载也简单。三层是通过IP去寻址,而四层的寻址粒度更小,在IP的基础 上,再增加PORT来寻址。在百度百科是这样描述的:
    用一个寻址机制来标识一个特定的应用程序(端口号)

  • 七层负载:该层是应用层,除了IP + PORT负载均衡外,还能根据更多的应用特征来做负载均衡。比如,根据请求的URL地址、请求的资源(如 png ,jpg,html,接口等)、请求的来源(移动端、PC)等等。在百度百科是这样描述的:
    网络服务与使用者应用程序间的一个接口

四层和七层做的负载所基于的协议是不同的,四层是基于TCP/UDP的传输协议,而七层是基于应用协议(如proxy,http/https等)。

service 的类型:

service在k8s中有如下四种类型:

  • clusterip:默认类型,自动分配一个仅cluster内部可以访问的虚拟ip。
  • nodeport:在clusterip的基础上为service在每台机器上绑定一个端口,这样就可以通过nodeport的方式来访问服务。
  • loadbalance:在Nodeport的基础上,借助cloud provider创建一个外部负载均衡器,并将请求转发到nodeport.
  • externalname:把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,该类型只有k8s 1.7或者更高版本的kube-dns才支持。

service代理访问过程图示

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:

  1. 因为这种方式下,客服端一般都会缓存一份列表到本地,客户端连接的时候只会使用本地存储的来进行连接而不是根据服务端的负载来连接,会造成负载不是那么均衡,而且有可能会出现热点。
  2. 该方案有ttl问题,服务端更新了,要等ttl时间过了,客户端才能和服务端使用新的配置,而这之前,都使用的是老的配置,并且这个时候,如果有一个服务端故障了,在tt时间超过之前,客户端接收到的信息都是失败,会导致消息阻塞。

代理模式的分类

  • userspace代理模式

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版本前是默认的转发策略。

userspace代理模式


  • iptables代理模式

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模式则可以。

iptables代理模式

  • ipvs代理模式

? kube-proxy跟踪API Server上Service的Endpoints对象的变动,据此来调用netlink接口创建ipvs规则,并确保与API Server中的变动保持同步,其请求流量的调度功能由ipvs实现,其余的功能由iptables实现。ipvs支持众多调度算法,如rr、lc、dh、sh、sed和nq等。

ipvs使用哈希表作为底层数据结构并在内核空间工作,可以更快的重定向流量,并且在同步代理规则时具有更好的性能。

ipvs代理模式

clusterip

clusterip主要在每个node节点使用iptables,将发向clusterip对应端口的数据,转发到kube-proxy中。然后kube-proxy自己内部实现有负载均衡的方法,并可以查询到这个service下对应pod的地址和端口,进而把数据转发给对应的pod的地址和端口。

cluseterip 实例

为了实现上图的功能,需要以下几个组件的协同工作

  • apiserver:用户通过kubectl命令向apiserver发送创建service的命令,apiserver接受到请求后将数据存储到etcd中。
  • kube-proxy:k8s的每个节点都有一个叫做kube-proxy的进程,这个进程负责感知service,pod的变化,并将变化的信息写入本地的iptables。
  • iptables使用nat等技术将vip的流量转入到endpoint中。

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来向节点导流。

loadbalance示例

ExternalName

externalname是service的特例,其没有selector,也没有定义任何的端口和endpoint。相反的,对于运行在集群外部的服务,其通过返回该外部服务器的别名这种方式来提供服务。

实际使用场景有:不同的namespace的pod服务互相通信,pod引用或者调用集群外部服务,如:数据库,redis等。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言