K8S中的Service的存在理由

###前言 Kubernetes Pod是有生命周期的,它们可以被创建,也可以被销毁,然而一旦被销毁生命就永远结束。 通过ReplicationController能够动态地创建和销毁Pod(例如,需要进行扩缩容,或者执行滚动升级)。

成都创新互联公司是一家专业提供如东企业网站建设,专注与成都网站建设、成都做网站HTML5、小程序制作等业务。10年已为如东众多企业、政府机构等服务。创新互联专业网站建设公司优惠进行中。

每个 Pod 都会获取它自己的 IP 地址,可一旦销毁后,重新创建后,IP地址会产生改变。 这会导致一个问题:在 Kubernetes 集群中,如果一组 Pod(称为 backend)为其它 Pod (称为 frontend)提供服务,一旦backend的Pod重新创建,那么frontend的Pod该如何发现,并连接到这组 Pod 中的哪些 backend 呢? ###Service Service资源用于为pod对象提供一个固定、统一的访问接口及负载均衡的能力,并借助新一代DNS系统的服务发现功能,解决客户端发现并访问容器化应用的问题。

注意:service只是在k8s集群内部起作用,集群外部访问是无效的 ###实现原理 Service通过关注定义出多个POD对象组合而成的逻辑集合,以及访问这组POD的策略,Service关联POD需要标签选择器完成,其基于标签选择器将一组POD定义成一个逻辑集合,并通过自己的IP地址和端口调度代理请求至后端POD之上。 ```js apiVersion: v1 kind: Service metadata: name: a-service spec: selector: app: pod-label ports: - protocol: TCP port: 80 targetPort: 9376 ``` 上面的例子服务a-service关联着label为【app:pod-label】的pod,这时候另一个服务B可以访问跟a-service服务绑定的service,service信息是固定的提前告诉B就行了,service通过Label Selector跟a服务的pod绑定,无论a的pod如何变化对b来说都是透明的。

###虚拟IP service对象的IP地址称为cluster IP,位于K8S集群配置指定的专用IP地址范围内,其是一种虚拟IP地址,其在service对象创建后保持不变,并且能够被同一集群中的POD资源访问,service端口接受客户端的请求并将其转发至后端POD中的相应端口,因此,其又被称为四层代理,因其工作在TCP/IP层。

一个service对象就是工作节点上的一些iptables或ipvs,用于将到达service对象的IP地址的流量转发到相应的endpoint对象指定的IP地址和端口上,kube-proxy组件通过api-server持续监控着各个service及其相关的POD对象,并将其创建或变动实时反映到工作节点的iptable或ipvs上 ###服务代理 k8s群集中的每个节点都运行一个kube-proxy的组件,kube-proxy其实是一个代理层负责实现service ###userspace模式 客户端访问ServiceIP(clusterIP)请求会先从用户空间到内核中的iptables,然后回到用户空间kube-proxy,kube-proxy负责代理工作。

###具体细节: 请求到达service后,其被转发到内核,经由套接字送往用户空间的kube-proxy,而后经由kube-proxy送回内核空间,并调度至后端POD,其传输方式效率太低。在1.1 版本之前,其是默认的转发策略。 ###iptables模式 客户端访问ServiceIP(clusterIP)请求会由iptables直接重定向到后端 ###具体细节: 客户端IP请求时,直接请求本地内核service ip,根据iptables的规则直接将请求转发到到各pod上,因为使用iptable NAT来完成转发,也存在不可忽视的性能损耗。

另外,如果集群中存在上万的Service/Endpoint,那么Node上的iptables rules将会非常庞大,性能还会再打折扣 Kubernetes v1.2之前默认是userspace之后是iptables模式,iptables模式性能和可靠性更好,但是iptables模式依赖健康检查,在没有健康检查的情况下如果一个pod不响应,iptables模式不会切换另一个pod上 ###ipvs模型 此模型跟踪API service上的service和endpoints对象的变动,据此来调用netlink接口创建IPVS规则,并确保API server中的变动保持同步,其流量调度策略在IPVS中实现,其余的在iptables中实现。 ipvs 支持众多调度算法,如rr、lc、dh、sh、sed和nq 等。 ###集群外部访问 我们如何在集群外访问service呢?k8s提供了几种方式 ###NodePort 通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 NodeIP:Port,可以从集群的外部访问一个 NodePort 服务。

这时要访问这个Service的话,只需要通过访问 :Port ###LoadBalancer 在NodePort基础上,Kubernetes可以请求底层云平台cloud provider 创建一个外部的负载均衡器,并将请求转发到每个Node作为后端,进行服务分发。 该模式需要底层云平台(例如GCE、AWS)支持。 ###ExternalName 创建一个dns别名指到service name上,主要是防止service name发生变化,要配合dns插件使用。通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容。

这只有 Kubernetes 1.7 或更高版本的 kube-dns 才支持 ###Ingress 上面我们提到几种方式,但是当集群服务很多的时候,NodePort方式大的缺点是会占用很多集群机器的端口;LB方式大的缺点则是每个service一个LB又有点浪费和麻烦,并且需要k8s之外的支持; 而ingress则只需要一个NodePort或者一个LB就可以满足所有service对外服务的需求。


网站标题:K8S中的Service的存在理由
文章网址:http://ybzwz.com/article/sdeogj.html