首页/云/Kubernetes 速查/StatefulSet 与 Headless Service 的 DNS

StatefulSet 与 Headless Service 的 DNS

Headless Service(clusterIP: None)为每个 Pod 提供独立 DNS 记录,客户端可直连具体实例;这是有状态集群互相发现的基础。

Kubernetes 速查云更新于 2026-10-13

机制定位

Headless Service 把 clusterIP 设为 None,不分配虚拟 IP,DNS 查询直接返回后端 Pod 的地址列表;再配合 StatefulSet 的稳定命名,每个副本还独享一条 <pod>.<svc>.<ns>.svc.cluster.local 记录。适用平台是 Kubernetes。这是有状态集群(数据库、消息队列、ZK/etcd 类)互相发现的基石:客户端需要知道具体是哪一个实例,而虚拟 IP 只能做无差别转发。

基本信息

适用平台Kubernetes,Service 与 StatefulSet 配合
Headless 标志spec.clusterIP: None
记录形式服务级 <svc>.<ns>.svc.cluster.local、Pod 级 <pod>.<svc>.<ns>.svc.cluster.local
就绪影响未就绪的 Pod 默认不进可用后端,可用 publishNotReadyAddresses 改变

典型使用场景

  • 数据库主从发现:客户端按固定名字连接某个具体实例
  • 集群成员配置:把 Pod 级 DNS 名写进集群的成员列表
  • 滚动重启期间的连接保序:先连指定序号再重建
  • 排查连接错实例:确认解析返回的是 Pod 地址列表还是虚拟 IP
  • 无头服务的调试:用临时 Pod 逐个解析各实例名字验证暴露情况

Headless Service

Headless Service
apiVersion: v1
kind: Service
metadata:
  name: db-headless
spec:
  clusterIP: None
  selector:
    app: db
  ports:
    - name: pg
      port: 5432

DNS 记录验证

DNS 记录验证
kubectl run dns-test --rm -it --image=busybox:1.36 --restart=Never -- sh
# 容器内:
nslookup db-headless.prod.svc.cluster.local
nslookup db-0.db-headless.prod.svc.cluster.local
nslookup db-1.db-headless.prod.svc.cluster.local
kubectl get endpoints db-headless                          # 对比 DNS 返回的地址列表
kubectl get pods -l app=db -o wide                         # 核对实例与就绪状态

两种 Service 的差别

对比项ClusterIPHeadless
解析结果返回虚拟 IP返回后端 Pod 地址列表
客户端选择由 kube-proxy 转发决定客户端自行选择实例
每实例记录无有(StatefulSet 场景)
适用场景无状态服务的负载均衡入口有状态集群的成员发现
Pod 级 DNS 形如 <pod>.<headless-svc>.<ns>.svc.cluster.local;Headless 的 DNS 直接返回 Pod IP 列表,由客户端自行选择,因此负载均衡策略落在客户端。
未就绪的 Pod 默认不会出现在可用地址里,重建期间成员列表会短暂缺少该实例,集群软件要能容忍这种情况。

落地时的核对点

  • 确认 StatefulSet 的 serviceName 指向 Headless Service,写错时 Pod 级记录不会生成
  • 确认 Pod 就绪:未就绪的实例默认不解析,重建期间成员列表会短暂变短
  • 确认客户端行为:Headless 不提供转发,连接失败要由客户端重试与重选实例
  • 确认证书与成员配置使用了 Pod 级名字,改 serviceName 时要同步更新这两处

易错点

  • 普通 Service 的 DNS 返回的是虚拟 IP,无法定位单个实例;有状态集群互联必须用 Headless
  • Pod 未 Ready 时默认不会出现在 Headless 的可用后端列表里(publishNotReadyAddresses 可改),重建期间成员数会波动
  • 把 Headless 当负载均衡器用:它不做转发,客户端要自己实现选路与重试,无状态服务仍应使用普通 Service
  • 改 StatefulSet 的 serviceName 会改变 Pod 级 DNS 名,成员配置与证书 SAN 都要同步更新,属于高危变更

数据来源与参考

  • Kubernetes 官方文档 · StatefulSet(Stable Network ID)/ Headless Services
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