【K8S】整体原理-K8S中Service对象

Service设计理念

service用于为提供服务的Pod抽象一个稳定的网络访问地址,对用户屏蔽了提供服务Endpoint的变化,核心功能是提供负载均衡和服务发现

首先我们知道,在K8S部署的服务是Pod来承载的,当某个服务有多个副本的时候,当我们的服务在某台机器上的时候,由于某台机器的故障,原有的Pod会迁移到其他的机器上,那其Pod的IP可能也会在迁移完成后被改变,对用户来说,总不能一直调整为其服务的IP地址来去访问服务,所有K8S抽象出来一个Service来为提供服务的Pod们提供一个稳定的IP地址,有了Service,客户端只需要访问Service对象的IP地址或者域名就可以了,不用管后面Pod的IP的变化。

基本原理

  • 业务逻辑

Service包含endpoint,endpoint记录对应Pod的ip;service相当于一组Pod的LB,外部应用访问Service时,Service会通过挑选提供具体服务的Pod,将流量转发到相应的Pod中。

在这里插入图片描述

在业务上来说,我们在定义一个Service的时候呢,会定义一个selector,因为Service是控制对Pod的网络访问,那Service该怎么知道他控制了那些Pod呢, 是通过selector里的label(即上图spec.selector:app=MyAPP中的【app=MyAPP】一部分),Service就会一直维护label所对应Pod的IP,会把他们的PodIP作为Service的Endpoints的列表,当有一个流量请求走到Service之后,Service会在Pod里做出一个挑选,进行负载均衡,然后将流量转发相应的Pod上。

实现层面

Service是借助每个Node上的kube-proxy程序实现其功能,Kube-proxy管理Service的访问入口和Service的Endpoints。Kube-Proxy就是一个网络代理组件,每个节点都会有Kube-Proxy的程序 ,Kube-Proxy会管理Service的访问入口,以及Service的Endpoint

Kube-proxy代理模式有四种:
  • userspace:由kube-proxy实现,效率最低

  • iptables:通过设置iptables实现Service到Endpoint的分支,效率高;但某个Endpoint不可用,会导致响应失败

  • ipvs:通过Linux Kernel的netlink接口设置IPVS规则,效率和吞吐率最高;需要系统开启IPVS模式,且支持较多的负载均衡策略

  • kernelspace:Windows Serever上用的

第一代kube-proxy实现Service功能

在这里插入图片描述

这个时候流量都会经过Kube-Proxy进行路由转发,就会有一个解封包的过程,效率就比较低,他是在用户空间执行的。

第二代kube-proxy实现Service功能

在这里插入图片描述

那到了第二代和第三代就不直接进行流量转发了,而仅是作为一个控制面,去控制IPTables/IPVS (IPVS就是LINUX系统自带的功能)按照路由规则进行流量转发,Kube-Proxy通过增加减少路由规则选项来控制流量转发,这样就效率就比较高。IPTables是第二代,IPVS是第三代。IPTables缺点是只能一条一条加(规定从哪儿来到哪儿去) ,IPVS能实现更复杂的规则(类似正则匹配),IPVS一条规则能达到多条IPTables达到的效果

Service访问方式

1.集群内部

  • ClusterIP: 默认会生成一个虚拟IP,加上端口,便可为Pod提供访问

  • 通过服务名:服务名靠K8S DNS解析,通过namespace.serviceName:Port 即可访问

  • 通过环境变量:在同一个namespace里的Pod启动时,K8S会把Service的一些IP地址,端口,以及简单的一些配置。通过环境变量的方式放到K8S的Pod里面,比如有一个名为MY_SERVICE的service对象,在集群中的某一个Pod里面,环境变量MY_SERVICE_SERVICE_HOST就是他的IP地址,也就是ClusterIP,MY_SERVICE_SERVICE_HOST就是他的端口号。

2.Headless service

在某些应用场景中,若需要人为指定负载均衡器,不适用Service提供的默认负载均衡的功能,或者应用程序希望知道属于同组服务的其他实例。K8S提供了Headless service来实现这个功能,就是通过定义中设置ClusterIP=none,就没有负载均衡功能了。仅通过Label Selector 将后端的Pod列表返回给调用的客户端。

3.向外暴露服务

在这里插入图片描述

NodePort: 每个node都会暴露集群中服务的端口,通过每个node都可以路由到指定Pod。NodePort背后是Kube-Proxy,Kube-Proxy是沟通Service网络,Pod网络和节点网络的桥梁。

LoadBalancer:在NodePort上面加了load balance,load balancer会把外部流量负载均衡到某个节点上的Nodeport上,然后NodePort再转化成ClusterIP,转发到实际的Pod上

Ingress:Ingress(Nginx)会提供根据路由规则直接将客户请求转发到Pod上,就跳过了kube-proxy设置的转发设置,所以提高了 效率。Ingress由Ingress Controller和Ingress对象组成,Ingress对象实质是Controller(Nginx )的路由规则配置(Controller一般由deployment管理),Controller根据Ingress配置实现真正路由转发,。

4.Service的Port

apiVersion: v1
kind: Service
metadata:
  labels:
    name: app1
  name: app1
  namespace: default
spec:
 type: NodePort
 ports:
 - ports: 8080  # Cluster ip 上的端口,相当于<Cluster ip>:port 是根据集群内部客户访问service的入口(端口转化前的端口)
   targetPort: 8080  # targetPort时Pod上的端口,从Port和nodePort上到来的数据最终经过kube-proxy流入到后端Pod的targetPort上进入容器(端口转化后的端口)
   nodePort: 30062 #<nodeIP>:nodePort 是提供给集群外部提供客户访问service的入口。从外网加端口的方式进入这个Service,就可以进入集群把流量转发到 - ports: 8080,然后转发到 targetPort: 8080,最终到容器里
 selector:
   name: app1

常用命令

  • 会话保持机制:保证请求转发到相同的Pod,配置service.spec.sessionAffinity = ClientIP

  • 将外部服务定义为service

两种方式:

1.创建service,但不需要设置Label Selector

2.定义一个与service关联到Endpoint资源

apiVersion: v1
kind: Endpoint
metadata: 
  name: my-service
  subsets:
  - addresses:
    - IP: 1.2.3.4
    ports:
    - port: 80  # Endpoint里的资源就会指向Pod里面的ip(1.2.3.4)和对应的端口(80)

为资源快速创建Pod,即为Pod(po),service(svc),replicationcontroller(rc),deployment(deploy),replicaset(rs)快速创建service

kubectl expose deploy webapp

其他功能

端点分片(Endpoint Slices)

当endpoint(就是Service或者Pod越来越多的时候)增多时,因为kube-proxy会把所有的路由转发规则都记录下来的,那kube-proxy需要维护的负载均衡也会急剧增大,就可以给他划个区域,就是EndpointSlice将Endpoint分片管理,一个分片管理一小片的服务,分片内部只保存分片内的负载分发规则,保证一片片的分片内的服务正常,就避免了所有机器都保存整个集群的负载分发规则,从而降低运维成本。

服务拓扑

,就可以给他划个区域,就是EndpointSlice将Endpoint分片管理,一个分片管理一小片的服务,分片内部只保存分片内的负载分发规则,保证一片片的分片内的服务正常,就避免了所有机器都保存整个集群的负载分发规则,从而降低运维成本。

服务拓扑

比如有北京有片Zone,广东有片Zone,想让调用Zone的时候想让同一个Zone进行一个相应,这样就不会跨城,就会更快。基于Node拓扑的服务路由,可以实现zone内流量的优先转发

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值