Azure Kubernetes集群中Spring Boot应用无法解析MongoDB Pod主机名
我之前在Azure K8s上部署Spring Boot + MongoDB的时候,碰到过几乎一模一样的UnknownHostException问题,结合当时的排查和解决经验,给你几个亲测有效的方向:
1. 别直接连Pod hostname,用MongoDB Service作为稳定入口
K8s里的Pod本身是临时资源——重启、扩缩容、调度后,Pod的hostname和IP都会变,哪怕你现在能解析,后续也大概率出问题。既然你说Spring Boot能连接到Mongo Service,那直接把连接字符串改成用Service名称就好:
mongodb://<mongo-service-name>:27017/your-database-name
比如你的Service叫mongo-dev,就写mongodb://mongo-dev:27017/your-db。K8s的DNS会自动把Service名称解析到背后的Mongo Pod,而且Service的DNS记录是稳定的,不会随Pod变化而失效。
如果是MongoDB副本集部署,推荐用Headless Service(clusterIP: None),这样客户端能自动发现所有副本集成员,连接字符串可以写成:
mongodb://<mongo-headless-service-name>:27017/your-db?replicaSet=your-replica-set-name
2. 检查Spring Boot Pod的DNS策略
默认情况下K8s Pod的DNS策略是ClusterFirst,会用集群内的CoreDNS解析内部域名,但如果你的Spring Pod被改成了Default策略,就会用节点的DNS,大概率解析不了Mongo Pod的hostname。
你可以查看Spring Pod的YAML配置,确认dnsPolicy字段:
apiVersion: v1 kind: Pod metadata: name: spring-app-pod spec: dnsPolicy: ClusterFirst # 确保是这个值 # 其他配置...
如果不是,改成ClusterFirst后重启Pod试试。
3. 验证集群DNS的可用性
有时候Azure K8s的CoreDNS组件可能出问题,导致内部域名解析失败。你可以做两个测试:
- 先检查CoreDNS Pod的状态:
确保所有CoreDNS Pod都是kubectl get pods -n kube-system | grep corednsRunning状态,没有频繁重启。 - 然后在Spring Boot Pod里手动解析Mongo Pod的hostname:
如果解析失败,说明CoreDNS没有同步Mongo Pod的DNS记录,可以尝试重启CoreDNS Pod:kubectl exec -it <spring-app-pod-name> -- nslookup mongo-dev-0kubectl rollout restart deployment coredns -n kube-system
4. 给MongoDB客户端加上重试与故障转移配置
哪怕偶尔出现解析问题,客户端的重试机制也能帮你自动恢复。在Spring Boot的配置里加上这些参数:
application.yml示例:
spring: data: mongodb: uri: mongodb://mongo-dev:27017/your-db?retryWrites=true&w=majority client-options: retry-reads: true retry-writes: true connect-timeout: 10000 # 10秒连接超时 socket-timeout: 10000 # 10秒Socket超时
这些配置会让客户端在连接失败、读取/写入失败时自动重试,提升连接的稳定性。
5. 检查网络策略是否限制了DNS流量
如果你的集群配置了K8s网络策略,可能不小心阻止了Spring Boot Pod访问CoreDNS(53端口,UDP/TCP协议),导致域名解析失败。可以临时禁用网络策略测试:
kubectl delete networkpolicy <policy-name>
如果禁用后连接恢复正常,就需要调整网络策略,允许Spring Boot Pod访问kube-system命名空间下的CoreDNS,以及Mongo Pod的相关流量。
内容的提问来源于stack exchange,提问作者mj17711

