Docker化MariaDB非root用户xyz登录被拒(root可正常登录)
问题描述
使用最新版MariaDB Docker镜像创建了与root凭据完全相同的用户xyz,执行查询查看用户信息:
mysql> SELECT User, Host FROM mysql.user; +-------------+-----------+ | User | Host | +-------------+-----------+ | root | % | | xyz | 127.0.0.1 | | healthcheck | 127.0.0.1 | | healthcheck | ::1 | | xyz | localhost | | healthcheck | localhost | | mariadb.sys | localhost | | root | localhost | +-------------+-----------+
查看该用户权限:
mysql> show grants for xyz@'127.0.0.1'; +-----------------------------------------------------------------------------------------------------------------------+ | Grants for xyz@127.0.0.1 | +-----------------------------------------------------------------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO `xyz`@`127.0.0.1` IDENTIFIED BY PASSWORD '*something' | | GRANT ALL PRIVILEGES ON `somedatabase`.* TO `xyz`@`127.0.0.1` | +-----------------------------------------------------------------------------------------------------------------------+
测试登录时,root用户可正常登录:
bash> mysql -uroot -h 127.0.0.1 -P3308 -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 19 ....
但xyz用户登录被拒绝:
bash> mysql -uxyz -h 127.0.0.1 -P3308 -p Enter password: ERROR 1045 (28000): Access denied for user 'xyz'@'172.17.0.1' (using password: YES)
原因分析
核心问题出在Docker网络的IP识别逻辑:
- 当你在宿主机执行
mysql -h 127.0.0.1连接Docker容器内的MariaDB时,请求会通过Docker默认网桥(docker0)转发到容器,此时容器内部识别到的客户端IP是宿主机在网桥中的默认IP(172.17.0.1),而非你指定的127.0.0.1。 - 当前xyz用户仅配置了
127.0.0.1和localhost的登录权限,没有覆盖172.17.0.1或更广泛的IP范围,因此被数据库拒绝。 - 而root用户存在
root@%的条目(%表示允许任意IP登录),所以可以正常连接。
排查与解决步骤
排查步骤
- 从错误提示确认连接来源IP:错误信息
Access denied for user 'xyz'@'172.17.0.1'直接说明容器识别到的客户端IP是172.17.0.1,而非你指定的127.0.0.1。 - 核对用户Host范围:查看
mysql.user表,确认xyz用户的Host列没有包含172.17.0.1或%。
解决方法
任选一种即可:
- 方法1:允许从宿主机网桥IP登录
进入容器内的MariaDB,执行以下命令:CREATE USER 'xyz'@'172.17.0.1' IDENTIFIED BY '你的密码'; GRANT ALL PRIVILEGES ON *.* TO 'xyz'@'172.17.0.1'; FLUSH PRIVILEGES; - 方法2:允许从任意IP登录(和root权限一致)
执行以下命令创建通配Host的xyz用户:CREATE USER 'xyz'@'%' IDENTIFIED BY '你的密码'; GRANT ALL PRIVILEGES ON *.* TO 'xyz'@'%'; FLUSH PRIVILEGES; - 方法3:使用socket连接(仅宿主机本地访问)
如果不需要远程连接,去掉-h 127.0.0.1参数,直接执行:
此时会通过Unix socket连接,匹配mysql -uxyz -P3308 -pxyz@localhost的用户条目。
内容的提问来源于stack exchange,提问作者celaeno
相关产品推荐
相关产品推荐

