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 是一个非常有用的排查手段。


原始标题:Demystifying Endpoints in Kubernetes