Service实现内部服务发现的核心是通过稳定服务名或ClusterIP访问Pod,关键在于标签匹配、端口对齐和DNS可达:确保Deployment标签与Service selector完全一致;正确区分port(Service暴露端口)和targetPort(Pod实际监听端口);默认ClusterIP类型自动分配集群内虚拟IP并注册DNS;需通过kubectl get endpoints、nslookup及curl验证连通性。

用 Service 实现内部服务发现,核心是让集群内应用通过稳定的服务名或 ClusterIP 访问后端 Pod,而不依赖会变化的 Pod IP。关键不在于写多复杂的配置,而在于标签匹配、端口对齐和 DNS 可达这三点。
确保 Pod 有明确且一致的标签
Service 通过 label selector 找到后端 Pod,所以 Deployment(或其他控制器)里定义的 labels 必须和 Service 的 selector 完全对应。
- 比如在 Deployment 中设置:
labels: {app: api-server} - 那 Service 的
selector就必须写成:app: api-server - 少一个空格、大小写不一致、键名拼错,Endpoint 就为空——
kubectl get endpoints <svc-name>会显示<none>
正确区分 port 和 targetPort
Service 配置里的两个端口容易混淆,但逻辑很清晰:
- port:Service 暴露出来的端口,集群内其他服务访问这个端口
-
targetPort:Pod 容器实际监听的端口,可以是数字(如
8080),也可以是容器中定义的端口名(如http) - 例如容器启动时监听
8080,那targetPort: 8080;如果容器 YAML 中写了ports: - name: http, containerPort: 8080,则targetPort: http也合法
默认 ClusterIP 类型即可满足内部发现
不写 type: 字段,Kubernetes 就自动创建 ClusterIP 类型 Service,这是专为内部通信设计的:
- 分配一个仅集群内可达的虚拟 IP(如
10.96.123.45) - 同时自动注册 DNS 名称:
<service-name>.<namespace>.svc.cluster.local - 同命名空间下可直接用
<service-name>访问(CoreDNS 自动补全) - 跨命名空间则用
<service-name>.<other-ns>,比如redis.default从prod空间调用
验证服务是否真正可发现
光看 kubectl get svc 不够,要确认三层连通性:
- 查 Endpoint:
kubectl get endpoints <svc-name>—— 应列出至少一个IP:port - 进一个 Pod 测试 DNS:
nslookup <svc-name>或ping <svc-name>(需 busybox 类镜像) - 测试连通性:
curl -v http://<svc-name>:80/health,看是否返回后端响应 - 如果失败,优先检查 Pod 是否就绪(
READY列为1/1)、readinessProbe 是否通过


















