win7系统用sqlyog连接不上docker启动的mysql数据库

写在前面

Docker 是一个能够把开发的应用程序自动部署到容器的开源引擎。Docker 提供了一个简单、轻量的建模方式。掌握 Docker 以后,使用 Docker 安装我们学习或者开发时常用的 mysql / redis / elastic search / rabbitMQ 等等会变得十分便捷。在作者尝试用windows 7 电脑上的 Docker 容器部署 mysql 5.7 数据库过程中,遇到了使用 sqlyog 却连接不上 mysql 服务的问题。在第1小节中,我将演示一下如何使用 docker-compose 在 Docker 容器中启动一个 MySQL 服务。第 2 小节,记录的是我分析 Sqlyog 连接不上 Docker 容器中的 mysql 数据库的原因。第 3 小节,则是阐述解决问题的方式。如果你只关心这个问题是如何解决的,请直接跳至“问题解决”章节。

作者在定位问题的过程中,接触了 Docker 常用的指令,在本文中也稍稍做个记录。另外,再开始 MySQL 部署之前,请确保你已经安装设置好 Docker 环境了,可以参考这篇 Docker在WIN7上的配置

win7系统用sqlyog连接不上docker启动的mysql数据库

1.Docker 容器启动 MySQL

Docker Mysql 官方文档
Docker compose-file 官方文档

相比于复杂的 docker 命令,我更愿意选择使用docker-compose方式在 Docker 容器中启动 MySQL。

1.1 创建 yaml 文件

version: '3.1'
services:
  test-mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    ports:
      - "3306:3306"
    volumes:
      - "/d/VirtualSpace/mysql/my.cnf:/etc/mysql/conf.d/my.cnf"
      - "/d/VirtualSpace/mysql/:/docker-entrypoint-initdb.d/"

version

