Skip to content

Kubernetes(四)–Kubernetes Services 是如何工作的?

Service 理论

之前我们提到Pod是Kubernetes用来部署的最小的原子单元,并且Pod is mortal Pod终有一死。
当kubernetes执行扩展,自恢复操作时,原来的Pod就会死掉,被新的Pod代替。那么原有Pod对应的IP就将不再工作。
这就导致了单独Pod的IP是不稳定的,是不能够依赖的。Kubernetes Service 能够拥有稳定的IP地址,DNS名字和端口。

Kubernetes Service 和Pods关联起来,并为这些Pod提供路由服务。如下图所示。
Service路由
通过在Pod前面部署的Service, Pods可以自由的扩展,更新,回滚而不会影响到整个服务,这些也是Kubernetes的精髓。
那么有一个问题,当一个Pod死掉,新的Pod加入的时候Service是如何发现Pods的呢?

Service是如何发现Pods的呢?

同Deployments 管理Pods的理论一样,Service也是通过标签选择器来管理Pods的,并且是一个松耦合的标签选择器。
Pods必须拥有Service定义的所有标签,但是Pods可以拥有Service没定义的额外标签。
比如下面3种情况的前两种情况是可以管理Pod的,但是最后一种确实不可以管理到Pod的。

第一种情况完全匹配:
完全匹配

第二种情况: Pods可以拥有额外的标签
第二种

第三种情况:Pods少了一个标签,匹配失败
第三种

Service通过标签选择器会创建一个叫Endpoints的object,这个Endpoints会负责维护一个匹配的Pods列表。 当Service把流量发送到Pods时就会查询这个Endpoints
Endopoints永远维护着最新的PodService通过标签选择器会创建一个叫Endpoints的object,这个Endpoints会负责维护一个匹配的Pods列表。

如何在cluster内部访问service服务?

Kubernetes Service包含了多种类型,默认的类型是ClusterIP Service。 ClusterIP Service 拥有稳定的IP地址的端口。ClusterIP Service 会把Service 名字注册到Cluster内部的DNS Service。
而cluster中的所有Pod都能够直到DNS Service(这个是在创建Pod时写进去的),即默认能够解析Service。

如何在Cluster外部访问Service服务?

Kubernetes Service通过另一个类型叫NodePort Service来支持从cluster 外部访问service。NodePort Service 是基于ClusterIP Service,并且包含一个额外的端口叫NodePort。
NodePort Service 包含4个属性。

Name: magic-sandbox
ClusterIP: 172.12.5.17
port: 8080
NodePort: 30050

除了NodePort 类型,Kubernetes还支持LoadBalancer和ExternalName类型。 LoadBalancer是基于NodePort Service的,允许通过云服务厂商的load balancer来访问Pods。

不同于前3种Service 类型,ExternalName Service 则是把流量路由到Kubernetes cluster之外的一种类型。

Kubernetes 如何实现Service 发现

Kubernetes 支持两种方式实现Service 发现, 基于DNS Service和基于环境变量。

基于DNS 实现的方式,kubernetes dns service会持续检测API Server,并自动把新创建的Service 注册到DNS中。
而基于环境变量的实现方式只能在创建Pod时把Kubernetes Service相关的信息写到Pod中,这导致的一个最大的问题是Pod无法发现在Pod创建后创建的Service。
所以目前基于DNS的Service发现是主流。

实际定义一个Service

下面我们来看一个实际的Service 的manifest 定义
hello-svc.yml

apiVersion: v1
kind: Service
metadata:
  name: hello-svc
spec:
  type: NodePort
  ports:
  - port: 8080
    nodePort: 30001
    targetPort: 8080
    protocal: TCP
  selector:
    app: hello-world

port 指示这个叫hello-svc的Service对cluster内部请求监测8080,NodePort指示对外部请求监测30001,targetPort指示Service把请求发送到Pod的8080端口(即application service监听端口)。

Published inKubernetes

Comments are closed.

Author Copyriht by BackendSite