01.Service

服务

Kubernetes Pods的创建和销毁都是为了匹配集群的状态。Pods是非永久性资源。如果您使用部署来运行您的应用程序,它可以动态地创建和销毁Pod。每个Pod都有自己的IP地址,然而在Deployment中,在某一时刻运行的Pod集可能与稍后运行该应用的Pod集不同。这就导致了一个问题:如果某套Pod(称其为 “后端”)为你的集群内的其他Pod(称其为 “前端”)提供功能,那么前端如何发现并跟踪连接到哪个IP地址,以便前端可以使用后端部分的工作负载?

A Kubernetes Service is an abstraction layer which defines a logical set of Pods and enables external traffic exposure, load balancing and service discovery for those Pods.

Kubernetes Service定义了这样一种抽象:一个Pod的逻辑分组及一种可以访问它们不同的策略;即Service是对一组提供相同功能的Pods的抽象,并为它们提供一个统一的入口。借助Service,应用可以方便的实现服务发现与负载均衡,并实现应用的零宕机升级。譬如考虑一个图片处理后端应用程序,它运行了3个副本。这些副本是可互换的:前端不需要关心它们调用了哪个后端副本。然而组成这一组后端程序的Pod实际上可能会发生变化,前端客户端不应该也没必要知道,而且也不需要跟踪这一组后端的状态;Service定义的抽象能够解耦这种关联。

CNI与服务的网络映射

为了给容器提供网络,K8s使用了CNI规范,Container Network Interface。CNI是一个规范,它汇集了一些用于开发插件的库,用于配置和管理容器的网络。它为K8s的各种网络解决方案提供了一个通用接口。你可以找到几个针对AWS、GCP、Cloud Foundry等的插件。虽然CNI定义了Pod网络,但它不能帮助你在不同节点的Pod之间进行通信。K8s网络的基本特征是:

  • 所有的Pod都能在不同的节点上相互通信。
  • 所有节点都能与所有的Pod进行通信。
  • 不要使用NAT

所有的Pod和节点的IP都不使用NAT进行路由。这是解决与使用一些软件,这将有助于你在创建一个Overlay网络:

K8s集群中,客户端需要访问的服务就是Service对象。每个Service会对应一个集群内部有效的虚拟IP,集群内部通过虚拟IP访问一个服务。Servicekube-proxy实现软件负载均衡器,负责将对Service的请求转发到后端的某个Pod实例上。且Kubernetes为每个Service分配了一个全局唯一的虚拟IP地址(Cluster IP),每个服务在Kubernetes架构上即变成了具备唯一IP地址的通信节点。此外,K8s还内建了基于域名的服务发现机制,KubernetesService NameService Cluster IP做一个DNS域名映射,优雅的解决了服务发现的问题。Kubernetes提供了内置的dns机制和ClusterIP机制,每个Service都自动注册域名,分配Cluster IP,这样服务间的依赖可以从IP变为nameDNS Server通过K8s api server来观测是否有新Service建立,并为其建立对应的dns记录。如果集群已经enable DNS,那么Pod可以自动对Servicename解析。

譬如,有个叫做my-serviceService,他对应的kubernetes namespacemy-ns,那么会有他对应的dns记录,叫做my-service.my-ns。那么在my-nsnamespace中的Pod都可以对my-servicename解析来轻松找到这个Service。在其他namespace中的pod解析my-service.my-ns来找到他。解析出来的结果是这个Service对应的Cluster IP

Links