00000234
1. 什么是 EndpointSlice?
EndpointSlice是 Kubernetes 1.16+ 引入的 服务发现资源,用于替代传统的 Endpoints资源,解决其在 大规模集群 中面临的性能问题。
Endpoints单资源 1000 个端点的限制。2. 与 Endpoints(ep)的对比
| 维度 | Endpoints(ep) | EndpointSlice |
|---|---|---|
设计理念 |
单资源存储一个 Service 的所有端点 |
分片存储,一个 Service 可对应多个 EndpointSlice |
最大端点数 |
约 1000 个(受 etcd 键值大小限制) |
理论无上限,推荐每片 100-500 个端点 |
网络协议 |
仅支持 TCP/UDP |
支持 TCP/UDP/SCTP,可扩展更多协议 |
元数据 |
仅包含 IP、Port、就绪状态 |
包含拓扑信息(区域/可用区)、节点名、主机名、拓扑键等 |
性能 |
大规模集群中 API Server 压力大,同步慢 |
分片减少单次更新数据量,提升同步效率 |
控制器 |
|
|
某电商平台 Kubernetes 集群规模:
Endpoints时,API Server 频繁出现 etcdserver: request is too large错误,kube-proxy 同步端点信息延迟高达 30s,导致服务访问超时。# 1. 确认集群版本与特性门控
# 确保 Kubernetes 版本 ≥ 1.16,且 EndpointSlice功能已启用(1.16+ 默认启用)。
kubectl version --short
# 检查 EndpointSlice 资源是否存在
kubectl get endpointslice --all-namespaces
# 2.验证 EndpointSlice 自动创建
# 创建测试 Service 和 Deployment,观察是否自动生成 EndpointSlice。
# product-service.yaml
apiVersion: v1
kind: Service
metadata:
name: product-service
namespace: ecommerce
spec:
selector:
app: product-api
ports:
- port: 80
targetPort: 80 #端口可更改
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: product-api
namespace: ecommerce
spec:
replicas: 2000 # 大规模副本数,测试建议小一点
selector:
matchLabels:
app: product-api
template:
metadata:
labels:
app: product-api
spec:
containers:
- name: product-api
image: harbor.wyasw.com/test/nginx:v1
ports:
- containerPort: 80 #服务端口
readinessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 5
periodSeconds: 10
# 部署
kubectl create ns ecommerce
kubectl apply -f product-service.yaml
kubectl get endpointslice -n ecommerce -l kubernetes.io/service-name=product-service
#预期输出:
NAME ADDRESSTYPE PORTS ENDPOINTS AGE
product-service-sn9g6 IPv4 80 10.100.1.62,10.100.2.74,10.100.1.56 + 28 more... 107s
可以看到,2000 个 Pod 端点被自动分片到多个 EndpointSlice 中。
# 3. 调整分片策略(可选)
# 默认每片 100 个端点,可通过 max-endpoints-per-slice调整(需 API Server 启用 EndpointSlice特性门控)。
# 通过 API Server 启动参数调整(全局)
# --feature-gates=EndpointSlice=true
# --max-endpoints-per-slice=500 # 调整为每片 500 个端点
# 4. 验证性能提升
API Server 负载:通过 Prometheus 监控 apiserver_request_duration_seconds和 etcd_request_duration_seconds,观察端点相关请求的延迟和错误率是否下降。
kube-proxy 同步延迟:通过 kubectl logs kube-proxy-xxx -n kube-system查看同步日志,延迟应从 30s 降至秒级。
服务访问延迟:通过监控工具(如 SkyWalking、Prometheus)观察服务间调用的 P99 延迟是否降低。
# 1.创建svc和EndpointSlice
[root@k8s-master-01 ~]# vim external-db-mysql.yaml
[root@k8s-master-01 ~]# cat external-db-mysql.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql-external
namespace: default
labels:
app: mysql-external
spec:
ports:
- name: mysql
port: 3306 # Service 端口
protocol: TCP
targetPort: 53306 # 外部 MySQL 端口(文档化用,EndpointSlice 中需一致)
# 不指定 selector,手动关联 EndpointSlice
---
apiVersion: discovery.k8s.io/v1 # EndpointSlice 的 API 组
kind: EndpointSlice
metadata:
name: mysql-external-abcde # 名称自定义(建议包含 Service 名前缀)
namespace: default
labels:
# 关键:关联 Service(与 Service 同名或通过 selector 匹配)
kubernetes.io/service-name: mysql-external
app: mysql-external
addressType: IPv4 # 端点地址类型(IPv4/IPv6)
ports:
- name: mysql # 端口名称(需与 Service 的 port.name 一致)
port: 53306 # 外部 MySQL 端口(必须与 Service 的 targetPort 一致)
protocol: TCP
endpoints:
# 端点 1:主库(写实例)
- addresses:
- "192.168.1.250" # 外部 MySQL 主库 IP(或域名解析后的 IP)
conditions:
ready: true # 标记为就绪(kube-proxy 会转发流量)
hostname: "mysql-master" # 外部实例主机名(可选)
zone: "cn-hangzhou-a" # 拓扑信息(可用区,用于拓扑感知路由)
nodeName: "external-mysql-master" # 自定义节点名(标识外部资源,可选)
# 端点 2:只读实例 1
- addresses:
- "192.168.1.251"
conditions:
ready: true
hostname: "mysql-slave"
zone: "cn-hangzhou-b"
nodeName: "external-mysql-readonly-1"
# 2. 部署
[root@k8s-master-01 ~]# kubectl apply -f external-db-mysql.yaml
# 3. 验证
[root@k8s-master-01 ~]# kubectl get EndpointSlice mysql-external-abcde
NAME ADDRESSTYPE PORTS ENDPOINTS AGE
mysql-external-abcde IPv4 53306 192.168.1.250,192.168.1.251 52s
[root@k8s-master-01 ~]# kubectl get -f external-db-mysql.yaml
[root@k8s-master-01 ~]# kubectl describe -f external-db-mysql.yaml