首页/云/云与容器速查/Headless Service 无头服务
Kubernetes68 条

Headless Service 无头服务

clusterIP: None 的 Service:不为服务分配虚拟 IP,DNS 直接返回各 Pod 的 A 记录。StatefulSet 的稳定 DNS、自定义服务发现都依赖它。

云与容器速查云更新于 2026-10-13

不给虚拟 IP 的服务

Headless Service 是不分配集群虚拟 IP 的 Service(把 clusterIP 设为 None):查询服务名时,DNS 直接返回各个后端 Pod 的地址列表,而不是一个统一的代理地址。有状态集群的稳定 DNS 标识与自研服务发现都依赖它,因为客户端需要看到全部实例,而不是被隐藏在一层转发之后。

基本信息

声明方式spec.clusterIP 设为 None
DNS 行为查询服务名得到全部就绪 Pod 的地址记录
单实例访问Pod 名.服务名.命名空间.svc.cluster.local 可直达指定实例
典型搭配StatefulSet 通过 serviceName 关联,自研选主与分片逻辑
对比普通 Service普通 Service 的 DNS 只返回一个集群地址,看不到后端列表
无选择器时可手工维护端点对象,用于把外部服务以固定名称接入集群

典型使用场景

  • 有状态数据库集群的节点发现与成员管理
  • 分片与选主逻辑需要完整的实例视图
  • 客户端自己做负载均衡(如一致性哈希)的场景
  • 在集群内按实例名精确访问某个副本
  • 把集群外部的服务以固定名称接入,由手工端点维护地址

Headless 示例与验证

Headless 示例与验证
apiVersion: v1
kind: Service
metadata:
  name: db-headless
spec:
  clusterIP: None          # 无头服务:不分配虚拟 IP
  selector:
    app: db
  ports:
    - port: 3306
      targetPort: 3306

# 验证
kubectl get svc db-headless -o jsonpath='{.spec.clusterIP}'   # 应输出 None
kubectl run -it --rm netshoot --image=nicolaka/netshoot -- nslookup db-headless.default.svc.cluster.local

检查项读法

检查项正常表现异常表现
clusterIP显示 None显示具体地址说明不是无头服务
服务名 DNS 查询返回多个后端地址只返回一个地址说明是普通 Service
单实例名查询解析到对应 Pod 地址解析失败说明实例名或命名空间写错
Endpoints列出全部就绪后端为空说明选择器不匹配或 Pod 未就绪
未就绪实例默认不出现在 DNS 结果中客户端拿到未就绪地址说明发布策略被改动过
客户端拿到多个地址后如何选择由应用决定:数据库类场景常见「连第一个可用实例」或按分片路由。无头服务本身不提供负载均衡与故障转移,重试与健康检查要由客户端实现。
把无头服务当负载均衡用会出问题:DNS 多值轮询不是四层负载均衡,客户端可能持续命中同一实例,或反复尝试已经故障的地址,表现为「扩容了但压力没分散」。

易错点

  • 把无头服务当负载均衡:多值轮询不等价于四层负载均衡,客户端需要自己容错与重试
  • 选择器留空却想做外部名称映射:语义不同,需要搭配手工维护的端点对象
  • 客户端长期缓存 DNS 结果:Pod 重建后地址变化,旧地址导致连接失败
  • 依赖未就绪实例做数据同步:默认不发布未就绪地址,同步链路要按就绪状态设计

数据来源与参考

  • Kubernetes Docs:Headless Services

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