尝试从主机连接到 MySQL Docker 容器时出现了“Reading initial communication packet”错误。
尝试从主机连接到 MySQL Docker 容器时出现了“Reading initial communication packet”错误。
我希望能够像在本地机器上安装了MySQL服务器一样连接到我的docker容器。我通过以下方式测试连接:
mysql -u root -proot -h 127.0.0.1 -P 3306 --protocol=tcp
如果我使用docker创建一个容器,我可以成功连接。像这样:
docker run --name some-mysql-standalone -p 127.0.0.1:3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7.29
如果我在docker-compose中使用容器作为服务,我会遇到错误:
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 2
MySQL服务器在容器内运行,我可以访问它。
我的docker-compose片段如下:
version: '2' services: mysql: image: mysql:5.7.29 container_name: some_mysql restart: unless-stopped volumes: - ./mysql/data:/var/lib/mysql - ./mysql/init:/docker-entrypoint-initdb.d ports: - 3306:3306 environment: MYSQL_DATABASE: some_mysql MYSQL_USER: root MYSQL_PASSWORD: root MYSQL_ROOT_PASSWORD: root
有趣的是,我已经使用这个docker-compose.yml
有一段时间了,没有任何问题。我不太确定我的环境发生了什么变化导致它停止工作。
如何使我的docker-compose中的mysql容器可以从主机访问?
问题出现的原因是mysql服务器为了更安全而设置的保护措施。在这种情况下,我是在一个构建在mysql:5.7之上的docker镜像中运行该服务的,而mysql服务器是通过调用/etc/init.d/mysql start来启动的,而不是使用mysql官方镜像的entrypoint。因此,这可能不适用于问题的上下文,但适用于mysql服务中指定的错误。
解决该问题的步骤如下:
1. 将/etc/mysql/mysql.conf.d/mysqld.cnf中的本地主机/循环地址替换为所有地址。
sed -i "s/bind-address.*/bind-address = 0.0.0.0/g" /etc/mysql/mysql.conf.d/mysqld.cnf
2. 重新启动mysql服务:
/etc/init.d/mysql restart
然后,我就能够从外部访问docker暴露的端口(使用主机机器进行验证)。
问题原因:某些docker镜像忽略环境变量指令,例如-e MYSQL_ROOT_PASSWORD=<MY_PASSWORD> -e MYSQL_ROOT_HOST=%
,所以需要手动在其他主机上添加(根)用户(%
)。
解决方法:通过以下步骤手动添加用户:
1. 运行docker exec -it <YOUR_CONTAINER_NAME> bash
进入容器的命令行界面。
2. 运行mysql -u root -p<MY_PASSWORD>
以root用户身份登录MySQL数据库。
3. 运行GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '<MY_PASSWORD>';
来授予root用户在任意主机上的所有权限。
4. 运行FLUSH PRIVILEGES;
来刷新权限设置。
以上方法能够解决问题,感谢您的建议。正如您所说,-e MYSQL_ROOT_PASSWORD=<MY_PASSWORD>
被忽略了,所以我必须使用默认密码"root"登录。