mysql - 图1

前言 此篇幅内容较多,讲解的很详细,也有很多知识点。能耐心认真的读完,就很不错了~

如果你觉得此文章不错的话,或者是根据此文档进行安装mysql的话,抽空在文档最下方留个言吧~让我看到你的支持~

Docker镜像加速器

如果觉得国外下载速度太慢,可以配置一个“Docker镜像加速器”,来提高镜像下载的速度。

一般情况下,建议配置镜像加速地址,在Linux中修改 /etc/docker/daemon.json 文件,填入以下内容:

  1. {
  2. "registry-mirrors": ["https://slbf4zxk.mirror.aliyuncs.com"]
  3. }

上面我就使用阿里云提供的镜像加速地址;

如果daemon.json不存在的话,需要自己创建一下。 文件修改保存成功之后,记得重启一下Docker服务,以便让这个镜像加速生效。

重启Docker服务 我们在【在centos系统中安装Docker】一节中讲过Docker随着服务器重启自动启动的内容,正好可以通过命令service docker restart来实现Docker服务的重启。 具体详情请查看 https://yuque.com/zhoubang/docker/rqspmt#cuygcr

然后我们在Linux中执行命令:

  1. service docker restart

出现下图所示结果,表明Docker服务已经重新启动了!这样就可以永久性的使用Docker加速服务了。

如果不做特别的配置的话,之前处于运行状态的容器,随着Docker服务的重启也会停止运行。

下载mysql镜像

  1. docker pull mysql

如果配置了镜像加速,那么在下载mysql镜像或者其他比较大的文件的时候,会发现下载速度变得非常快!

启动mysql容器

  1. docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --name=mysql mysql

其中 -e 的作用是用于设置环境变量,mysql默认用户名为root,则MYSQL_ROOT_PASSWORD即为root设置密码,即123456

查看运行的mysql容器

  1. docker ps

如下图:
mysql - 图2

mysql容器已经正常启动了!

进入mysql容器

既然mysql服务启动了,如果我们想对mysql进行操作(比如进入命令行操作、客户端连接等操作),该怎么办?

通过 docker exec 命令进入mysql容器:

  1. docker exec -it c9 /bin/bash

其中的“c9”指的当前mysql容器ID的前面部分值(在上图就可以看出来mysql容器的ID是 c94faeed480a)。

回车运行效果如下图:
mysql - 图3

其实这个时候,命令行控制台可以输入mysql相关的命令了。

连接mysql数据库

  1. mysql -u root -p123456

如下图:
mysql - 图4
这个就是我们非常熟悉的mysql命令行界面了!
我们可以在这里创建数据库、表等操作。再次印证了Docker的强大和方便!mysql - 图5

查看当前所有的数据库

在mysql命令行中执行命令:

  1. show databases;

如下图所示:mysql - 图6

完全就是和平常使用mysql一样。

创建数据库、表、新增测试数据

  • 创建数据库
  1. create database docker_test;

效果如下图:
mysql - 图7

这里我就创建了一个数据库docker_test

  • 选择数据库

首先需要选择具体的数据库,执行命令选择刚刚创建的数据库:

  1. use docker_test
  • 创建表
  1. create table test(name varchar(20),age int(11));

创建了test表,有2个字段:name、age

  • 添加测试数据
  1. insert into test values("Kitty",26),("Tom",18),("Jack",36);

这里就简单添加3条测试数据。

我们查询一下数据是否存在于数据库中:

  1. select * from test;

mysql - 图8

一切OK!

客户端连接mysql数据库

既然mysql成功启动并运行,除了能在命令行中操作mysql数据库之外,肯定也是必须要能在客户端上连接和操作数据库才行。

下面我就在我本地电脑上通过数据库客户端软件连接一下这个mysql数据库, 看看能不能正常连接和操作。

我使用的是DataGrip客户端软件,如果你们需要的话,可以下载使用 https://pan.baidu.com/s/1NkzEG_rjwFBylUSMxfIUzw 如果版本低的话,可以到官方下载最新版本 https://www.jetbrains.com/datagrip/

打开本地DataGrip客户端,新建连接mysql数据库
mysql - 图9

输入正确的mysql相关信息,连接数据库:
mysql - 图10

输入完成之后,可以点击下方的 Test Connection 按钮,来测试连接是否正常。

查看创建的数据库和表:
mysql - 图11

到此,mysql的相关服务已经正常访问和操作了。这和我们传统的使用mysql没有什么不同。

