K8S中service的分类以及各种使⽤场景详解
前⾔
前⾯两个章节讲解了K8S的总体⼊门准备以及全局配置管理的相关内容,正常来说接下来应该将将存储或者组件,但是由于那两部分内容过多且相对偏重细节,所以这⼀篇先把K8S中的Service先讲解下,帮助⼤家先理清K8S的整体架构,后续再讲解细节内容的时候可以快速上⼿,便于理解。
正⽂
Service是什么?
在说明Service是什么之前先了解下Service的使⽤场景:
当客户端想要访问K8S集中的pod时,需要知道pod的ip以及端⼝,那K8S中如何在不知道pod的地址信息的情况下进⾏pod服务的快速连接?
若某⼀node上的pod发⽣故障,K8S最⼤的特点就是能够给感知和重启该pod,但是pod重启后ip会发⽣变化,那么客户端如何感知并保持对pod的访问?
如果多个pod组合在⼀起形成pod组,如何在被访问时达到负载均衡的效果?
针对上⾯三种需求,K8S提出了Service的概念,意在解决上述三个问题和场景,下⾯俩看看Service的定义:
Kubernetes Service是为了管理具有相同功能的⼀组Pod⽽定义的⼀种对象,Service具体的作⽤和场景如下:
通过Pod的Label Selector访问Pod组。
Service的IP保持不变(Headless Servcie除外,下⾯会单独讲),保证了访问接⼝的稳定性,屏蔽了Pod的IP地址变化带来的影响,进⽽实现解耦合。虽然这样,还是建议使⽤ServiceName进⾏访问。
Service通过kube-proxy借助iptables/ipvs提供负载均衡的能⼒,实现反向代理,将请求转发到合适的Pod上。
Service的⼯作机制
⾸先根据我对整个Service⼯作流程的理解,画了这张图,下⾯就围绕这张图进⾏展开来说明下:
1. master上的kube-apiserver会处理service的创建,以及Service与通过label匹配与Pod绑定⽽产⽣的en
dpoints对象,并将这些元
数据内容存储到etcd中。
2. node上的kube-proxy通过实时监听kube-apiserver上service以及endpoints的变化情况来感知相关事件并更新本地的service和
endpoint的映射关系;同时node上的kubedns/coredns服务也会同时将service的域名信息与IP的对应关系存储起来供dns解析之⽤。
3. kube-proxy将从apiserver获取到的service和endpoint的映射关系保存在本地的iptables/ipvs中供后续查询使⽤
4. client发起对服务的访问,⾸先kubedns/coredns将服务名称解析成⼀个虚拟IP(ClusterIP)
5. 然后使⽤这个IP去iptables/ipvs中去service和endpoint的映射关系
6. 到映射关系后,通过iptables/ipvs的负载均衡算法(典型也是最简单的就是roundrobin算法)匹配到⼀个合适的Pod进⾏访问即
可。
下⾯看⼀个例⼦:
上图就是⼀个service的详细信息,先对照上⾯的流程⼀下对应关系:
service和endpoint的映射关系:everisk-receiver(10.233.3.127)=> 10.233.68.41:6280,10.233.68.43:6280,这些数据会存储到iptables/ipvs中
service的域名信息与IP的对应关系:everisk-receiver => 10.233.3.127,这些数据会存储到kubedns/coredns中
负载均衡反向代理:10.233.68.41:6280,10.233.68.43:6280这两个Pod就是需要进⾏负载均衡以及反向代理的两个
Pod,iptables/ipvs会根据⾃⾝的负载均衡算法来完成此过程
整体的数据访问流程即everisk-receiver => 10.233.3.127 => 10.233.68.41:6280
Service的类型
K8S中Service分为四类,分别是ClusterIP,NodePort,LoadBalancer以及ExternalName。下⾯⼀张图描述了他们之间的关系以及服务类型:
其中绿⾊的代表从外向内的访问模式;蓝⾊的代表从内向外的访问模式,黄⾊代表集内部的访问模式。可以看到,除了ExternalName类型之外,其余三种类型都是逐层封装⽽来的。下⾯就分类讲⼀讲这四种类型:
ClusterIP
这是K8S默认的服务类型,只能在K8S中进⾏服务通信。在ClientIP中,K8S会在Service创建完毕后提供⼀个内部IP作为ClientIP属
性,K8S内部服务可以通过ClientIP或者ServiceName来访问该服务。
创建该类型Service的yaml例⼦如下:
apiVersion: v1
kind: Service
metadata:nodeselector
name: service-clusterip
spec:
ports:
- port: 3000
protocol: TCP
targetPort: 443
# clusterIP: 10.233.3.127    ##可配可不配,不配的话系统会分配⼀个随机的IP并保持不变
selector:
app: pod-clusterip
type: ClusterIP        ##type可以不配,不配的话默认就是ClusterIP类型
NodePort
NodePort则是Service type是Nodeport的实现,NodePort通过配置nodePort属性,外部⽤户可以通过NodeIP:NodePort的⽅式单独访问每个Node上的服务。
创建该类型Service的yaml例⼦如下:
apiVersion: v1
kind: Service
metadata:
name: service-nodeport
spec:
ports:
- port: 3000
protocol: TCP
targetPort: 443
nodePort: 30080    ##可配可不配,不配的话系统会分配⼀个随机的端⼝并保持不变
selector:
app: pod-nodeport
type: NodePort
LoadBalancer
LoadBalancer类型的service 是可以实现集外部访问服务的另外⼀种解决⽅案。不过并不是所有的k8s集都会⽀持,⼤多是在公有云托管集中会⽀持该类型。负载均衡器是异步创建的,关于被提供的负载均衡器的信息将会通过Service的status.loadBalancer字段被发布出去。
另外据说LoadBalancer需要⼀些本地资源如F5的⽀持,⽽且据说要额外收费,作者不是很了解这⾥不做过多介绍了。
创建该类型Service的yaml例⼦如下:
apiVersion: v1
kind: Service
metadata:
name: service-loadbalancer
spec:
ports:
- port: 3000
protocol: TCP
targetPort: 443
nodePort: 30080
selector:
run: pod-loadbalancer
type: LoadBalancer
ExternalName
Service的ExternalName⽅式实现,即设置Service的type为ExternalName。这样做的好处就是内部服务访问外部服务的时候是通过别名来访问的,屏蔽了外部服务的真实信息,外部服务对内部服务透明,外部服务的修改基本上不会影响到内部服务的访问,做到了内部服务和外部服务解耦合。
创建该类型Service的yaml例⼦如下:
kind: Service
apiVersion: v1
metadata:
name: service-externalname
spec:
ports:
- port: 3000
protocol: TCP
targetPort: 443
type: ExternalName
externalName: remote.server.url
Headless Service
上⾯我们讲解了service的使⽤⽅法和实现逻辑,主要就是代理⼀组pod容器提供负载均衡以及反向代理服务。但是有时候我们不需要这种负载均衡,⽐如下⾯的两个场景:
K8S部署某个kafka集,此时就不需要service来负载均衡,客户端需要的是⼀组pod所有ip的列表。
客户端⾃⼰处理负载均衡的逻辑,⽐如K8S部署两个mysql,客户端⾃⼰处理负载请求,或者根本不处理这种负载,就要两套mysql然后⼿动控制读写请求。
基于上⾯的两个场景,K8S提供了headless serivce功能,字⾯意思是⽆头service,其实就是该service不显式的对外提供IP。
创建该类型Service的yaml例⼦如下:
apiVersion: v1
kind: Service
metadata:
name: service-headless
spec:
ports:
- port: 3000
protocol: TCP
targetPort: 443
nodePort: 30080
clusterIP: None        ##如此配置即开启了headless serivce
selector:
app: pod-headless
type: NodePort
最后说⼀嘴,headless service⼀般结合StatefulSet来部署有状态的应⽤,⽐如⼤数据组件或者nosql数据库等,这种分布式的系统需要headless service来获取所有节点ip的列表供业务场景使⽤。
总结
上⾯讲述了K8S Service的使⽤⽅法以及部分原理,希望能帮助⼤家掌握Service的相关知识。
⽽Service作为外部系统与K8S解耦合的关键组件,对外能够简化外系统调⽤K8S服务的复杂度,屏蔽K8S内部的实现细节;对内提供K8S 内部的复杂均衡以及反向代理,是K8S的核⼼内容,需要重点且优先掌握。
另外,笔者长期关注⼤数据通⽤技术,通⽤原理以及NOSQL数据库的技术架构以及使⽤。如果想⼀起⼊门学习K8S的⼩伙伴,欢迎⼤家多多点赞和分享转发,也许你的朋友也喜欢。
最后挂个⼆维码,的⽂章是最新的,CSDN的会有些滞后,想追更的朋友欢迎⼤家关注,谢谢⼤家⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。