前言KubernetesPod是有生命周期的,可以创建也可以销毁,一旦销毁,生命将永远结束。Pod可以通过ReplicationController动态创建和销毁(例如,当需要缩放时,或执行滚动升级时)。每个Pod都会获得自己的IP地址,但一旦销毁,重新创建后IP地址会发生变化。这会导致一个问题:在Kubernetes集群中,如果一组Pod(称为backend)为其他Pod(称为frontend)提供服务,一旦backendPod被重新创建,frontendPod应该如何发现并连接?组Pod中的后端是什么?ServiceService资源用于为pod对象提供固定统一的访问接口和负载均衡能力,利用新一代DNS系统的服务发现功能解决客户端发现和容器化应用访问问题。注意:服务只在k8s集群内部起作用,外部访问集群无效。其实现原理是Service定义了一个由多个POD对象组成的逻辑集合,并定义了访问这组POD的策略。服务需要标签选择器来关联POD。完成后,它根据标签选择器将一组POD定义成一个逻辑集合,通过自己的IP地址和端口向后端POD派发代理请求。apiVersion:v1kind:Servicemetadata:name:a-servicespec:selector:app:pod-labelports:-protocol:TCPport:80targetPort:9376上面的示例服务a-service与标签为[app:pod-label]的pod相关联.届时,另一个服务B可以访问绑定到a-service服务的服务。服务信息是固定的,提前告诉B。service通过LabelSelector绑定到aservice的pod上。不管a的pod如何变化,它对于b都是透明的。虚拟IP服务对象的IP地址称为集群IP,位于K8S集群配置指定的专用IP地址范围内。是服务对象创建后保持不变的虚拟IP地址,可供同一集群内的POD资源使用。Access,服务端口接受客户端的请求,转发到后端POD中对应的端口。因此,它也被称为四层代理,因为它工作在TCP/IP层。一个服务对象是工作节点上的一些iptables或ipvs,用于将到达该服务对象IP地址的流量转发到对应端点对象指定的IP地址和端口。kube-proxy组件持续监控每个Service及其相关的POD对象,并将其创建或更改实时反映到工作节点的iptable或ipvs中。k8s集群中的每个节点都运行一个kube-proxy组件。kube-proxy其实是一个代理层,负责实现serviceuserspace方式的客户端访问ServiceIP(clusterIP)请求,会先从用户空间到内核中的iptables,再回到用户空间kube-proxy,kube-proxy负责代理工作.具体细节:请求到达服务后,转发给内核,通过socket发送到用户空间的kube-proxy,再通过kube-proxy传回内核空间,调度到后面-结束POD。传输方式效率太低。在1.1版本之前,它是默认的转发策略。在iptables模式下,客户端访问ServiceIP(clusterIP)请求会被iptables直接重定向到后端。具体细节:客户端IP请求时,直接请求本地内核服务ip,请求根据iptables的规则直接转发给各个pod,因为使用iptableNAT完成转发也有不可忽视的性能损耗。另外,如果集群中有几万个Services/Endpoints,Node上的iptables规则会非常庞大??,性能会进一步打折扣。在Kubernetesv1.2之前,默认是userspace然后是iptables模式。iptables模式的性能和可靠性更好,但iptables模式依赖于健康检查。如果一个pod在没有健康检查的情况下没有响应,那么iptables模式将不会切换到另一个pod上的ipvs模式。该模型跟踪API服务上的服务和端点对象的变化,并相应地调用netlink接口创建IPVS规则并确保API服务器中的变化保持同步。它的流量调度策略在IPVS中实现,其余在iptables中实现。ipvs支持很多调度算法,如rr、lc、dh、sh、sed、nq等。集群外访问我们如何访问集群外的服务呢?k8s提供了几种NodePort通过每个Node上的IP和静态端口(NodePort)暴露服务的方式。NodePort服务将被路由到自动创建的ClusterIP服务。可以通过请求NodeIP:Port从集群外部访问NodePort服务。如果此时要访问这个Service,只需要访问<任意宿主机的IP>:PortLoadBalancerKubernetes基于NodePort,可以请求底层云平台云提供商创建外部负载均衡器,并将请求转发给各个节点用作服务分发的后端。该模式需要底层云平台(如GCE、AWS)的支持。ExternalName创建一个dns别名来引用服务名,主要是为了防止服务名发生变化,需要配合dns插件使用。通过返回CNAME及其值,可以将服务映射到externalName字段的内容。只有Kubernetes1.7或更高版本的kube-dns支持Ingress。上面我们提到了几种方法,但是当集群服务比较多的时候,NodePort方式最大的缺点就是会占用大量的集群机器端口;LB方式最大的缺点是每个服务一个LB有点浪费和繁琐,需要k8s以外的支持;而ingress只需要一个NodePort或者一个LB就可以满足所有服务的对外服务需求。工作机制大致可以用下图来表示:Ingress是基于service实现七层路由转发能力
