必须配置headless service并正确关联statefulset,其核心是设置clusterip: none且statefulset中servicename字段严格匹配service名称,从而为每个pod生成如kafka-broker-0.kafka-headless.default.svc.cluster.local的稳定可解析域名,支撑有状态服务发现与直连。

要在Kubernetes中让StatefulSet的每个Pod拥有固定可解析的域名、支持节点间直连与服务发现,必须配置Headless Service并正确关联StatefulSet,否则Pod重启后DNS名称失效、客户端无法定位特定实例。
创建Headless Service资源
执行以下YAML定义一个不分配ClusterIP的服务,仅用于DNS服务发现:
apiVersion: v1
kind: Service
metadata:
name: kafka-headless
labels:
app: kafka
spec:
clusterIP: None
ports:
- port: 9092
name: broker
selector:
app: kafka
【clusterIP: None是唯一判定Headless Service的关键字段】,漏写或写成"null"、""、"false"均无效,Kubernetes会默认回退为ClusterIP类型。
编写StatefulSet并绑定Headless Service
StatefulSet必须通过serviceName字段显式引用上一步创建的Headless Service名称,否则Pod不会获得稳定DNS记录:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: kafka-broker
spec:
serviceName: "kafka-headless"
replicas: 3
selector:
matchLabels:
app: kafka
template:
metadata:
labels:
app: kafka
spec:
containers:
- name: kafka
image: confluentinc/cp-kafka:7.3.0
ports:
- containerPort: 9092
serviceName字段值必须与Headless Service的metadata.name完全一致,包括大小写和连字符。若填错,kubectl apply不会报错,但Pod的DNS记录(如kafka-0.kafka-headless.default.svc.cluster.local)将无法生成。
验证DNS解析是否生效
进入任一Pod内部,用nslookup检查Headless Service域名是否返回全部Pod IP:
kubectl exec -it kafka-broker-0 -- nslookup kafka-headless.default.svc.cluster.local
预期输出应包含三条A记录,对应kafka-broker-0、kafka-broker-1、kafka-broker-2的真实IP;若只返回一条或报NXDOMAIN,说明Service未正确匹配Pod标签或CoreDNS异常。
再单独查询某个Pod的全限定域名:
kubectl exec -it kafka-broker-0 -- nslookup kafka-broker-1.kafka-headless.default.svc.cluster.local
这步能确认StatefulSet的每个实例是否拥有独立可解析身份——这是ZooKeeper选举、Kafka Controller注册、Dledger节点发现的前提。











