文章背景图

Kubernetes Service 详解:ClusterIP、NodePort、LoadBalancer 与服务发现

2026-07-25
3
-
- 分钟

Pod 是动态的:重建后 IP 可能变化,副本数量也会随扩缩容调整。Service 为一组 Pod 提供稳定访问入口,让客户端不需要跟踪每个 Pod 的地址。

一、Service 如何找到 Pod

大多数 Service 通过 selector 匹配 Pod 标签:

apiVersion: v1

kind: Service

metadata:

name: web

spec:

selector:

app: web

ports:

- name: http

port: 80

targetPort: 8080

如果 Pod 带有 app=web 标签,控制平面会为 Service 维护相应的 EndpointSlice。数据面实现再把访问 Service 的流量转发给可用后端。

检查关系时,不要只看 Service:

kubectl get service web -o yaml

kubectl get pod -l app=web --show-labels

kubectl get endpointslice \

-l kubernetes.io/service-name=web

Service 有 ClusterIP 但没有 EndpointSlice,通常意味着 selector 没有匹配到 Ready Pod,或者端口配置不正确。

二、port、targetPort 与 nodePort

port 是客户端访问 Service 时使用的端口。

targetPort 是后端 Pod 实际接收流量的端口,可以使用数字,也可以引用容器端口名称。

nodePort 只用于 NodePort 或部分 LoadBalancer 实现,是节点上对外开放的端口。

建议给容器端口命名,并让 targetPort 引用名称。这样应用容器端口变化时,Service 规则更容易维护。

三、ClusterIP

ClusterIP 是默认类型,只在集群网络内提供虚拟 IP 和 DNS 名称:

web.default.svc.cluster.local

同一命名空间通常可以直接使用 web 访问。跨命名空间访问时,可以使用 web.default 或完整域名。

ClusterIP 适合内部微服务、数据库代理和不需要直接暴露公网的应用。

四、NodePort

NodePort 在每个符合条件的节点上开放同一个端口,客户端可以通过 NodeIP:NodePort 访问。

apiVersion: v1

kind: Service

metadata:

name: web-nodeport

spec:

type: NodePort

selector:

app: web

ports:

- port: 80

targetPort: 8080

它适合实验、受控内网入口或作为某些外部负载均衡器的后端,但不适合大量服务直接暴露公网。还应结合节点防火墙、安全组和 source IP 策略评估风险。

五、LoadBalancer

LoadBalancer 请求云厂商或集群内负载均衡实现创建外部入口。能否获得外部地址、如何收费、健康检查和 source IP 如何保留,都取决于具体环境。

kubectl get service web -w

如果 EXTERNAL-IP 长期 Pending,常见原因是集群没有配置负载均衡控制器、云权限不足、配额不足或注解参数错误。

不要继续依赖已经弃用且语义不统一的 spec.loadBalancerIP。固定地址的配置方式应遵循云厂商或负载均衡实现的当前文档。

六、ExternalName

ExternalName 不创建代理或虚拟 IP,而是通过 DNS CNAME 把集群内名称映射到外部域名:

apiVersion: v1

kind: Service

metadata:

name: external-db

spec:

type: ExternalName

externalName: db.example.com

它适合做 DNS 级别的名称抽象,但 HTTP Host 和 TLS 证书可能因为访问域名与真实目标域名不同而出现问题。

七、Headless Service

把 clusterIP 设置为 None,可以创建 Headless Service:

apiVersion: v1

kind: Service

metadata:

name: database

spec:

clusterIP: None

selector:

app: database

ports:

- port: 5432

Headless Service 不提供普通虚拟 IP 负载均衡,DNS 会返回后端端点地址。它常用于 StatefulSet、成员发现或客户端自己选择后端的场景。

八、没有 selector 的 Service

Service 也可以不写 selector,再由管理员或控制器维护 EndpointSlice,把 Kubernetes 服务名映射到集群外或特殊后端。

这种方式需要谨慎:地址生命周期、健康检查和安全责任不再由普通 Pod selector 自动管理。EndpointSlice 中也不能把另一个 Service 的 ClusterIP 当作后端地址。

九、Service 与 Ingress 的关系

Service 主要提供稳定服务发现和四层转发;Ingress 或 Gateway 负责按 HTTP Host、Path 等七层规则把外部流量路由到 Service。

常见链路是:

客户端 → LoadBalancer/Ingress Controller → Service → EndpointSlice → Pod

Ingress 后端配置正确但访问失败时,仍需要继续检查 Service selector、EndpointSlice 和 Pod readiness。

十、常见故障排查

先确认 DNS:

kubectl run -it --rm dns-test \

--image=registry.k8s.io/e2e-test-images/agnhost:2.39 \

--command -- nslookup web.default.svc.cluster.local

检查 Service 和后端:

kubectl describe service web

kubectl get endpointslice \

-l kubernetes.io/service-name=web -o wide

kubectl get pod -l app=web -o wide

再从集群内直接测试 Service:

kubectl run -it --rm curl-test \

--image=curlimages/curl -- \

curl -v http://web:80/

重点检查:

1. selector 与 Pod 标签是否完全匹配。

2. Pod 是否 Ready。

3. targetPort 是否为容器实际监听端口。

4. NetworkPolicy 是否允许流量。

5. kube-proxy 或替代的数据面是否正常。

6. NodePort、LoadBalancer 的安全组和健康检查是否正确。

总结

Service 把动态 Pod 变成稳定服务。ClusterIP 用于集群内部,NodePort 在节点开放端口,LoadBalancer申请外部入口,ExternalName 提供 DNS 映射,Headless Service 则把后端发现交给客户端。排障时,Service、EndpointSlice、Pod 标签和 readiness 必须一起检查。

参考资料:

https://kubernetes.io/docs/concepts/services-networking/service/

https://kubernetes.io/docs/tasks/debug/debug-application/debug-service/

原创

Kubernetes Service 详解:ClusterIP、NodePort、LoadBalancer 与服务发现

本文链接: Kubernetes Service 详解:ClusterIP、NodePort、LoadBalancer 与服务发现

本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

评论交流

文章目录