Headless Service 是一种很特殊的 Service 用法:它不分配 ClusterIP,而是把 DNS 结果更直接地指向 Pod 级别。它最适合那些需要明确知道“自己在和哪个副本说话”的系统,尤其是数据库、复制集群和其他有状态服务。
一个 Service 怎么才算 headless
关键字段其实很简单:
clusterIP: None
一旦这样配置,Kubernetes 就不会再给它一个普通的虚拟 IP 来做传统意义上的负载均衡,而是更强调 Pod 级别的 DNS 发现。
什么时候该用 Headless Service
- StatefulSet 场景下需要稳定副本身份
- 数据库主从或多成员拓扑需要精确定位实例
- 集群成员之间依赖固定 peer 发现
- 客户端自己要感知或控制具体副本
如果你只想做普通集群内访问,大多数时候普通的 ClusterIP Service 更简单、更合适。
最小示例
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
为什么它和 StatefulSet 天然连在一起
StatefulSet 负责给副本稳定名字,Headless Service 负责让这些名字在 DNS 层变得真正可用。
所以这两个主题天然是一起看的:
kubernetes-quickstart-statefulset.md讲的是稳定身份和顺序- 这篇讲的是客户端和节点怎么真正发现这些身份
Headless Service 不会替你做什么
这里最容易出错。
Headless Service 不会:
- 像普通 ClusterIP 那样帮你做常规负载均衡
- 自动保证所有返回的地址都“逻辑上可用”
- 帮你修复 selector 错误或 readiness 错误
它主要改变的是“服务发现方式”,不是“自动兜底逻辑”。
真出问题时先检查什么
别一上来就怀疑 DNS 或 CoreDNS,先看对象关系:
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>
如果 selector 没选中、Pod 不 Ready、endpoints 不对,DNS 再正常也帮不了你。
Headless 和普通 Service 的区别
普通 Service 更适合:
- 客户端只需要一个稳定服务名
- 后端副本可互换
- 流量应该自动分散
Headless 更适合:
- 客户端必须知道具体副本是谁
- 业务自己处理拓扑和连接分配
- 副本身份是协议或集群行为的一部分
一个很实用的心智模型
普通 Service 更像是在说:
“把流量打到这组应用上。”
Headless Service 更像是在说:
“告诉我现在到底有哪些具体 Pod 存在。”
YAML 只差一点点,运维思路其实差很多。
常见故障模式
DNS 能解析,但流量还是不通
通常不是 DNS 本身坏了,而是返回的 Pod 还没 Ready,或者客户端错误地以为它还能得到普通负载均衡体验。
没有有效 endpoints
大多数时候就是 selector、labels 或 readiness 问题。
Stateful 应用在发布时拓扑异常
这往往意味着应用确实依赖固定成员关系,但 rollout 顺序、readiness 或拓扑假设没有设计好。
FAQ
Q: Headless Service 是不是只能配 StatefulSet? A: 不是,但 StatefulSet 是最典型、最自然的搭配场景,因为它提供稳定副本身份。
Q: Headless Service 会帮我做负载均衡吗? A: 不会按普通 ClusterIP 的方式帮你做。它主要是暴露副本级别的 DNS 身份。
Q: 为什么我应该先看 endpoints,而不是先抓 DNS 日志? A: 因为大多数 Headless 问题,本质上是 selector、readiness 或 endpoints 关系不对,而不是 DNS 实现本身坏了。
下一步阅读
- 接着读
kubernetes-quickstart-statefulset.md,理解稳定身份是怎么来的 - 再读
kubernetes-quickstart-service.md,对比普通 Service 的工作方式 - 如果你还要把状态和存储串起来,继续看
kubernetes-quickstart-pv-pvc.md和kubernetes-quickstart-storageclass.md
收个尾
Headless Service 的价值,在于它少做了一层抽象。这让有状态系统更容易获得明确的副本身份,但也意味着你必须更认真地思考 selector、readiness、客户端行为和拓扑假设。