1. 概述
在 Kubernetes 中,Endpoint 是一个常被忽视的资源对象。很多用户对其了解不多,主要是因为我们通常不需要手动创建或直接操作它。Kubernetes 会在后台自动创建和维护这些对象。
本文将深入讲解 Endpoint 的作用、它是如何工作的,以及它在 Kubernetes 服务发现机制中的关键角色。
2. Pod IP 的临时性问题
在 Kubernetes 中,Pod 是临时性的。这意味着它们可能会随时被终止并重新创建。虽然我们通常使用 Deployment 等控制器来保证 Pod 的数量和可用性,但 Pod 被重建后其 IP 地址会发生变化。
这带来了一个问题:客户端无法依赖 Pod 的 IP 地址进行稳定连接。一旦 Pod 被删除并重建,客户端就会因连接到旧 IP 而断开。
举个例子:
$ kubectl create deploy test --image=nginx --replicas=1
deployment.apps/test created
$ kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-764c85dd84-c6v5t 1/1 Running 0 7s 10.244.1.3 node01 <none> <none>
此时 Pod 的 IP 是 10.244.1.3
。如果我们删除该 Pod:
$ kubectl delete pod test-764c85dd84-c6v5t
pod "test-764c85dd84-c6v5t" deleted
$ kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-764c85dd84-6nrzp 1/1 Running 0 21s 10.244.1.4 node01 <none> <none>
可以看到,新 Pod 的 IP 是 10.244.1.4
。客户端如果还连接在旧 IP 上,就会断开连接。
3. Kubernetes Service 的作用
为了解决 Pod IP 不稳定的问题,Kubernetes 引入了 Service 这个资源对象。Service 提供了一个稳定的 IP 地址,客户端通过这个 IP 来访问服务,而 Service 负责将流量转发到后端的 Pod。
我们可以把 Service 理解为一个负载均衡器:
- 客户端连接的是 Service 的稳定 IP(前端)
- Service 将流量转发给后端 Pod(后端)
Service 会自动追踪后端 Pod 的变化(如 Pod 被删除或新增),并更新其转发目标。它通过 Label 和 Selector 来匹配对应的 Pod。
举个例子,我们创建一个 Service:
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
然后创建一个匹配该 Label 的 Deployment:
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
部署后访问 Service:
$ kubectl apply -f deployment.yaml
deployment.apps/nginx-deployment created
$ kubectl apply -f service.yaml
service/my-service created
$ curl my-service
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
---------------- OUTPUT TRIMMED ------------
✅ 说明 Service 已成功将请求转发给后端 Pod。
4. Endpoint 的工作原理
当 Service 创建后,Kubernetes 会自动创建一个 Endpoint 对象。该对象的作用是记录所有匹配 Service Selector 的 Pod 的 IP 和端口。
换句话说,Endpoint 是 Service 转发流量的目标地址列表。
查看 Service 的 Endpoint:
$ kubectl describe svc my-service
Name: my-service
Namespace: default
Selector: app=my-app
Type: ClusterIP
IP: 10.103.145.6
Port: 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.2:80,10.244.2.2:80,10.244.2.3:80
我们可以确认这些 IP 是否对应实际的 Pod:
$ kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE
nginx-deployment-79557f68d5-9lnlt 1/1 Running 0 95m 10.244.1.2 node01
nginx-deployment-79557f68d5-f6rqt 1/1 Running 0 95m 10.244.2.2 node02
nginx-deployment-79557f68d5-g4s4f 1/1 Running 0 95m 10.244.2.3 node02
✅ 完全一致。现在我们删除其中一个 Pod:
$ kubectl delete pod nginx-deployment-79557f68d5-9lnlt
pod "nginx-deployment-79557f68d5-9lnlt" deleted
$ kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE
nginx-deployment-79557f68d5-76kdl 1/1 Running 0 26s 10.244.1.8 node01
nginx-deployment-79557f68d5-f6rqt 1/1 Running 0 99m 10.244.2.2 node02
nginx-deployment-79557f68d5-g4s4f 1/1 Running 0 99m 10.244.2.3 node02
$ kubectl describe svc my-service
Endpoints: 10.244.1.8:80,10.244.2.2:80,10.244.2.3:80
⚠️ 可以看到,旧 Pod 的 IP 10.244.1.2
被替换为新 Pod 的 10.244.1.8
,Service 自动更新了 Endpoint,保证流量转发正常。
5. 总结
- Pod 的 IP 是临时的,重建后会变化 ❌
- Service 提供稳定 IP,作为客户端访问入口 ✅
- Endpoint 是 Service 与 Pod 之间的桥梁,记录后端 Pod 的 IP 和端口 ✅
- Endpoint 由 Kubernetes 自动维护,无需手动干预 ✅
- 删除或新增 Pod 时,Endpoint 会自动更新 ✅
理解 Endpoint 的工作机制,有助于我们更好地排查服务访问问题,尤其是在服务不通、Pod 重建后无法访问等场景中,查看 Endpoint 是一个非常有用的排查手段。