如何让Docker容器正确连接宿主机内的MySQL数据库?
问题描述
- .NET 8 API被打包为Docker容器,运行在内部IPv4地址为
1.1.1.1的Ubuntu 22.04虚拟机中 - 使用MySQL 8.0.33数据库,连接字符串如下:
"ConnectionStrings": { "MySQL": "Server=1.1.1.1;Port=3306;initial catalog=db_name;uid=my-user;pwd=my-pass" }
- 本地运行API(将
Server改为localhost)正常,但容器化运行后出现连接错误:
An error occurred using the connection to database '' on server '1.1.1.1'. Unhandled exception. System.InvalidOperationException: An exception has been raised that is likely due to a transient failure. Consider enabling transient error resiliency by adding 'EnableRetryOnFailure()' to the 'UseMySql' call. ---> MySqlConnector.MySqlException (0x80004005): Unable to connect to any of the specified MySQL hosts.
- 尝试创建
my-user@localhost和my-user@1.1.1.1用户,SSH登录服务器后用mysql -u my-user -p可正常连接数据库,但容器仍无法连接,怀疑问题出在Docker网络配置。
解决方案
1. 修正MySQL用户的访问权限范围
容器内的请求来源并非宿主机的localhost或内部IP1.1.1.1,而是Docker默认子网(如172.17.0.0/16)内的IP。需创建允许Docker子网访问的用户:
-- 测试场景:允许所有IP访问(生产环境不建议) CREATE USER 'my-user'@'%' IDENTIFIED BY 'my-pass'; GRANT ALL PRIVILEGES ON db_name.* TO 'my-user'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES;
生产环境建议限制为Docker子网IP段,例如'my-user'@'172.17.0.%',可通过docker network inspect bridge查看具体子网范围。
2. 调整连接字符串的Server地址
容器访问宿主机MySQL时,需使用正确的宿主机网络地址:
- 默认bridge网络:将连接字符串的
Server改为host.docker.internal(Ubuntu需启动Docker时添加参数--add-host=host.docker.internal:host-gateway),或使用Docker网关IP(通常为172.17.0.1,可通过ip addr show docker0查看) - Host网络模式:启动容器时添加
--network host参数,容器共享宿主机网络,此时连接字符串可使用1.1.1.1或localhost:
docker run --network host -d your-api-image:tag
3. 检查MySQL绑定地址配置
确保MySQL允许外部访问,修改配置文件(通常为/etc/mysql/mysql.conf.d/mysqld.cnf):
bind-address = 0.0.0.0
重启MySQL服务生效:
sudo systemctl restart mysql
4. 验证容器与MySQL的网络连通性
进入容器内部测试网络连通性,排查是否为网络问题:
# 进入容器 docker exec -it your-api-container-name bash # 安装telnet(若未安装) apt update && apt install telnet # 测试MySQL端口连通性 telnet 172.17.0.1 3306
若能连通,说明网络正常,需检查用户权限或连接字符串;若不通,需排查Docker网络配置或宿主机防火墙规则。
内容的提问来源于stack exchange,提问作者Guilherme Santana
相关产品推荐
相关产品推荐

