Kubernetes资源类型之Service

2025-04-16 22:27:00
丁国栋
原创 32
摘要:本文记录Kubernetes中关键的资源类型 Service 相关的笔记。

在Kubernetes中如何确定一个ClusterIP对应的业务或服务是哪一个?

在 Kubernetes 中,ClusterIP 是服务(Service)的内部虚拟 IP 地址,用于集群内通信。要确定一个 ClusterIP 对应的业务或服务,可以通过以下步骤进行排查:


1. 使用 kubectl get services 查看所有服务

列出当前命名空间(或所有命名空间)的服务,直接匹配 ClusterIP

kubectl get svc --all-namespaces -o wide | grep <ClusterIP>

输出示例:

NAMESPACE NAME      TYPE      CLUSTER-IP     EXTERNAL-IP PORT(S)  AGE SELECTOR 
default   nginx-svc ClusterIP 10.96.123.456  <none>      80/TCP   5d  app=nginx

关键字段

 • NAME:服务名称。

 • SELECTOR:服务通过标签选择器关联的 Pod。

 • PORT(S):服务暴露的端口。


2. 检查服务的标签选择器(Selector)

服务的 Selector 决定了它关联哪些 Pod,进而关联到具体的业务应用:

kubectl describe svc <service-name> -n <namespace>

输出中的 Selector 字段会显示匹配的 Pod 标签,例如:

Selector: app=nginx, tier=frontend

3. 通过标签查找关联的 Pod

根据服务的 Selector 查询 Pod:

kubectl get pods -n <namespace> -l app=nginx,tier=frontend

这些 Pod 通常属于同一个业务应用(如 Deployment 或 StatefulSet)。


4. 检查 Pod 的所属控制器

进一步确认 Pod 的归属(如 Deployment、StatefulSet):

kubectl describe pod <pod-name> -n <namespace>

在输出的 OwnerReferencesControlled By 字段中,可以看到上级控制器(如 Deployment/nginx-deploy)。


5. 检查服务的注解(Annotations)

某些服务可能通过注解(Annotations)标注业务信息:

kubectl get svc <service-name> -n <namespace> -o jsonpath='{.metadata.annotations}'

例如:

{"business-unit": "payment-team", "owner": "team-xyz"}

6. 检查命名空间(Namespace)

Kubernetes 的命名空间通常按业务或环境划分(如 prod, dev, payment),命名空间名称可能直接提示业务归属。


7. 查询服务关联的 Endpoints

服务的 ClusterIP 实际代理的 Pod IP 可通过 EndpointsEndpointSlices 查看:

kubectl get endpoints <service-name> -n <namespace>

输出会显示后端 Pod 的 IP 和端口,从而确认实际业务 Pod。


8. 检查 Ingress 或 Gateway 配置

如果服务被外部访问,可能关联了 Ingress:

kubectl get ingress --all-namespaces | grep <service-name>

9. 使用集群监控/日志工具

Prometheus/Grafana:通过服务指标(如 kube_service_info)查询 ClusterIP 关联的指标标签。 • 日志系统:检索服务名称或 ClusterIP 相关的日志(如通过 Fluentd 或 Loki)。


总结流程图

ClusterIP → kubectl get svc → 服务名称/Selector → 关联 Pod → Pod 控制器(Deployment等) → 业务应用

通过以上步骤,可以清晰地追踪 ClusterIP 对应的业务服务及其上下文。

为什么通过get查看Service的yaml时看不到Endpoints,但describe这个Service就可以?

在 Kubernetes 中,kubectl getkubectl describe 命令的输出差异是由它们的默认行为和数据来源不同导致的。具体到 Service 的 Endpoints 是否显示,原因如下:


1. kubectl get svc -o yaml 为什么不显示 Endpoints?

数据来源kubectl get 默认从 Kubernetes API 直接返回资源的 声明式配置(即用户定义的 YAML/JSON 内容)。

 • Service 的 YAML 仅包含用户定义的字段(如 spec.portsselector 等),而 Endpoints 是运行时动态生成的资源,不属于 Service 的声明式配置的一部分。 

• Endpoints 实际上是一个独立的资源(类型为 EndpointsEndpointSlices),由 Kubernetes 控制器根据 Service 的 selector 自动创建和维护。

示例

 kubectl get svc my-service -o yaml

输出中不会包含 Endpoints,但会显示 selector 字段(用于关联 Pod)。


2. kubectl describe svc 为什么能显示 Endpoints?

数据来源kubectl describe 是一个 聚合命令,除了返回 Service 的声明式配置外,还会额外查询关联的运行时状态信息,包括:

 • 自动生成的 Endpoints 资源(列出后端 Pod 的 IP 和端口)。

 • 事件(Events)和其他控制器生成的元数据。

示例

 kubectl describe svc my-service

输出中会包含类似以下字段:

 Selector: app=nginx Endpoints: 10.244.1.2:80,10.244.2.3:80

3. 如何直接查看 Endpoints 资源?

Endpoints 是独立资源,可以通过以下命令显式查询:

# 查看传统 Endpoints 资源 
kubectl get endpoints my-service 
# 或查看更现代的 EndpointSlices(Kubernetes 1.21+ 默认启用)
kubectl get endpointslices

关键点: 

• 如果 Service 没有设置 selector(如手动指定 externalNameclusterIP: None),则不会有自动生成的 Endpoints。

 • 如果 Service 的 selector 不匹配任何 Pod,Endpoints 列表会为空。


4. 为什么这样设计?

职责分离

 • Service 负责定义 如何访问一组 Pod(通过 selector 和端口映射)。

 • Endpoints 负责存储 实际的 Pod 地址(由 Endpoints 控制器动态更新)。

 • 这种分离允许更灵活的扩展(如自定义 Endpoints 逻辑)。

性能优化: Endpoints 可能频繁变化(如 Pod 扩缩容),与 Service 配置分离可以避免频繁写入主资源。


总结

命令/行为 显示 Endpoints? 原因
kubectl get svc -o yaml ❌ 否 只返回用户定义的声明式配置,Endpoints 是独立资源。
kubectl describe svc ✅ 是 聚合了 Service 配置 + 关联的 Endpoints/Events 等运行时信息。
kubectl get endpoints ✅ 是 直接查询 Endpoints 资源。

如果需要通过脚本自动化处理 Endpoints,建议直接查询 EndpointsEndpointSlices 资源,而非依赖 describe

发表评论
博客分类