如何通过域名正常访问Docker容器内运行的MySQL服务器?
核心原因
MySQL用户授权中的Host字段,匹配的是发起连接的客户端来源IP(或其反向解析的主机名),而非客户端连接时指定的目标服务器域名/IP。
你看到错误提示里的192.168.10.10,说明发起连接的客户端IP就是DNS服务器的IP(比如你是在DNS服务器容器内执行的连接命令)。你授权的db_user@db.xxx.com,只有当客户端IP反向解析后的主机名是db.xxx.com时才会匹配,但192.168.10.10的反向解析结果显然不是这个域名,因此连接被拒绝。
另外,你的Docker Compose配置中,network_mode: "host"与ports配置冲突——host网络模式下,容器直接使用宿主机网络端口,ports配置会被忽略,可以删除该字段。
可行解决方案
方案1:利用反向解析匹配主机名
如果希望通过主机名而非IP授权,确保客户端IP(192.168.10.10)的反向DNS解析结果是你期望的主机名,然后授权对应主机名的用户:
CREATE USER 'db_user'@'dns-server-hostname' IDENTIFIED BY 'your-password'; GRANT ALL PRIVILEGES ON your-db.* TO 'db_user'@'dns-server-hostname'; FLUSH PRIVILEGES;
方案2:关闭MySQL反向解析
若不需要通过主机名授权,可在MySQL配置文件中添加skip-name-resolve,关闭IP反向解析功能。此时MySQL仅通过IP匹配用户Host字段,需确保授权的Host是客户端IP或IP段:
[mysqld] skip-name-resolve port = 3306 bind-address = 192.168.10.100
注意:开启
skip-name-resolve后,所有用主机名定义的用户(比如db_user@db.xxx.com)将无法匹配,需改为IP形式授权。
方案3:精准授权客户端IP段
如果客户端IP属于固定段,可授权对应IP段而非单个IP:
CREATE USER 'db_user'@'192.168.10.%' IDENTIFIED BY 'your-password'; GRANT ALL PRIVILEGES ON your-db.* TO 'db_user'@'192.168.10.%'; FLUSH PRIVILEGES;
补充说明
你之前用localhost配置正常,是因为当时客户端是在MySQL容器内部或宿主机本地连接,来源IP是localhost,与授权的db_user@localhost匹配。修改监听地址和用户后,客户端来源IP变为DNS服务器的IP,因此触发权限问题。
内容的提问来源于stack exchange,提问作者Jib

