Kubernetes StatefulSet关联Pod名称无法通过CoreDNS解析问题排查
问题根因定位
StatefulSet 要生成 podname.servicename 格式的DNS解析记录,必须同时满足3个核心条件,你当前的配置缺失了至少一项:
serviceName指向的服务必须是带选择器的无头服务,即同时满足:- 服务的
spec.clusterIP显式设置为None - 服务的
spec.selector完全匹配 StatefulSet 模板中 Pod 的标签
- 服务的
- StatefulSet 配置的
serviceName必须和上述无头服务的名称完全一致,且同属一个命名空间 - 对应 Pod 被 StatefulSet 自动注入
spec.subdomain字段,值为serviceName的配置值
常见配置误区说明
为什么之前非无头服务场景能正常解析?
你之前的环境里同时存在 spilodemo-config 无头服务,且大概率 StatefulSet 实际绑定的 serviceName 是该无头服务,而非指向主库的无选择器ClusterIP服务,只是你之前没有注意到该关联关系。无选择器的服务不会关联Pod标签,CoreDNS 永远不会为其生成Pod级别的解析记录。
Zalando 示例中 spilodemo-config 无头服务的作用
原示例中指向主库的 spilodemo-svc 是无选择器服务,需要由Patroni手动维护Endpoint指向主库IP。如果直接用该服务作为StatefulSet的serviceName,无法满足带选择器的要求,因此额外新增一个带选择器的无头服务spilodemo-config,专门用来给StatefulSet提供稳定网络标识,生成Pod级DNS记录,同时不会干扰Patroni手动维护的主库Endpoint。
修复步骤
方案1:对齐Zalando原有架构(推荐,不影响主库访问逻辑)
- 保留原有无选择器的ClusterIP服务
spilodemo-svc,仍作为主库访问入口,由Patroni维护其Endpoint - 恢复
spilodemo-config无头服务配置,确保:spec.clusterIP: Nonespec.selector完全匹配StatefulSet中Pod的标签
- 修改StatefulSet的
serviceName参数值为spilodemo-config - 滚动更新StatefulSet,触发所有Pod重建,验证Pod的
spec.subdomain字段值为spilodemo-config即可。此时Pod的解析域名为spilodemo-0.spilodemo-config,如果需要用spilodemo-0.spilodemo-svc格式,只需将无头服务的名称改为spilodemo-svc,主库服务改名为spilodemo-master-svc即可。
方案2:合并为单一无头服务
- 将
spilodemo-svc修改为带选择器的无头服务:spec: clusterIP: None selector: # 替换为你实际的Pod标签键值对 app: spilodemo - 删除原有手动创建的
spilodemo-svc对应的Endpoint资源,避免被K8s自动覆盖 - 单独创建一个ClusterIP类型的服务作为主库访问入口,仍由Patroni维护其Endpoint
- 确认StatefulSet的
serviceName为spilodemo-svc,滚动更新StatefulSet即可。
验证方法
- 执行命令
kubectl get pod spilodemo-0 -o jsonpath='{.spec.subdomain}',输出值必须和serviceName配置一致 - 在同命名空间下的测试Pod中执行
nslookup spilodemo-0.spilodemo-svc,如果返回对应Pod的IP则配置生效。跨命名空间解析需要补全后缀:spilodemo-0.spilodemo-svc.<命名空间>.svc.cluster.local
内容的提问来源于stack exchange,提问作者Salvatore D'angelo
相关产品推荐
相关产品推荐

