最推荐做法是在docker-compose.yml服务级配置dns和dns_search字段。它确保所有Java容器统一使用内网DNS(如192.168.10.5)优先解析短域名,并通过dns_search自动补全后缀(如svc.cluster.local),兼顾公网兜底,且可避免宿主机DNS干扰和JVM缓存问题。

在 Java 容器化部署中,为多容器项目配置统一的内部自定义 DNS,核心目标是让所有 Java 服务(如 Spring Boot 应用)能稳定解析内网短域名(如 auth、payment),同时兼顾公网域名访问。不依赖宿主机 DNS,也不靠硬编码完整域名,关键在于从 Docker 网络层统一注入可复用的 DNS 策略。
用 docker-compose.yml 在服务级声明 dns + dns_search
这是最推荐、最可控的做法,尤其适合微服务编排场景:
- 在每个 Java 服务的
service下直接写dns和dns_search字段,确保容器启动时/etc/resolv.conf被准确覆盖 -
dns列表按优先级顺序填写:内网 DNS(如公司 CoreDNS 地址192.168.10.5)放第一位,公网 DNS(如114.114.114.114或8.8.8.8)作兜底 -
dns_search设为内网域名后缀(如["svc.cluster.local", "internal"]),这样 Java 应用调用http://auth时,DNS 会自动尝试auth.svc.cluster.local和auth.internal - 示例片段:
services: order-service: image: my-java-app:1.0 dns: - 192.168.10.5 - 114.114.114.114 dns_search: - svc.cluster.local - internal
通过自定义 bridge 网络统一继承 DNS 配置
当多个 Java 服务共用同一套网络策略时,避免重复配置,提升可维护性:
- 在
networks区块定义一个自定义 bridge 网络,并直接设置dns和dns_search - 所有接入该网络的服务(包括 Java 应用、数据库、缓存等)自动继承,无需每个服务单独写
- 注意:仅对
bridge或overlay网络生效,host或none网络不支持 - 示例:
networks: app-net: driver: bridge dns: - 192.168.10.5 - 1.1.1.1 dns_search: - internal - svc.cluster.local然后各服务通过networks: [app-net]接入即可
配合内嵌 DNS 实现服务名直连(轻量级服务发现)
Docker 自带的内嵌 DNS(地址 127.0.0.11)可解析同网络容器名,适合无额外 DNS 服务的简单场景:
立即学习“Java免费学习笔记(深入)”;
- 创建自定义网络(如
docker network create myapp)后,所有加入该网络的 Java 容器默认启用内嵌 DNS - Java 应用可直接用
http://user-service访问同网服务(前提是服务名与docker-compose.yml中的 service 名一致) - 若需解析公网域名,仍需搭配
dns字段提供上游 DNS;内嵌 DNS 本身不递归查询外部域名 - 验证方式:进入容器执行
nslookup user-service,应返回对应 IP
验证与常见避坑点
配置完成后务必验证实际行为,避免“写了但没生效”:
- 进容器检查:
cat /etc/resolv.conf,确认nameserver和search行已写入预期值 - 测试解析:
nslookup auth.internal或dig +short payment.svc.cluster.local - 注意 systemd-resolved:若宿主机使用它,
/etc/resolv.conf往往是软链接,Docker 不穿透解析,必须显式配置dns字段 - Java 应用自身缓存:JVM 默认对 DNS 结果缓存较久(可能达数分钟),可在启动参数加
-Dnetworkaddress.cache.ttl=30缩短 TTL


