客户端中操作表数据

我们通过DataGrip客户端,在test表中手动再添加一条数据,然后我们在docker中看看是否能查看到新增的数据:

mysql - 图12

【注意】:我这里添加了一条带有中文的数据。

进入mysql容器中查询表数据

mysql - 图13

呀!是不是发现问题了~ 没错,中文乱码!怎么解决呢?

mysql容器中解决表数据中文乱码

查看mysql容器的ID
mysql - 图14

进入mysql的docker容器

  1. docker exec -it c9 /bin/bash

编辑mysql配置文件

  1. vim /etc/mysql/my.cnf

如果提示 vim: command not found 的错误信息,需要安装相关依赖包,执行下面两个命令即可:

  1. apt-get update
  1. apt-get install vim

在my.cnf文件中加入以下配置

  1. [mysqld]
  2. character-set-server=utf8
  3. [client]
  4. default-character-set=utf8
  5. [mysql]
  6. default-character-set=utf8

最终修改结果为:
mysql - 图15

重新进入mysql容器,查询表数据,显示结果为:
mysql - 图16

可以看到,已经正常显示中文了!

停止并重启mysql容器,再次查看效果

mysql - 图17

客户端DataGrip重新连接mysql:
mysql - 图18

客户端连接正常!

进入mysql容器,查看表数据:
mysql - 图19

mysql容器重启之后,查询数据正常显示中文!一切没什么问题了~

通过commit命令提交新的镜像

根据在mysql容器中所做的更改,创建新的mysql镜像。

回想一下,我们在mysql容器中做了什么更改? 创建数据库、表、新增数据、修改my.cnf配置文件,就是这些吧~

使用commit命令提交新镜像
通过在Linux命令行中执行命令,提交新的镜像:

  1. docker commit c9 mysql-new

其中,“c9”就是指的容器ID,新的镜像名称为“mysql-new”。

如下图:
mysql - 图20

查看所有镜像列表:
mysql - 图21

是不是发现了我们创建的新的镜像mysql-new了。

启动新创建的mysql镜像

mysql - 图22

由于上面我们已经运行了一个mysql的容器了,端口是3306,所以我们新运行一个mysql容器的时候,端口号就不能是3306了,这里我指定为3307,且容器的别名是mysql-new,方便区分查看。

进入新创建的mysql容器

  • 查看mysql数据库信息

mysql - 图23

  • 查看my.cnf配置文件内容

mysql - 图24
从上面2张图中,可以明显的看到,我们之前创建的数据库docker_test、表test,都没有了!但是修改的my.cnf配置文件的内容还是保留着的。

why??? 为什么会这样呢?

官方文档在commit命令的介绍中,有这样一段话: The commit operation will not include any data contained in volumes mounted inside the container.

意思是commit操作并不会包含容器内挂载数据卷中的数据。

如果对于“数据卷”不了解的话,确实看不懂是什么意思。

数据卷与数据卷容器

生产环境中使用Docker的过程中,往往需要对数据进行持久化,或者需要在多个容器之间进行数据共享,这必然涉及容器的数据管理操作。

容器中管理数据主要有两种方式:

数据卷(Data Volumes):数据卷是一个可供容器使用的特殊目录,它将主机操作系统目录直接映射进容器。 数据卷容器(Data Volume Containers):数据卷容器也是一个容器,但是它的目的是专门用来提供数据卷,供其他容器挂载使用的。

根据官方文档对于commit的介绍中,可以猜测到为何之前创建的数据库、表都不见了,原因是因为mysql容器的挂载数据卷引起的。

我们可以通过命令查看到别名是“mysql”的容器挂载数据卷的目录。

看一下我们的“mysql”容器的ID信息,方便查看。

mysql - 图25

通过命令docker inspect查看mysql这个容器的数据卷挂载信息:

  1. docker inspect c9

执行命令之后,由于显示的内容比较多,这里我们就贴一下重要的信息:

mysql - 图26

通过图中可以看到,mysql容器将容器内的/var/lib/mysql路径作为volume挂载。真正的数据库相关数据文件所在的目录就是“Source”对应的目录,即:/var/lib/docker/volumes/1b0b17f6a4f78d357a187116d75991db8ee784213e67cc9b9988c8ef647fe563/_data

我们可以进入mysql容器查看/var/lib/mysql目录下的内容:
mysql - 图27

发现的确是mysql数据库的数据文件(红色区域)。

