主题
第6章 后端发现机制:Endpoints 与 EndpointSlice
Service 只是声明了“我想要把流量发给哪些 Pod”,真正记录“具体发给谁”的是 Endpoints 和 EndpointSlice。本章深入讲解这个发现机制。
6.1 为什么需要 Endpoints
Service 的 selector 定义了选择条件,但 Kubernetes 需要有一个地方记录当前匹配了哪些 Pod、IP 和端口是什么。这就是 Endpoints/EndpointSlice 的作用。
text
Service (意图)
│
▼
Endpoints/EndpointSlice (当前状态)
│
▼
Pod IP:targetPort (真实后端)6.2 Endpoints(旧机制)
当 Service 定义了 selector,Kubernetes 控制平面会自动创建同名的 Endpoints 对象,记录所有匹配 Pod 的 IP:targetPort。
YAML 示例
yaml
apiVersion: v1
kind: Endpoints
metadata:
name: web-service
subsets:
- addresses:
- ip: 10.244.1.10
- ip: 10.244.1.11
ports:
- port: 8080查看命令
bash
kubectl get endpoints <svc-name>6.3 EndpointSlice(推荐)
Endpoints 在大规模集群中存在性能和可扩展性问题(单个对象过大)。Kubernetes 1.21+ 默认使用 EndpointSlice:
- 将后端端点拆分为多个 Slice,每个最多 100 个端点。
- 支持更丰富的元数据(拓扑信息、条件状态等)。
- 更高效的增量更新,降低网络和控制平面压力。
YAML 示例
yaml
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: web-service-abc12
labels:
kubernetes.io/service-name: web-service
addressType: IPv4
ports:
- name: http
protocol: TCP
port: 8080
endpoints:
- addresses:
- 10.244.1.10
conditions:
ready: true
nodeName: node-1
zone: cn-north-1a关键字段
| 字段 | 含义 |
|---|---|
addressType | IPv4 / IPv6 / FQDN |
ports[].port | 后端端口,即 targetPort |
endpoints[].addresses | Pod IP 列表 |
endpoints[].conditions.ready | 是否就绪 |
endpoints[].nodeName | Pod 所在节点 |
endpoints[].zone | 可用区信息 |
查看命令
bash
kubectl get endpointslices -l kubernetes.io/service-name=<svc-name>6.4 Endpoints 与 EndpointSlice 的关系
text
Service
│
├── Endpoints (v1,旧版,单个对象)
│
└── EndpointSlice (discovery.k8s.io/v1,新版,分片)
├── web-service-abc12
├── web-service-def34
└── ...在 Kubernetes 1.21+ 中,EndpointSlice 是默认机制,Endpoints 仍然保留以兼容旧系统。
6.5 无 Selector 的 Service 如何手动关联后端
如果 Service 没有 selector,需要手动创建 Endpoints/EndpointSlice,用于指向集群外部服务或自定义后端。
场景:访问集群外部的 MySQL
yaml
apiVersion: v1
kind: Service
metadata:
name: external-mysql
spec:
type: ClusterIP
ports:
- port: 3306
---
apiVersion: v1
kind: Endpoints
metadata:
name: external-mysql
subsets:
- addresses:
- ip: 192.168.1.100
ports:
- port: 3306集群内应用就可以像访问内部服务一样访问外部 MySQL:
bash
mysql -h external-mysql -P 33066.6 readinessProbe 决定端点是否加入
只有满足以下条件的 Pod 才会被加入 Endpoints/EndpointSlice:
- Pod 的 IP 可达。
- Pod 的标签匹配 Service selector。
- Readiness Probe 通过(如果配置了)。
- Pod 不处于 Terminating 状态。
因此,生产服务务必配置 readinessProbe,否则未就绪的 Pod 会收到流量。
yaml
spec:
containers:
- name: app
image: my-app:1.0
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 56.7 本章小结
- Endpoints/EndpointSlice 是 Service 与 Pod 之间的“桥梁”。
- EndpointSlice 是推荐机制,支持分片和更丰富的拓扑信息。
- 无 Selector 的 Service 需要手动创建 Endpoints/EndpointSlice。
- readinessProbe 决定了 Pod 是否能接收流量。
本章练习
- 创建一个 Service 和 Deployment,观察自动生成的 Endpoints 和 EndpointSlice。
- 为一个 Pod 配置失败的 readinessProbe,观察它是否从 Endpoints 中移除。
- 创建一个无 Selector 的 Service,手动创建 Endpoints 指向一个外部 IP,验证集群内能否访问。