美文网首页
【k8s学习】Kubernetes Service介绍

【k8s学习】Kubernetes Service介绍

作者: 伊丽莎白2015 | 来源:发表于2022-06-23 20:33 被阅读0次

【文章内容】

  • Service组件的介绍,使用场景。
  • Service类型介绍ClusterIP Services, Headless Services, NodePort Services, LoadBalancer Services
  • 不同Service类型的区别以及使用场景。

【前置文章】


1. Service介绍

在前面的文章讲过,Pod虽然有自己的IP地址,但不是固定的,并且重启后就会变。而Pod设计出来就是瞬间的,即Pod会经常重启。

而Service的IP是比较稳定的,原因是它和Pod的生命周期是独立互不干扰的,Pod重启并不影响Service,并且Service提供负载均衡的功能,如Service下有3个Pod,请求通过Service进行转发到Pod的过程中,会考虑负载均衡(即随机发送)。

2. Service类型:ClusterIP

ClusterIP是Servie的默认类型,如果在yaml中没有声明具体的type,那么默认创建的Service就是这个类型。

ClusterIP又称为Internal Service(内部的Service),并不具备在集群外直接访问的能力。

2.1 Cluster Services
假设我们的Kubernetes架构如下: ClusterIP Service

【2个Worker工作节点】:

  • 节点1比如可以分配内部IP范围为:10.2.1.x(x表示0-255)
  • 节点2比如可以分配内部IP范围为:10.2.2.x

假设我们的Pod中跑了两个Container:

  • my-app-ms:my-app微服务,具体的业务跑在这里。containerPort为3000。
  • my-app-log-collector:my-app的log收集系统。containerPort为9000

Pod-1跑在上述的Node2中,即启动的时候被分配了内部地址为:10.2.2.5(可通过命令kubectl get pod -o wide来查看IP)
Pod-2跑在上述的Node1中,内部地址为:10.2.1.4。

这时候我们创建了一个Service,它定义了两个端口,一个为port,即自身Service的port(比如为3200),另一个为targetPort(比如3000)。同样的,Service也有自己的IP,比如10.128.8.64,有自己的name,比如my-app-service。

【问题】

  • 请求通过Ingress转发到Service后,Service是怎么找到Pod并转发的?
    答案是通过selector标签找到相应的Pod。(Pod定义中会有metadata.lables,全部的值一样就match上了)。
  • 转发的Port为多少?
    答案是通过targetPort找到相应的Port。

【总结就是Service通过selector找到相应的Pod,并通过targetPort找到Pod中具体的Container】

kubectl get endpoints可查看所有的endPoint,即为上述的10.2.1.4:3000,10.2.2.5:3000。

【ClusterIP的使用场景】

  • 使用场景-1即上述图中的场景,作为Ingress的后置,请求通过Ingress到达Service后,Service进行转发。
  • 使用场景-2:假设我们有MongoDB的Pod,为此我们创建了MongoDB的Service,这个时候的Service类型也可为ClusterIP,因为MongoDB的服务是为内部其它Pod提供的(比如上述的my-app-ms项目可以连接)。

【一个Service可以有多个Port吗?】
答案是可以的。在定义多个Port的时候,需要同时定义name作为区分。

【Ingress如何通过serviceName找到Service的IP并进行转发?】
答案是通过DNS Lookup,通过serviceName,返回Service IP,即上述的10.128.8.64。

2.2 Headless Service

假设一个Service下配置的selector与多个Pod match上了。但需求是:只想让请求访问某个固定的Pod,那么上述的ClusterIP Service是做不到的,因为它是负载均衡的,会随机的挑Pod进行访问。

什么情况下会产生上述的需求呢?比如我们在Kubernetes上部署了有状态的服务如DB(mysql, mongoDB),通过StatefulSet部署的有状态的Pod一般会按顺序启动,且第一台为Master Pod,负责读和写,其它为Workder Pod。

  • 写操作总是将请求转发到Master Pod上 --> 固定到Master Pod
  • 如果新起一台Worker Pod,它需要访问它的前面一台Pod来clone数据 --> 固定到前一个Pod

【如何做?】
把clusterIP设为None,这样DNS在查询的时候,则返回的是Pod的IP地址。

在定义Headless Service的时候,yaml中的type依旧为ClusterIP(或者不定义type默认就是这个),通过命令kubectl get service可以看到2.1章节的Service会有cluster-ip,比如10.128.204.105,而Headless Service的cluster-ip则为None

针对这个设计,我们的my-app项目在连接mongoDB的时候,可以依旧使用Service类型为ClusterIP并且有IP地址的Service,这样可以做到负载均衡。而与此同时,还会创建Headless Service,用来给写操作或是新Workder Pod创建的时候连接用的。

3. Service类型:NodePort

如同上述提到的,ClusterIP类型的Service又叫内部Service,原因是只能在内部访问。

而NodePort Service的架构如下: NodePort

而这里的172.90.1.2则为Kubernetes Worker Node IP。
NodePort范围为:30000-32767。

通过命令kubectl get service查看可以看到Type为NodePort, cluster-ip为10.128.8.4,port(s)为3200:30008/TCP。

一般在生产环境不建议这么做,比如有安全的风险,或者是在不同的节点上有多份Service的时候,就比较麻烦。
通常情况下NodePort可作为方便测试的时候使用。

4. Service类型:LoadBalancer

定义的时候将type设为LoadBalancer,ports里依然有三个类型的port,即:port, targetPort, nodePort

在我们创建LoadBalancer Service的时候,会自动的生成上述的NodePort以及ClusterIP相关的内容。只是这时候的NodePort并不是直接对集群外部可见,而是只对LoadBalencer可见。

LoadBalancer Service是NodePort Service的扩展,它弥补了NodePort Service作为集群中一个固定的Node对外暴露的缺点。而是可以将部署在集群中不同的Node间的Service作负载均衡,并对外暴露。

下图是service的列表: image.png

LoadBalancer架构图:
图来自网上:https://www.densify.com/kubernetes-autoscaling/kubernetes-service-load-balancer

image.png

可以看到不同于NodePort单个节点的对外暴露,LoadBalancer可以对多个Node进行转发并做到负载均衡。


参考:
https://www.youtube.com/watch?v=X48VuDVv0do

相关文章

网友评论

      本文标题:【k8s学习】Kubernetes Service介绍

      本文链接:https://www.haomeiwen.com/subject/fijuvrtx.html