比如说我们在Kubernetes 名字空间"my-ns"中有个叫my-service的服务,DNS服务会创建一条"my-service.my-ns"的DNS记录。同在这个命名空间的Pod就可以通过"my-service"来得到这个Service分配到的Cluster IP,在其它命名空间的Pod则可以用全限定名"my-service.my-ns"来获得这个Service的地址。
Pod IP and Service Cluster IPPod IP 地址是实际存在于某个网卡(可以是虚拟设备)上的,但Service Cluster IP就不一样了,没有网络设备为这个地址负责。它是由kube-proxy使用Iptables规则重新定向到其本地端口,再均衡到后端Pod的。我们前面说的Service环境变量和DNS都使用Service的Cluster IP和端口。
就拿上面我们提到的图像处理程序为例。当我们的Service被创建时,Kubernetes给它分配一个地址10.0.0.1。这个地址从我们启动API的service-cluster-ip-range参数(旧版本为portal_net参数)指定的地址池中分配,比如--service-cluster-ip-range=10.0.0.0/16。假设这个Service的端口是1234。集群内的所有kube-proxy都会注意到这个Service。当proxy发现一个新的service后,它会在本地节点打开一个任意端口,建相应的iptables规则,重定向服务的IP和port到这个新建的端口,开始接受到达这个服务的连接。
当一个客户端访问这个service时,这些iptable规则就开始起作用,客户端的流量被重定向到kube-proxy为这个service打开的端口上,kube-proxy随机选择一个后端pod来服务客户。这个流程如下图所示:
根据Kubernetes的网络模型,使用Service Cluster IP和Port访问Service的客户端可以坐落在任意代理节点上。外部要访问Service,我们就需要给Service外部访问IP。
外部访问ServiceService对象在Cluster IP range池中分配到的IP只能在内部访问,如果服务作为一个应用程序内部的层次,还是很合适的。如果这个Service作为前端服务,准备为集群外的客户提供业务,我们就需要给这个服务提供公共IP了。
外部访问者是访问集群代理节点的访问者。为这些访问者提供服务,我们可以在定义Service时指定其spec.publicIPs,一般情况下publicIP 是代理节点的物理IP地址。和先前的Cluster IP range上分配到的虚拟的IP一样,kube-proxy同样会为这些publicIP提供Iptables 重定向规则,把流量转发到后端的Pod上。有了publicIP,我们就可以使用load balancer等常用的互联网技术来组织外部对服务的访问了。
spec.publicIPs在新的版本中标记为过时了,代替它的是spec.type=NodePort,这个类型的service,系统会给它在集群的各个代理节点上分配一个节点级别的端口,能访问到代理节点的客户端都能访问这个端口,从而访问到服务。
Label和Label selectorLabel标签在Kubernetes模型中占着非常重要的作用。Label表现为key/value对,附加到Kubernetes管理的对象上,典型的就是Pods。它们定义了这些对象的识别属性,用来组织和选择这些对象。Label可以在对象创建时附加在对象上,也可以对象存在时通过API管理对象的Label。
在定义了对象的Label后,其它模型可以用Label 选择器(selector)来定义其作用的对象。
Label选择器有两种,分别是Equality-based和Set-based。
比如如下Equality-based选择器样例:
environment = production tier != frontend environment = production,tier != frontend对于上面的选择器,第一条匹配Label具有environment key且等于production的对象,第二条匹配具有tier key,但是值不等于frontend的对象。由于kubernetes使用AND逻辑,第三条匹配production但不是frontend的对象。
Set-based选择器样例:
environment in (production, qa) tier notin (frontend, backend) partition第一条选择具有environment key,而且值是production或者qa的label附加的对象。第二条选择具有tier key,但是其值不是frontend和backend。第三条选则具有partition key的对象,不对value进行校验。