CFN Cloud
Cloud Future New Life
en zh
2025-10-11 · 52 次浏览

Headless Service(无头服务)

为 StatefulSet 提供稳定 DNS 解析,不做负载均衡。

Headless Service 不分配 ClusterIP,而是直接返回 Pod 的 DNS 记录,常用于 StatefulSet。

典型用途

  • 需要固定 Pod 地址的数据库
  • 主从复制需要准确定位实例

示例

apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  clusterIP: None
  selector:
    app: mysql
  ports:
    - port: 3306
      targetPort: 3306

创建后可直接访问: mysql-0.mysql.default.svc.cluster.local

真正需要你关注的点

Headless Service 最容易被误解的一点是:它不做负载均衡。它做的事情很简单——把 DNS 解析结果直接指到 Pod(或者 EndpointSlice)上。

所以排查时你别先去找什么“ClusterIP 通不通”,而是先确认下面几件事:

  • selector 有没有选中 Pod(选不中就没有 endpoints)
  • Pod 是否 Ready(不 Ready 也可能不会进 endpoints)
  • 你访问的 DNS 名称是否正确(尤其是 namespace 和 service 名)

最常用的几条命令:

kubectl get svc -n <ns> <svc> -o yaml
kubectl get pods -n <ns> -l app=mysql -o wide
kubectl get endpoints -n <ns> <svc> -o wide
kubectl get endpointslices -n <ns> -l kubernetes.io/service-name=<svc>

如果 endpoints 不对,先别怀疑 DNS,通常是 selector/labels 或 readiness 的锅。

网络身份与服务发现

Kubernetes 网络强调“稳定名称”而不是“稳定 IP”。Service 提供稳定的虚拟 IP 和 DNS 名称,Endpoints 会追踪后端 Pod。Headless Service 是在这个模型上构建网络访问与发现规则的关键环节。

Service 类型与路由选择

ClusterIP 适合内部访问,NodePort 与 LoadBalancer 用于对外暴露,Ingress 则负责 HTTP 路由与域名管理。选择何种类型取决于环境与流量路径,建议明确哪些入口是用户访问、哪些是内部调用、哪些仅用于调试。

Headless 与直连模式

Headless Service 不创建虚拟 IP,而是直接发布 Pod IP,适合需要固定地址或集群内 peer 发现的系统。此时客户端需要自行处理连接均衡与故障转移,但可以获得更直接的拓扑控制。

Port forward 的定位与限制

端口转发适合临时调试,不改变集群网络配置即可从本地访问 Pod 或 Service。它不应作为生产访问方式,也不适合长期自动化。需要常规访问时,应设计正式的 Service 或 Ingress。

DNS 命名习惯

Kubernetes DNS 支持短名称与完整名称,跨命名空间时建议使用 service.namespace 形式。稳定的命名规则可以减少配置混乱,提升团队协作效率。

外部流量路径

外部流量通常经过负载均衡、NodePort、kube-proxy 到达 Pod,每一跳都会引入超时与失败点。排障时应按路径逐段确认连接状态。

安全与策略

NetworkPolicy 可能阻断通信,即便 DNS 能解析也无法连通。若使用 mTLS 或服务网格策略,要确保策略与 Service 选择器一致,避免意外断流。

运维建议

统一命名规则便于 DNS 预测。上线时关注 endpoints 是否及时更新,尤其是在滚动更新期间。外部流量要设置健康检查与超时策略,避免负载均衡层把请求打到不可用实例。

kubectl get svc -n demo
kubectl get endpoints -n demo
kubectl get endpointslices -n demo
kubectl port-forward svc/demo-api 8080:80 -n demo

收个尾:Headless 的排障别绕远路

Headless Service 相关问题,最常见的“假象”是:你以为是 DNS 不工作,实际上是 endpoints 根本不对(selector 没选中、Pod 不 Ready、端口或标签对不上)。

所以遇到访问不通时,优先做一件事:先看 endpoints / endpointslices,再决定要不要怀疑 DNS。这比一上来抓 CoreDNS 日志更省时间。

参考链接