Service 理论
之前我们提到Pod是Kubernetes用来部署的最小的原子单元,并且Pod is mortal Pod终有一死。
当kubernetes执行扩展,自恢复操作时,原来的Pod就会死掉,被新的Pod代替。那么原有Pod对应的IP就将不再工作。
这就导致了单独Pod的IP是不稳定的,是不能够依赖的。Kubernetes Service
能够拥有稳定的IP地址,DNS名字和端口。
Kubernetes Service 和Pods关联起来,并为这些Pod提供路由服务。如下图所示。
通过在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监听端口)。
Comments are closed.