Docker Compose 解决服务间 DNS 解析失败问题

前言

在使用 Docker Compose 部署微服务架构时,发现部分服务无法通过容器名称解析其他服务,导致服务启动失败并进入重启循环。

问题现象

初始错误

启动 Docker Compose 时,出现以下错误:

bash 复制代码
docker compose --env-file .env --env-file .env.image.amd64 up -d
✘ Container elastic-wanwu       Error dependency es failed to start

服务重启循环

多个服务出现重启循环,日志显示 DNS 解析失败:

json 复制代码
{"level":"FATAL","ts":"2026-01-06T07:12:05.681Z","caller":"assistant-service/main.go:56","msg":"init redis err: dial tcp: lookup redis-wanwu: i/o timeout"}
{"level":"FATAL","ts":"2026-01-06T07:11:36.091Z","caller":"iam-service/main.go:58","msg":"init redis err: dial tcp: lookup redis-wanwu: i/o timeout"}

问题排查过程

1. 首先解决 Elasticsearch 启动问题

Elasticsearch 容器日志显示:

复制代码
bootstrap check failure [1] of [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

解决方案:

bash 复制代码
# 永久修复
echo 'vm.max_map_count=262144' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

2. 网络连接状态检查

检查 Docker 网络配置:

bash 复制代码
docker network ls | grep wanwu
docker network inspect wanwu-net

发现网络配置正常,所有容器都正确连接到 wanwu-net 网络并获得了 IP 地址。

3. DNS 解析测试

使用测试容器验证 DNS 解析:

bash 复制代码
docker run --rm --network wanwu-net alpine:latest nslookup redis-wanwu

结果显示:

复制代码
;; connection timed out; no servers could be reached

这表明问题出在 DNS 解析层面。

4. Docker 守护进程配置检查

检查 Docker 服务状态:

bash 复制代码
sudo systemctl status docker

发现 Docker 守护进程配置了有问题的 DNS 设置:

复制代码
--dns 10.233.0.3 --dns 127.0.0.53 --dns-search default.svc.cluster.local --dns-search svc.cluster.local

这些 Kubernetes 相关的 DNS 配置导致容器内的 DNS 解析失败。

根本原因分析

问题的根本原因是 Docker 守护进程配置了不当的 DNS 设置,这些设置来自于系统中的多个配置文件:

  • /etc/systemd/system/docker.service.d/docker-dns.conf
  • /etc/systemd/system/docker.service.d/docker-options.conf
  • /etc/systemd/system/docker.service.d/override.conf

这些配置文件中的 DNS 设置(特别是 Kubernetes 集群的 DNS)在非 Kubernetes 环境中无法正常工作,导致容器内的 DNS 解析完全失败。

解决方案

方案一:临时解决 - 使用 IP 地址

bash 复制代码
# 获取 Redis 容器的 IP 地址
docker inspect redis-wanwu | grep IPAddress

# 修改环境变量,使用 IP 地址替代主机名
cp .env.bak .env.temp
sed -i 's/redis-wanwu/172.18.0.4/g' .env.temp

# 重启服务
docker compose --env-file .env.temp --env-file .env.image.amd64 restart bff-service iam-service assistant-service

方案二:根本解决 - 清理 Docker DNS 配置

  1. 查看现有配置文件:
bash 复制代码
ls -la /etc/systemd/system/docker.service.d/
cat /etc/systemd/system/docker.service.d/docker-dns.conf
  1. 备份并禁用有问题的 DNS 配置:
bash 复制代码
# 备份现有配置
sudo cp /etc/systemd/system/docker.service.d/docker-dns.conf /etc/systemd/system/docker.service.d/docker-dns.conf.bak

# 临时禁用 DNS 配置
sudo mv /etc/systemd/system/docker.service.d/docker-dns.conf /etc/systemd/system/docker.service.d/docker-dns.conf.disabled
  1. 重启 Docker 服务:
bash 复制代码
sudo systemctl daemon-reload
sudo systemctl restart docker
  1. 重新启动应用服务:
bash 复制代码
docker compose --env-file .env --env-file .env.image.amd64 up -d

验证解决方案

解决后,可以通过以下方式验证:

  1. 检查容器状态:
bash 复制代码
docker ps
  1. 测试 DNS 解析:
bash 复制代码
docker run --rm --network wanwu-net alpine:latest nslookup redis-wanwu
  1. 查看服务日志:
bash 复制代码
docker logs assistant-service --tail 10
docker logs iam-service --tail 10

经验总结

问题诊断思路

  1. 分层排查:从基础设施(Elasticsearch)到网络层(DNS)逐步排查
  2. 日志分析:通过容器日志快速定位问题类型
  3. 网络测试:使用简单的测试容器验证网络连通性
  4. 配置检查:检查 Docker 守护进程的配置参数

预防措施

  1. 环境隔离:避免在非 Kubernetes 环境中使用 Kubernetes 相关的 DNS 配置
  2. 配置管理:定期检查和清理不必要的 Docker 配置文件
  3. 监控告警:建立容器健康检查和 DNS 解析监控

适用场景

这个解决方案适用于以下场景:

  • Docker Compose 服务间无法通过容器名称互相访问
  • 容器内 DNS 解析超时或失败
  • 在混合环境(Kubernetes + Docker Compose)中出现的 DNS 冲突

通过彻底清理 Docker 的 DNS 配置,我们成功解决了服务间的网络通信问题,所有微服务都能正常启动并相互通信。

相关推荐
酷酷的崽79813 分钟前
CANN 生态可维护性与可观测性:构建生产级边缘 AI 系统的运维体系
运维·人工智能
做人不要太理性18 分钟前
CANN Runtime 运行时组件深度解析:任务调度机制、存储管理策略与维测体系构建逻辑
android·运维·魔珐星云
souyuanzhanvip28 分钟前
ServerBox v1.0.1316 跨平台 Linux 服务器管理工具
linux·运维·服务器
文静小土豆36 分钟前
Docker 与 containerd 代理配置详解:镜像拉取速度慢的终极解决方案
运维·docker·容器
HalvmånEver2 小时前
Linux:线程互斥
java·linux·运维
JY.yuyu2 小时前
Docker常用命令——数据卷管理 / 端口映射 / 容器互联
运维·docker·容器
lpruoyu3 小时前
【Docker进阶-06】docker-compose & docker swarm
运维·docker·容器
China_Yanhy4 小时前
入职 Web3 运维日记 · 第 8 日:黑暗森林 —— 对抗 MEV 机器人的“三明治攻击”
运维·机器人·web3
艾莉丝努力练剑4 小时前
hixl vs NCCL:昇腾生态通信库的独特优势分析
运维·c++·人工智能·cann
酉鬼女又兒4 小时前
每天一个Linux命令_printf
linux·运维·服务器