Kubernetes Service
Service、EndpointSlice、CoreDNS、服务发现和集群内访问链路说明。
Kubernetes Service
Service 为一组 Pod 提供稳定访问入口。Pod IP 会随重建变化,Service 通过 selector 匹配 Pod,并通过 EndpointSlice 维护后端地址。
Service 类型
| 类型 | 说明 |
|---|---|
ClusterIP | 集群内访问,默认类型 |
NodePort | 在每个节点暴露端口 |
LoadBalancer | 由云厂商或负载均衡控制器分配外部入口 |
ExternalName | 返回外部 DNS 名称 |
| Headless Service | clusterIP: None,直接返回后端 Pod 地址 |
ClusterIP
# API 版本。Service 是核心资源,使用 v1。
apiVersion: v1
# 资源类型。这里表示创建 Service。
kind: Service
metadata:
# Service 名称,也是集群内 DNS 名称的一部分。
name: order-api
spec:
# Service 类型。ClusterIP 表示只在集群内访问。
type: ClusterIP
# 通过标签选择后端 Pod。
selector:
# 匹配 label app=order-api 的 Pod。
app: order-api
# Service 暴露的端口列表。
ports:
# 端口名称,便于区分多端口 Service。
- name: http
# Service 端口,客户端访问这个端口。
port: 80
# 后端 Pod 容器监听端口。
targetPort: 8080
访问方式:
curl http://order-api.default.svc.cluster.local
NodePort
# API 版本。Service 是核心资源,使用 v1。
apiVersion: v1
# 资源类型。这里表示创建 Service。
kind: Service
metadata:
# Service 名称。
name: order-api-nodeport
spec:
# NodePort 会在每个节点暴露一个端口。
type: NodePort
# 通过标签选择后端 Pod。
selector:
app: order-api
ports:
# Service 集群内端口。
- port: 80
# 后端 Pod 容器监听端口。
targetPort: 8080
# 节点上暴露的端口,默认范围通常是 30000-32767。
nodePort: 30080
访问:
curl http://<node-ip>:30080
NodePort 适合测试或内部临时暴露,生产入口通常使用 LoadBalancer、Ingress 或 Gateway。
Headless Service
# API 版本。Service 是核心资源,使用 v1。
apiVersion: v1
# 资源类型。这里表示创建 Service。
kind: Service
metadata:
# Headless Service 名称。
name: redis-headless
spec:
# None 表示不分配 ClusterIP,DNS 直接返回后端 Pod 地址。
clusterIP: None
# 通过标签选择后端 Pod。
selector:
app: redis
ports:
# Service 端口。
- port: 6379
# 后端 Pod 容器监听端口。
targetPort: 6379
常用于 StatefulSet,让客户端直接发现每个 Pod。
EndpointSlice
查看 Service 后端:
kubectl get svc order-api -n default -o wide
kubectl get endpointslice -n default -l kubernetes.io/service-name=order-api
kubectl describe endpointslice -n default -l kubernetes.io/service-name=order-api
如果 EndpointSlice 为空,通常说明:
- Service selector 和 Pod labels 不匹配。
- Pod 未 Ready。
- Pod 不在同一命名空间。
DNS
常见 DNS 名称:
<service-name>
<service-name>.<namespace>
<service-name>.<namespace>.svc
<service-name>.<namespace>.svc.cluster.local
测试 DNS:
kubectl run dns-test --image=busybox:1.36 -it --rm -- nslookup order-api.default.svc.cluster.local
访问链路
集群内访问通常是:
client pod -> service dns -> clusterIP -> kube-proxy / dataplane -> endpoint pod
排查时按顺序确认:
- DNS 是否解析。
- Service 是否存在。
- EndpointSlice 是否有后端。
- 后端 Pod 是否 Ready。
- targetPort 是否和容器监听端口一致。
- NetworkPolicy、CNI、防火墙是否拦截。
常见排查命令
kubectl get svc order-api -n default -o yaml
kubectl get pod -n default -l app=order-api -o wide
kubectl get endpointslice -n default -l kubernetes.io/service-name=order-api
kubectl describe svc order-api -n default
进入调试容器:
kubectl run netshoot --image=nicolaka/netshoot -it --rm -- bash
在调试容器中执行:
dig order-api.default.svc.cluster.local
curl -v http://order-api.default.svc.cluster.local
curl -v http://<pod-ip>:8080
常见问题
| 现象 | 排查方向 |
|---|---|
| DNS 解析失败 | 检查 CoreDNS、Service 名称和命名空间 |
| Service 有 IP 但不通 | 检查 EndpointSlice、Pod Ready、targetPort |
| NodePort 不通 | 检查节点防火墙、安全组、kube-proxy |
| 访问偶发失败 | 检查后端 Pod 健康、连接池、滚动发布窗口 |