K8S Service相关概念

基本概念

K8S Service是K8S实现微服务架构最重要的组件之一,主要作用:1)为Pod提供稳定的访问地址(域名或IP),2)实现负责均衡,3)自动屏蔽后端Endpoints的变化。

假设我们开发了一个用户认证和授权的功能,这个功能以Deployment的形式来部署,replicas是5,即有5个pod可以同时提供认证和授权的功能。如果没有Service,客户端在使用此功能的时候,需要知道这5个Pod的IP地址,并访问某一个IP地址。这里带来了很多问题,1)客户端需要维护这5个IP地址,并选择某一个IP地址,增加了客户端的复杂性。2)如果客户端的IP地址发生变化,客户端并不会自动感知,很难及时通知到客户端。使用K8S的Service就能完美解决此问题。

由于Service的域名或IP地址不会发生变化,所以对客户端来说其看到的服务域名是不变的,即便Service对应的Endpoints发生了改变。一个Service的后端有多个Endpoints,所以Service在选择某个Endpoint的时候会通过LB的方式来进行(通过kube-proxy组件来实现LB,具体基于iptables或ipvs)。K8S的Service降低了普通微服务架构中服务注册和发现的开销,很轻量级的实现了微服务架构中对服务的管理。

重要配置

Service中最重要的配置是ports和selector,其中ports中定义了Service本身的端口和后端Pod的端口,selector定义了选择哪些Pod来作为该Service的Endpoints。K8S的Service控制器会持续监控后端Pod列表的变化,如果发生改变,则其会实时更新Endpoints列表。

负载均衡机制

从Service的IP到后端Pod的选择是由运行在每个Node上的kube-proxy来实现的。可以选择iptables模式或者ipvs模式,通过启动参数--proxy-mode来设置。

iptables:基于Linux kernel的iptables规则来实现路由规则的定义和数据包的转发,关于iptables可以参考:
https://www.cnblogs.com/kalixcn/p/17323391.html
https://zhuanlan.zhihu.com/p/633712699

ipvs:IPVS是Linux kernel内置的层四的LB,比iptables的性能高,且支持比较多的LB算法,如rr,lc,dh,sh等。

会话保持机制

通过设置sessionAffinity,可以实现基于客户端IP的会话保持机制,即首次将某个客户端来源IP发起的请求转发到后端的某个Pod上,之后相同的IP客户端的请求也转发到此Pod上。

多端口设置

一个Service可以绑定多个端口,例如区分管理端口和业务端口,只需要后端的Pod能对不同的端口提供相应的服务即可。不同的端口还可以具备不同的协议,如TCP,UDP等。

如何将外部服务定义为Service

两种办法,1)定义Endpoints。通过这种方式,service没有selectors配置,即不需要选择后端的Pod,但是可以额外定义一个Endpoints资源,在里面手动指定外部服务的IP地址,service就能选择这些IP地址。2)将Service的类型定义为ExternalName。如果Service的type是ExternalName,那么需要指定一个属性externalName,该属性可以设置外部服务的域名。

服务类型

ClusterIP:K8S默认的类型,会为K8S分配一个仅在集群内部使用的IP地址。

NodePort:K8S会将Service的端口映射到每个Node的一个端口上,这样集群外部的Client可以通过任何一个Node来访问此服务。NodePort类型下,可以手动通过nodePort属性指定一个外部的端口,如果没有指定,则K8S会自动分配一个30000-32767范围内的端口。还可以指定通过哪些网卡来对外提供服务。

LoadBalancer:将此服务映射到一个已经存在的LB上,这样在集群外部也能访问Service,且已经存在的LB可以自动选择某个node。通常在Public Cloud上使用,也可以基于MetalLB在非公有云上使用。

ExternalName:将外部的服务映射到K8S里面。

将服务暴露到集群外部的方法

NodePort:参见上面的说明。

LoadBalancer:参见上面的说明。

Ingress:使用Ingress资源,在L7上进行路由。

服务发现机制

环境变量:K8S将集群中所有有效的服务,通过环境变量的方式注入到每个Pod中,在Pod中就可以通过环境变量来获取服务的IP地址,端口等。

DNS:推荐的方式。在Pod中直接使用服务的DNS域名。

Headless Service

客户端如果不想使用K8S提供的服务的LB机制,或者需要自己选择某个后端Pod,那么此时可以使用Headless Service。如果访问服务域名,返回的将是后端Pod列表(如果服务设置了Label Selector),而不是服务的Cluster IP。

端点分片和服务拓扑

端点分片:如果K8S集群的Node很多,且服务关联的Pod也很多的时候,在更新服务的Endpoints列表时将带来很大开销,为此K8S提供了端点分片的功能(EndpointSlice),即不是在所有的Node上更新Endpoints,而是在需要的Node上更新。例如Deployment的滚动升级,可以只更新部分Node,等在这些Node上的测试完成后,再更新所有Node。这需要通过创建EndpointSlice来实现。

服务拓扑

一个服务的Endpoint可以包含分布在不同地理位置的Pod,不同的请求也可能来自不同的地理位置。可以设置规则,让服务根据这些规则来返回Endpoint,只让满足规则的Endpoints来相应客户端请求。这些规则通过topologyKeys来指定,如按照hostname,zone,region等。

Ingress七层路由机制

目的是可以通过七层路由机制来指定不同的URL进入到不同的Service。例如:对http://www.mysite.com/api的访问会进入到提供API的服务,对http://www.mysite.com/doc的访问会进入到提供doc的服务。

相关推荐
wuxingge8 小时前
k8s1.30.0高可用集群部署
云原生·容器·kubernetes
志凌海纳SmartX9 小时前
趋势洞察|AI 能否带动裸金属 K8s 强势崛起?
云原生·容器·kubernetes
锅总9 小时前
nacos与k8s service健康检查详解
云原生·容器·kubernetes
BUG弄潮儿9 小时前
k8s 集群安装
云原生·容器·kubernetes
颜淡慕潇11 小时前
【K8S系列】kubectl describe pod显示ImagePullBackOff,如何进一步排查?
后端·云原生·容器·kubernetes
Linux运维日记11 小时前
k8s1.31版本最新版本集群使用容器镜像仓库Harbor
linux·docker·云原生·容器·kubernetes
AI_小站13 小时前
RAG 示例:使用 langchain、Redis、llama.cpp 构建一个 kubernetes 知识库问答
人工智能·程序人生·langchain·kubernetes·llama·知识库·rag
长囧鹿17 小时前
云原生之k8s服务管理
云原生·容器·kubernetes
怡雪~18 小时前
centos7.9搭建k8s集群
云原生·容器·kubernetes
我要用代码向我喜欢的女孩表白21 小时前
k8s入门(不教部署,部署跟着文档来就行了)
云原生·容器·kubernetes