version 代表的是 Compose File Format(构成文件格式)的版本,有 1,2,2.x,3.x 版本,目前常见的是 3.x 版本(传送门
你可以通过 docker --version 命令查看一下你的 docker 是否支持对应的 Compile File Format 版本。

win7系统用sqlyog连接不上docker启动的mysql数据库

services

我认为,services 代表是服务进程,可以通过docker ps查看启动进程。

win7系统用sqlyog连接不上docker启动的mysql数据库

这个名字的组成结构是 <当前工作路径名>_<servicename>_<sequencenumber>,我的 docker-compose.yml 文件路径是 D:\VirtualSpace\mysql\docker-compose.yml;服务名称 servicename 是 test-mysql;序号 sequencenumber 是从 1 开始计数的。

想了解更多关于 servicename 的内容,可以查看 docker-compose service name和container name的关系

image

一般来说,比较推荐使用 Dockerfile 来构建镜像,截止到 2020 年 11 月,MySQL 支持的镜像标签有以下几种:

environment

启动 mysql 映像时,可以通过在 docker run 命令行上传递一个或多个环境变量来调整 MySQL 实例的配置。

MYSQL_ROOT_PASSWORD
该变量是必需变量,它指定将为 MySQL root 用户的密码。

ports

要么指定两个端口(HOST:CONTAINER),要么仅指定容器端口(选择临时主机端口)。

volumes

冒号左边是指定主机的文件系统路径,冒号右边是指定容器的文件系统路径。从基础主机文件系统系统路径,装入容器文件系统路径。
首次启动容器时,将创建一个具有指定名称的新数据库,并使用提供的配置变量对其进行初始化。 此外,它将执行在/docker-entrypoint-initdb.d中找到的扩展名为.sh.sql.sql.gz的文件。文件将按字母顺序执行。您可以通过将 SQL 转储安装到该目录中并为自定义图像提供贡献的数据来轻松填充 mysql 服务。 默认情况下,SQL 文件将导入到 MYSQL_DATABASE 变量指定的数据库中。

关于 windows 系统的特殊说明:

我使用的是 win7 系统,在安装 Docker 时,用到了 VirtualBox,Docker 其实是运行在 VirtualBox 中的

win7系统用sqlyog连接不上docker启动的mysql数据库

默认情况下,仅对C:\Users 目录下进行挂载,对应的 Linux 虚拟机路径是 /c/Users

win7系统用sqlyog连接不上docker启动的mysql数据库

因为我们在 docker-compose.yml 中有指定 /d/VirtualSpace/mysql/my.cnf/d/VirtualSpace/mysql/,这其实是由你 Windows 主机上的 D:\VirtualSpace\mysql\my.cnfD:\VirtualSpace\mysql 共享给虚拟机,然后再挂载到 Docker 容器。正因为共享给虚拟机了,所以虚拟机中也可以访问到我们的指定文件。

win7系统用sqlyog连接不上docker启动的mysql数据库

1.2 启动服务

docker-compose down

暂停所有的服务

docker-compose up

启动当前工作目录下的服务,docker-compose up -d 表示后台启动命令。

1.3 使用 SQLyog 尝试连接

然后在使用 SQLyog 连接时,主机地址选择 localhost,端口 3306:

win7系统用sqlyog连接不上docker启动的mysql数据库

出现错误 1045,这是表示访问密码错误:

win7系统用sqlyog连接不上docker启动的mysql数据库

出现这个错误的主要原因:我以前在本地安装过 mysql,所以这个其实是我 windows 主机安装的 mysql 服务,不是 docker 容器的 mysql 服务,为了避开这个问题,我选择修改了 docker-compose.ymlports 属性

ports:
  - "3311:3306"

然后重新启动服务。再次尝试,这次的 Host Address 仍然是 localhost,端口改为 3311

win7系统用sqlyog连接不上docker启动的mysql数据库

2003 错误主要原因,网上的常见说法都是没有启动 mysql 服务。如果是 windows 主机安装的 mysql 服务,只要启动一下 mysql 服务就好了。但是,我们此时是用 Docker 容器启动服务的。

2.问题分析

真的会是 Docker mysql 服务没有正常启动的原因吗?

docker ps

该命令可以查看 Docker 服务进程

win7系统用sqlyog连接不上docker启动的mysql数据库

分析:我们看到 test-mysql 服务是正常启动的,而且端口也是正确的。

难道说端口映射不起作用?于是我百度了一下,找了好久,这篇文章(解决无法对docker容器进行端口映射的问题)终于解答了我的疑惑。

网上还有一种说法,说是没有给 root 账号授权。

docker exec

docker exec 命令允许您在 Docker 容器内运行命令。 以下命令行将在 mysql容器内为您提供 bash 外壳:

docker exec -it mysql_test-mysql_1

在 Bash 中登录 mysql 客户端

mysql -uroot -p123456

在 mysql 客户端查询用户权限

SELECT HOST,USER,PLUGIN FROM mysql.user;

win7系统用sqlyog连接不上docker启动的mysql数据库

这里默认是给 host 授权了的,所以至少我连不上不是因为 root 账号没有授权的缘故。

3.问题解决

之所以在 Windows 主机上出现端口映射“不起作用”的情况,是因为在Linux上,docker 守护进程(和您的容器)在 Linux 机器本身上运行,因此“localhost”也是容器在其上运行的主机,并且端口已映射到该主机。
相对地,在 Windows(和 OS X)上,docker 守护程序和您的容器无法在本地运行,因此只有 docker 客户端在 Windows 机器上运行,而守护程序(和您的容器)在运行Linux的 VirtualBox 虚拟机中运行。于是我们通过以下命令:

docker-machine ip default

找到这个Linux的ip地址,一般情况下这个地址是 192.168.99.100

win7系统用sqlyog连接不上docker启动的mysql数据库

因此 Host Address 改为 192.168.99.100

win7系统用sqlyog连接不上docker启动的mysql数据库

总结一下:

在 Windows(和 OS X)系统上,docker 守护程序和您的容器无法在本地运行,因此只有 docker 客户端在 Windows 机器上运行,而守护程序(和您的容器)在运行Linux的 VirtualBox 虚拟机中运行。

参考文献

解决无法对docker容器进行端口映射的问题

Docker之docker volume 挂载到容器(Windows下,volume目录挂载在容器、四)(第十四篇)

Docker Mysql 官方文档

Docker compose-file 官方文档

上一篇:数据库原理学习记录


下一篇:Android中使用HttpGet和HttpPost访问HTTP资源