3. Service ClusterIP与DNS服务发现验证
从 Pod IP 到稳定服务入口
Deployment 管理的是 Pod 副本,但 Pod 的 IP 会随重建而变化,客户端不能直接依赖 Pod IP。ClusterIP Service 提供一个虚拟 IP 和稳定 DNS 名称,由 kube-proxy 将访问流量分发到后端就绪 Pod。本例部署 3 副本应用,创建 ClusterIP Service,并在集群内用 Service 名称和完整 DNS 域名验证访问与负载均衡。
创建 Deployment 与 ClusterIP Service
先部署一个返回自身主机名的应用,便于观察负载均衡效果。以下 YAML 定义 3 副本 Deployment 和对应 Service。
# web-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: hashicorp/http-echo:0.2.3
args:
- "-text=$(POD_NAME)"
- "-listen=:8080"
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 2
periodSeconds: 3
---
apiVersion: v1
kind: Service
metadata:
name: web-svc
spec:
type: ClusterIP
selector:
app: web
ports:
- port: 80
targetPort: 8080
protocol: TCP
应用并确认资源状态:
kubectl apply -f web-deploy.yaml
kubectl get deploy web -o wide
kubectl get pods -l app=web -o wide
kubectl get svc web-svc
kubectl get endpoints web-svc
预期看到 3 个 Pod 处于 Running 且 Ready,Service 的 ClusterIP 已分配,Endpoints 列出 3 个 Pod IP:8080。若 Endpoints 为空,检查 selector 标签是否与 Pod 标签一致,以及 readinessProbe 是否通过。
集群内 DNS 解析与访问验证
启动一个临时客户端 Pod,在集群内验证短名和 FQDN 解析,并多次请求观察负载均衡。
# 启动测试客户端
kubectl run test-client --image=busybox:1.36 --restart=Never -- sleep 3600
# 等待就绪后进入
kubectl exec -it test-client -- sh
# 在容器内执行:
nslookup web-svc
nslookup web-svc.default.svc.cluster.local
# 短名访问
wget -qO- http://web-svc
# FQDN 访问
wget -qO- http://web-svc.default.svc.cluster.local
# 多次请求观察负载均衡
for i in $(seq 1 10); do wget -qO- http://web-svc; echo; done
DNS 解析应返回 Service 的 ClusterIP。多次请求的响应文本应出现不同的 Pod 名称(如 web-xxxxx-aaa、web-xxxxx-bbb、web-xxxxx-ccc),说明 kube-proxy 在多个后端之间分发流量。若始终返回同一 Pod,可能是会话保持或客户端连接复用导致,可尝试新建连接或使用不同客户端验证。
ClusterIP 只能在集群内部访问。若需从集群外访问,应使用 NodePort、LoadBalancer 或 Ingress。DNS 短名仅在 Pod 所在命名空间内有效,跨命名空间需使用
service.namespace 或 FQDN。验证清单
| 检查项 | 命令 | 预期结果 |
|---|---|---|
| Pod 就绪 | kubectl get pods -l app=web | 3 个 Pod Running,READY 1/1 |
| Service 创建 | kubectl get svc web-svc | ClusterIP 已分配,PORT 80/TCP |
| Endpoints 关联 | kubectl get endpoints web-svc | 列出 3 个 Pod IP:8080 |
| DNS 短名解析 | nslookup web-svc | 返回 ClusterIP |
| DNS FQDN 解析 | nslookup web-svc.default.svc.cluster.local | 返回 ClusterIP |
| HTTP 访问 | wget -qO- http://web-svc | 返回某个 Pod 名称 |
| 负载均衡 | 循环请求 10 次 | 出现多个不同 Pod 名称 |
常见问题排查
- Endpoints 为空:检查 Service selector 与 Pod labels 是否匹配;检查 readinessProbe 是否通过。
- DNS 解析失败:确认 CoreDNS Pod 运行正常;检查客户端 Pod 的
/etc/resolv.conf中 nameserver 和 search 域配置。 - 连接被拒绝:确认 targetPort 与容器实际监听端口一致;检查 Pod 是否 Ready。
- 负载不均衡:短时间连续请求可能因连接复用命中同一 Pod,属于正常现象;可通过新建连接或增加请求次数观察。
清理测试资源:
kubectl delete pod test-client。保留 Deployment 和 Service 供后续案例使用,或按需删除。