K8s-Service端点切片和服务拓扑

背景

Service背后指向了一组Endpoint列表,当集群规范增大时,kube-proxy负载迅速上升,同时Service对Endpoint的CRUD操作成本是上升。

所以在K8s 1.16引入了端点切片(Endpoint Slices)机制,包括一个新的EndpointSlice资源对象和新的EndpointSlice控制器。

在K8s 1.17进入beta阶段,其原理是对Endpoint进行分片管理,实现降低Master和Node之间的网络传输数据量和提供整体性能。

默认:EndpointSlice控制器创建Endpoint为100,需要修改需要设置kube-controller-manager –max- endpoint-per-slice设置,但是最大上限不能超过1000

什么是EndpointSlice

#地址类型 包括 IPV4 IPV6 FQDN
addressType: IPv4
apiVersion: discovery.k8s.io/v1
# endpoint列表
endpoints:
- addresses:
- 10.10.102.96
# Endpoint状态
conditions:
ready: true
nodeName: k8s-master
# Endpoint对应的Pod
targetRef:
kind: Pod
name: zlm-deployment-7c8555f784-ls7lj
namespace: default
metadata:
annotations:
endpoints.kubernetes.io/last-change-trigger-time: "2023-10-18T08:11:45Z"
creationTimestamp: "2023-09-19T07:04:43Z"
generateName: zlm-service-
generation: 5
labels:
endpointslice.kubernetes.io/managed-by: endpointslice-controller.k8s.io
kubernetes.io/service-name: zlm-service
name: zlm-service-qh6td
namespace: default
ownerReferences:
- apiVersion: v1
blockOwnerDeletion: true
controller: true
kind: Service
name: zlm-service
uid: 2b6004f8-9979-4bbd-ab05-062555ebf2cb
resourceVersion: "5655775"
uid: 96d6f129-da8b-49e7-a135-57804f0148b7
ports:
- name: zlm-rtsp
port: 554
protocol: TCP
- name: zlm-port
port: 80
protocol: TCP

数据分布管理机制

K8s控制器提供对EndpointSlice中数据管理

  1. 遍历所有EndpoinceSlice资源,删除不需要的Endpoint,更新匹配的Endpoint
  2. 同时对于已更新的EndpointSlice资源,将需要添加的Endpoint添加
  3. 如果还有新的待添加Endpoint,则尝试将其放入之前未更新的 EndpointSlice中,或者尝试创建新的EndpointSlice并添加

第3步优先考虑创建新的EndpointSlice而不是更新原 EndpointSlice。例如,如果要添加10个新的Endpoint,则当前有两个 EndpointSlice各有5个剩余空间可用于填充,系统也会创建一个新的 EndpointSlice用来填充这10个新Endpoint。换句话说,单个EndpointSlice 的创建优于对多个EndpointSlice的更新

服务拓扑(Service Topology)

服务拓扑机制从Kubernetes 1.17版本开始引入,目前为Alpha阶段, 目标是实现基于Node拓扑的流量路由,例如将发送到某个服务的流量优 先路由到与客户端相同Node的Endpoint上,或者路由到与客户端相同 Zone的那些Node的Endpoint上

在默认情况下,发送到一个Service的流量会被均匀转发到每个后端 Endpoint,但无法根据更复杂的拓扑信息设置复杂的路由策略。服务拓 扑机制的引入就是为了实现基于Node拓扑的服务路由,允许Service创建 者根据来源Node和目标Node的标签来定义流量路由策略

服务拓扑机制需要通过设置kube-apiserver和kube-proxy服务的启动 参数–feature-gates=”ServiceTopology=true,EndpointSlice=true”进行启用 (需要同时启用EndpointSlice功能),然后就可以在Service资源对象上 通过定义topologyKeys字段来控制到Service的流量路由了