智能
助手
最大化  清空记录 停止  历史记录
翻译选中文本
选中一段文本后进行翻译
名词解释
选中一段文本后进行名词解释
知识图谱生成
通过图谱展示知识信息
登录用户在知识浏览页面可用
答案生成
AI自动回答一个问答功能中的问题
登录用户在问答浏览页面,且问题开放回答中可用
知识摘要
自动为当前知识生成摘要
知识浏览页面可用
知识问答
针对当前知识进行智能问答
知识浏览面可用
2026-01-21 20:49:26 版本 : 6.8.8 EndpointSlice 大规模服务发现案例(替代Endpoints 缩写:ep)
作者: 文艺范儿 于 2026年01月21日 发布在分类 / Docker & K8S / K8S基础 下,并于 2026年01月21日 编辑
 历史版本

备注 修改日期 修改人
创建版本 2026-01-21 20:49:26[当前版本] 文艺范儿

6.8.8 EndpointSlice 大规模服务发现案例(替代Endpoints 缩写:ep)

简介

1. 什么是 EndpointSlice?

EndpointSlice是 Kubernetes 1.16+ 引入的 服务发现资源,用于替代传统的 Endpoints资源,解决其在 大规模集群 中面临的性能问题。

  • 核心作用:存储和管理一个 Service 对应的 后端 Pod 网络端点(IP:Port) 的集合,支持更细粒度的切片、扩展字段和更高的可扩展性。
  • 设计目标
    • 突破 Endpoints单资源 1000 个端点的限制。
    • 减少大规模集群中 API Server 和 kube-proxy 的负载。
    • 提供更丰富的元数据(如拓扑信息、就绪状态、节点信息等)。

2. 与 Endpoints(ep)的对比

维度 Endpoints(ep) EndpointSlice

设计理念

单资源存储一个 Service 的所有端点

分片存储,一个 Service 可对应多个 EndpointSlice

最大端点数

约 1000 个(受 etcd 键值大小限制)

理论无上限,推荐每片 100-500 个端点

网络协议

仅支持 TCP/UDP

支持 TCP/UDP/SCTP,可扩展更多协议

元数据

仅包含 IP、Port、就绪状态

包含拓扑信息(区域/可用区)、节点名、主机名、拓扑键等

性能

大规模集群中 API Server 压力大,同步慢

分片减少单次更新数据量,提升同步效率

控制器

kube-controller-manager内置 Endpoints 控制器

endpointslice-controller独立管理

案例1:大规模服务发现:万级 Pod 电商集群

场景描述

某电商平台 Kubernetes 集群规模:

  • 节点数:500+
  • Pod 总数:50,000+
  • 核心服务:商品服务(Product Service)、订单服务(Order Service),每个服务对应 2000+ Pod 副本(多可用区部署)。
  • 问题:使用传统 Endpoints时,API Server 频繁出现 etcdserver: request is too large错误,kube-proxy 同步端点信息延迟高达 30s,导致服务访问超时。
解决方案:迁移到 EndpointSlice
# 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 延迟是否降低。

案例2:自定义EndpointSlice资源实现K8S集群外部地址映射

# 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
历史版本-目录  [回到顶端]
    文艺知识分享平台 -V 5.2.5 -wcp