Windows Docker环境下GitLab CI作业无法解析服务主机名db
环境
- GitLab 15.8-ee
- Windows Server 2019 Datacenter(已启用容器功能)
- GitLab Runner 采用
docker-windows执行器
问题
Linux环境中正常运行的CI配置,迁移到Windows后,构建容器无法通过服务别名db访问MySQL服务容器。但两者IP互ping正常,构建容器也能ping通服务容器的随机主机名。
排查方向
检查构建容器hosts文件
执行docker inspect <构建容器ID>找到HostsPath对应的文件,查看是否存在db到服务容器IP的映射。Windows Docker的NAT网络下,GitLab Runner可能无法自动注入别名条目。验证Runner网络配置
查看Runner的config.toml,确认network_mode是否为nat(Windows默认),检查是否有其他网络相关配置影响别名解析:[[runners]] executor = "docker-windows" [runners.docker] network_mode = "nat" # 其他配置...确认服务容器的别名配置
执行docker inspect <服务容器ID>,查看NetworkSettings.Aliases字段,确认db别名是否已正确设置。
解决方法
方法1:动态添加Hosts条目
在构建脚本中获取服务容器IP并手动添加到hosts:
script: - # 获取服务容器IP(可通过容器标签或名称过滤) - FOR /f "tokens=*" %%i IN ('docker inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" <服务容器标识>') DO SET DB_IP=%%i - # 写入hosts文件 - echo %DB_IP% db >> C:\Windows\System32\drivers\etc\hosts - mysqlping -h db
需确保构建容器有修改hosts的权限,或使用特权模式运行容器。
方法2:使用Runner自动生成的服务IP变量
GitLab Runner会为每个服务生成环境变量<别名>_PORT_<端口>_TCP_ADDR,直接用该变量连接:
script: - mysqlping -h %DB_PORT_3306_TCP_ADDR%
该变量无需手动配置,由Runner自动注入,是最简便的解决方案。
方法3:切换Docker网络为Transparent模式
NAT网络的限制可能导致别名解析异常,切换到Transparent模式让容器直接使用宿主机网段IP,更接近Linux bridge的解析逻辑:
- 停止Docker服务:
Stop-Service Docker - 修改
C:\ProgramData\docker\config\daemon.json:{ "bridge": "none", "ipam": { "driver": "default", "config": [{"subnet": "你的宿主机网段/24", "gateway": "你的网关IP"}] } } - 重启Docker服务:
Start-Service Docker - 更新Runner的
config.toml,将network_mode改为transparent。
方法4:升级GitLab Runner版本
旧版docker-windows执行器存在服务别名解析的已知bug,升级到最新稳定版(建议16.x及以上)可能修复问题。直接替换现有Runner服务并重新注册配置即可。
内容的提问来源于stack exchange,提问作者Jürgen Steinblock

