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上的配置

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 版本。

services

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

这个名字的组成结构是 <当前工作路径名>_<servicename>_<sequencenumber>,我的 docker-compose.yml 文件路径是 D:VirtualSpacemysqldocker-compose.yml;服务名称 servicenametest-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 中的

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

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

1.2 启动服务

docker-compose down

暂停所有的服务

docker-compose up

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

1.3 使用 SQLyog 尝试连接

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

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

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

ports:
  - "3311:3306"

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

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

2.问题分析

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

docker ps

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

分析:我们看到 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;

这里默认是给 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

因此 Host Address 改为 192.168.99.100

总结一下:

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

参考文献

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

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

Docker Mysql 官方文档

Docker compose-file 官方文档

原文地址:https://www.cnblogs.com/kendoziyu/p/windows-os-cannot-connect-to-mysql-server-with-sqlyog.html