这时候,我们切换到Linux命令行,进入到mysql容器的数据挂载目录,看看该目录下有什么内容:
/var/lib/docker/volumes/1b0b17f6a4f78d357a187116d75991db8ee784213e67cc9b9988c8ef647fe563/_data
如下图所示:
mysql - 图28

咦~ 是不是发现了什么!把黄色区域的内容与上图中红色区域内容进行对比,是不是内容一模一样!
这也就印证了,当初我们在mysql容器中创建的数据库、表等,真正的数据库文件存放的位置就是在宿主机下面,而不是存放在容器中。

到此,我们终于知道了为何mysql-new容器中的数据库、表都不见了,原来数据库文件是存放在宿主机上的。

那该如何解决这个问题呢?怎样才能让mysql-new容器启动之后可以正常加载我们之前创建的数据库、表等数据呢?这就引入了下面的正题 —— 数据挂载。

数据挂载

docker的数据挂载分为三种,volume、bind mount和tmpfs,关于三种的具体说明,有兴趣了解的可以看一下官网的文档 https://docs.docker.com/storage/

参考文档 《基于docker部署mysql的数据持久化问题》 https://www.jianshu.com/p/530d00f97cbf

上面的文章里面,把问题描述的非常详细清楚。我这里就不多做说明了。

使用 -v 实现数据挂载(数据卷)

如果我们想在 run 一个新的mysql容器的时候,可以正常访问我们之前在mysql容器中创建的数据库、表数据,则在docker run命令启动容器的时候,就需要指定挂载目录。

注意:要想让新的mysql容器能正常挂载名称是“mysql”容器,前提是需要先停止名称是“mysql”的容器,不然的话,即使run命令配置正确,容器启动的时候会一直报错:
mysql - 图29
上图就是因为没有事先停止mysql容器导致的。

下面开始具体操作:

  • 先停止mysql容器

mysql - 图30

  • 重新启动一个新的mysql容器,命令如下:
  1. docker run -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql-v -v /var/lib/docker/volumes/1b0b17f6a4f78d357a187116d75991db8ee784213e67cc9b9988c8ef647fe563/_data:/var/lib/mysql mysql

最重要的一个参数 -v :挂载数据卷。-v 后面的值中间有“:”号,前半部分指的是宿主机的目录(也就是我们上面的mysql容器的数据库存储的目录),后半部分指的是容器的目录。 实现的效果就是说:新启动的容器,挂载宿主机的目录,实现数据共享。

运行结果:
mysql - 图31

登录新的mysql-v容器,查看数据库信息

直接看下图的命令操作吧:
mysql - 图32
看到效果了吧!在这个mysql-v的新容器里面,已经可以看到我们一开始在“mysql”容器中创建的数据库和表了。
也就实现了容器之间的数据共享。mysql - 图33

核心的实现就是在run命令里面加入了 -v 参数。如果不太明白-v的含义的,可以自行网上查询资料了解学习,加深印象。

上面我们解决了容器挂载数据卷的问题,但是细心的朋友,可能还有一个疑问:

为什么修改了my.cnf配置文件、以及运行mysql镜像时指定的MYSQL_ROOT_PASSWORD=123456,却依然可以在新容器mysql-new中使用呢,为什么这俩样数据不会消失呢?

官方文档对于commit命令还有这样一段描述: It can be useful to commit a container’s file changes or settings into a new image.

谷歌翻译过来的意思就是:将容器的文件更改或设置提交到新映像可能很有用。

还记得我们当初运行第一个mysql容器的时候,docker run 命令是怎样的,这里贴一下当时启动容器的命令:

  1. docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --name=mysql mysql

其中,里面使用到了 -e 参数,设置了root用户的密码为123456。 所以,结合官方文档对commit的介绍(It can be useful to commit a container’s file changes or settings into a new image. ),就可以知道,通过 -e 设置的信息,在使用commit提交新镜像的时候,这些设置被容器保留了下来,commit命令使用这些设置构建了新的镜像,在新容器里面使用的是相同的设置。

这也印证了,我们在mysql-new容器中登录数据库的时候,登录密码写的是123456。因为在第一次启动mysql服务的时候,用户root密码是通过 -e 指定的,所以在commit提交新的镜像的时候,是被一同提交到了新镜像mysql-new中。

数据卷容器

通过数据卷容器也可以实现多个容器间的数据共享。

如果要授权一个容器访问另一个容器的数据卷,我们可以使用-volumes-from参数来执行docker run。

(这里就不多做说明了,有兴趣的可以网上自行查阅资料研究)