layout: blog title: K8S Service categories: [k8s] description: k8s keywords: k8s cnblogsClass: [Markdown],[随笔分类]服务器,[随笔分类]k8s —
Service的使用场景:
当客户端想要访问K8S集群中的pod时,需要知道pod的ip以及端口,那K8S中如何在不知道pod的地址信息的情况下进行pod服务的快速连接?
若某一node上的pod发生故障,K8S最大的特点就是能够给感知和重启该pod,但是pod重启后ip会发生变化,那么客户端如何感知并保持对pod的访问?
如果多个pod组合在一起形成pod组,如何在被访问时达到负载均衡的效果?
Kubernetes Service是为了管理具有相同功能的一组Pod而定义的一种对象,Service具体的作用和场景如下:
通过Pod的Label Selector访问Pod组。
Service的IP保持不变(Headless Servcie除外,下面会单独讲),保证了访问接口的稳定性,屏蔽了Pod的IP地址变化带来的影响,进而实现解耦合。虽然这样,还是建议使用ServiceName进行访问。
Service通过kube-proxy借助iptables/ipvs提供负载均衡的能力,实现反向代理,将请求转发到合适的Pod上。
k8s集群中service的类型包括ClusterIP、NodePort、Headless Service、LoadBalancer、ExternalName;其中Headless Service、ExternalName的使用属于比较特殊但重要:
- 前期部署在集群外,后期需要迁移到k8s集群内的服务;(ExternalName)
- 需要屏蔽外部服务的真实信息,外部服务对内部服务透明,外部服务的修改基本上不会影响到内部服务的访问,做到了内部服务和外部服务解耦合;(ExternalName) ![[Pasted image 20221223154226.png]] 其中绿色的代表从外向内的访问模式;蓝色的代表从内向外的访问模式,黄色代表集群内部的访问模式。可以看到,除了ExternalName类型之外,其余三种类型都是逐层封装而来的。
- 使用Headless Service获取所有Statefulset应用节点的ip列表以供业务场景使用,实际就是应用自身决定连接后端的ip;(Headless Service)
![[Pasted image 20221223153805.png]]
ClusterIp
这是K8S默认的服务类型,只能在K8S中进行服务通信。在ClientIP中,K8S会在Service创建完毕后提供一个内部IP作为ClientIP属性,K8S内部服务可以通过ClientIP或者ServiceName来访问该服务。
NodePort
NodePort的原理在于在 Node上开了一个端口,将向该端口的流量导入到 kube-proxy,然后由 kube-proxy进一步到给对应的 pod。
LoadBalancer
LoadBalancer和NodePort其实是同一种方式。区别在于LoadBalancer比NodePort多了一步,就是可以调用Cloud provider去创建LB来向节点导流
ExternalName
Service的ExternalName方式实现,即设置Service的type为ExternalName。这样做的好处就是内部服务访问外部服务的时候是通过别名来访问的,屏蔽了外部服务的真实信息,外部服务对内部服务透明,外部服务的修改基本上不会影响到内部服务的访问,做到了内部服务和外部服务解耦合。
Headless Service
上面我们讲解了service的使用方法和实现逻辑,主要就是代理一组pod容器提供负载均衡以及反向代理服务。但是有时候我们不需要这种负载均衡,比如下面的两个场景:
- K8S部署某个kafka集群,此时就不需要service来负载均衡,客户端需要的是一组pod所有ip的列表。
- 客户端自己处理负载均衡的逻辑,比如K8S部署两个mysql,客户端自己处理负载请求,或者根本不处理这种负载,就要两套mysql然后手动控制读写请求。 基于上面的两个场景,K8S提供了headless serivce功能,字面意思是无头service,其实就是该service不显式的对外提供IP。 ```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的列表供业务场景使用
question
headless 加pod,serve端存在无法获取地址问题
- 加keepalive参数
长连接,删减pod会感知,增加pod 预估2小时才会刷新