Docker容器无法连接宿主机Cosmos DB模拟器问题咨询
问题场景
环境配置:Windows设备运行Linux容器模式的Docker Desktop,通过Docker Compose部署容器化.NET应用,应用依赖Cosmos服务,默认配置内置Cosmos模拟器的官方默认账户密钥。
使用的docker-compose.yml配置片段如下:
customerapi: container_name: mycustomerapi image: acr.io/customer-api:master ports: - "20102:80" environment: - ASPNETCORE_ENVIRONMENT=Development - CosmosOptions__Endpoint=${endpoint} - CosmosOptions__DisableSsl=true
故障表现
覆盖配置连接Azure托管的正式Cosmos实例时,应用运行正常,但始终无法连接宿主机本地运行的Cosmos模拟器,已尝试的配置及对应报错如下:
- 将
${endpoint}设置为https://host.docker.internal:8081/:等待约5分钟后连接失败,报错为System.Net.Http.HttpRequestException: Connection refused (127.0.0.1:8081) - 将
${endpoint}设置为宿主机局域网IP地址https://192.168.10.110:8081/:约10秒后快速失败,报错与上述连接被拒绝错误一致 - 为服务添加
network_mode: host配置后重试上述两个地址,仍然失败:- 访问
https://host.docker.internal:8081/依旧报连接被拒绝错误 - 访问
https://192.168.10.110:8081/约10秒后失败,报错为System.Net.Http.HttpRequestException: No route to host (192.168.10.110:8081)
- 访问
排查解决步骤
按以下顺序逐一排查即可定位解决绝大多数同类问题:
- 修正Cosmos模拟器启动参数
Cosmos模拟器默认仅绑定127.0.0.1环回地址,不会响应来自本机其他网卡(包括Docker虚拟网卡、局域网网卡)的请求,这是该场景下最高发的故障原因。- 先完全退出本地运行的Cosmos模拟器
- 打开命令提示符,进入模拟器默认安装目录
C:\Program Files\Azure Cosmos DB Emulator,执行以下命令启动模拟器,放开网络访问限制:Microsoft.Azure.Cosmos.Emulator.exe /AllowNetworkAccess /Key=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw== - 启动完成后执行
netstat -ano | findstr "8081",确认8081端口的监听地址为0.0.0.0:8081,而非仅127.0.0.1:8081,同时在宿主机浏览器访问https://localhost:8081/_explorer/index.html确认模拟器本身运行正常。
- 修正Docker网络配置
- 删除compose配置中的
network_mode: host项:注意:Windows平台Docker Desktop的host网络模式仅对Windows容器生效,Linux容器使用该配置会出现路由表异常,直接导致访问宿主机失败。恢复使用默认的桥接网络即可。 - 不要使用宿主机局域网IP作为Endpoint,Linux容器访问宿主机服务统一使用
host.docker.internal特殊域名,最终CosmosOptions__Endpoint配置值固定为https://host.docker.internal:8081/即可。
- 删除compose配置中的
- 放行Windows防火墙规则
打开Windows Defender防火墙高级设置,添加入站规则允许8081端口的TCP入站连接,也可以临时关闭防火墙做连通性验证。配置完成后进入运行中的应用容器,执行以下命令测试网络连通性:
如果命令能返回HTML内容,说明容器到模拟器的网络层已经打通。curl -k https://host.docker.internal:8081 - 解决模拟器自签名证书信任问题
仅配置CosmosOptions__DisableSsl=true无法完全绕过.NET SDK的SSL校验,Cosmos模拟器使用自签名证书,容器内的Linux系统默认不信任该证书,会导致连接失败,二选一处理即可:- 规范处理方式:将模拟器生成的自签名证书(默认路径为
C:\Users\<你的用户名>\AppData\Local\AzureCosmosDBEmulator\cosmosdbemulatorcert.pem)挂载到容器的系统信任证书目录,在compose服务配置下添加卷挂载:
同时在容器启动时先执行volumes: - C:\Users\你的用户名\AppData\Local\AzureCosmosDBEmulator\cosmosdbemulatorcert.pem:/usr/local/share/ca-certificates/cosmosdbemulatorcert.crt:roupdate-ca-certificates更新系统信任证书列表,再启动.NET应用。 - 开发临时处理方式:在.NET应用初始化Cosmos客户端的代码中,配置HttpClient回调忽略SSL证书错误,注意:该配置仅允许本地开发环境使用,禁止在生产环境开启。
- 规范处理方式:将模拟器生成的自签名证书(默认路径为
内容的提问来源于stack exchange,提问作者zXynK
相关产品推荐
相关产品推荐

