使用Docker在linux上部署MySQL

下载MySQL服务器Docker镜像

使用命令下载MYSQL-Community:

1
docker pull mysql/mysql-server:tag

   tag是你想拉的镜像版本的标签(例如5.5, 5.6,5.7, 8.0,或latest)。如果省略则会下载最新GA版本的MySQL-community-server的镜像。

1
2
3
4
5
6
7
8
[root@docker-study ~]# docker pull mysql/mysql-server:5.6
5.6: Pulling from mysql/mysql-server
a8d84c1f755a: Pull complete
36934cee5f0d: Pull complete
5a6871e55c04: Pull complete
7c67030deb6e: Pull complete
Digest: sha256:5a1cfc50ab8d147cb163c32558c7334519f5bb69ea82587d480f9f7050b77047
Status: Downloaded newer image for mysql/mysql-server:5.6

  使用以下命令列出下载的Docker镜像:

1
2
3
4
[root@docker-study ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql/mysql-server 5.6 ad62049ce4ab 6 weeks ago 217MB
[root@docker-study ~]#

启动MySQL服务器实例

   将MySQL镜像启动为容器:

1
2
3
[root@docker-study ~]# docker run --name=mysql1 -d mysql/mysql-server:5.6
321d33b946e7eb8ebea4fe829d1cfb953c6dd5663021088fb9cff21bcea2a112
[root@docker-study ~]#

    –name用于为容器提供自定义名称,该选项是可选的;,如果没有提供容器名称,则生成随机的名称。如果先前的docker pull或docker run 命令未下载指定名称和标记的镜像, 则现在下载该图像。下载完成后,开始初始化容器,并在运行docker ps命令时容器显示在正在运行的容器列表中 ; 例如:

1
2
3
4
[root@docker-study ~]# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
321d33b946e7 mysql/mysql-server:5.6 "/entrypoint.sh mysq…" 3 minutes ago Up 3 minutes (healthy) 3306/tcp mysql1
[root@docker-study ~]#

   初始化完成后,命令的输出将包含为root用户生成的随机密码; 例如,使用以下命令检查密码:

1
2
3
[root@docker-study ~]# docker logs mysql1 2>&1 | grep GENERATED
[Entrypoint] GENERATED ROOT PASSWORD: mOkuHorEKBEh4plym@KYsXYk%Ih
[root@docker-study ~]#

连接到Container内的MySQL服务器

    服务器准备就绪后,可以在刚刚启动的MySQL Server容器中运行 mysql客户端,并将其连接到MySQL服务器。使用docker exec -it命令在已启动的Docker容器中进入 mysql客户端,输入生成的root密码。因为MYSQL_ONETIME_PASSWORD 默认情况下该选项为true,所以在将mysql客户端连接 到服务器之后,重置服务器root密码,如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@docker-study ~]# docker exec -it mysql1 mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 50
Server version: 5.6.43

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123456');
Query OK, 0 rows affected (0.00 sec)

容器shell访问

   要使用shell访问MySQL Server容器,请使用 docker exec -it命令在容器内启动bash shell:

1
2
[root@docker-study ~]# docker exec -it mysql1 bash
bash-4.2#

   然后可以在容器内运行Linux命令。例如,要查看容器内server数据目录中的内容

1
2
3
bash-4.2# ls /var/lib/mysql
auto.cnf ib_logfile0 ib_logfile1 ibdata1 mysql mysql.sock performance_schema test
bash-4.2#

停止和删除MySQL容器

   使用以下命令停止创建的MySQL Server容器:

1
2
3
[root@docker-study ~]# docker stop mysql1
mysql1
[root@docker-study ~]#

   docker stop向 mysqld进程发送SIGTERM信号 ,以便正常关闭服务器。

   另请注意,当容器的主进程(MySQL服务器容器中的mysqld)停止时,Docker容器会自动停止。

1
2
3
4
5
6
7
8
9
10
11
12
要再次启动MySQL Server容器:
docker start mysql1

使用单个命令停止并重新启动MySQL Server容器:
docker restart mysql1

要删除MySQL容器,请先将其停止,然后使用 docker rm命令:
docker stop mysql1
docker rm mysql1

如果希望同时删除服务器数据目录的 Docker卷,请将该-v选项添加到 docker rm命令。
docker rm -v mysql1

配置MySQL服务器

   启动MySQL Docker容器时,可以通过docker run命令将配置选项传递给服务器; 例如,对于MySQL服务器:

1
2
3
[root@docker-study ~]# docker run --name mysql1 -d mysql/mysql-server:5.6 --character-set-server=utf8mb4 --collation-server=utf8mb4_col
ae491dde8ad07c8db420facc6a7b6546b3ae375d7e37430e4a01a6b4c34913f3
[root@docker-study ~]#

   该命令启动MySQL服务器 utf8mb4作为默认字符集和 utf8mb4_col数据库的默认排序规则。

   配置MySQL服务器的另一种方法是准备配置文件并将其安装在容器内的服务器配置文件的位置。

持久化数据和配置更改

   Docker容器原则上是短暂的,如果容器被删除或损坏,预计会丢失任何数据或配置。 但是,Docker卷提供了一种机制来保存在Docker容器中创建的数据。在初始化时,MySQL Server容器为服务器数据目录创建一个Docker卷。在容器上运行docker inspect命令的JSON输出有一个 Mount键,其值提供有关数据目录卷的信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@docker-study ~]# docker inspect mysql1
[
…………
"Mounts": [
{
"Type": "volume",
"Name": "4ae57cb3823bf75c18b2212530fee42bc7d851446a5fee48406542c04df62221",
"Source": "/var/lib/docker/volumes/4ae57cb3823bf75c18b2212530fee42bc7d851446a5fee48406542c04df62221/_data",
"Destination": "/var/lib/mysql",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],…………

   输出显示/var/lib/docker/volumes/4ae57cb3823bf75c18b2212530fee42bc7d
851446a5fee48406542c04df62221/_data主机文件夹(主机上持有数据)已安装在 /var/lib/mysql容器内的服务器数据目录中。

   保留数据的另一种方法是 在创建容器时 使用–mount绑定安装主机目录。可以使用相同的技术来持久保存服务器的配置。以下命令创建MySQL Server容器并绑定安装数据目录和服务器配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@docker-study ~]#  ls
anaconda-ks.cfg datadir docker initial-setup-ks.cfg my.cnf src
[root@docker-study ~]# cat my.cnf
[client]
default-character-set=utf8
socket = /usr/local/mysql/mysql.sock
[mysql]
default-character-set=utf8
[mysqld]
basedir = /usr/local/mysql
datadir = /var/lib/mysql
port = 3306
socket = /usr/local/mysql/mysql.sock
character-set-server=utf8
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
[root@docker-study ~]# docker run --name=mysql1 \
--mount type=bind,src=/root/my.cnf,dst=/etc/my.cnf \
--mount type=bind,src=/root/datadir,dst=/var/lib/mysql \
-d mysql/mysql-server:5.6
58d707e7a9f75b38516d17dc54ee3685e00052969c01c887b40f0ac8f819a936
[root@docker-study ~]# ls datadir/
ibdata1 ib_logfile0 ib_logfile1 mysql performance_schema test
[root@docker-study ~]#

   安装 path-on-host-machine/my.cnf 到/etc/my.cnf(容器内部的配置文件),同时 path-on-host-machine/datadir 到/var/lib/mysql(数据容器内的目录)。必须满足以下条件才能使绑定安装正常工作:

   配置文件 path-on-host-machine/my.cnf 必须已存在,并且必须包含使用用户启动mysql服务器的规范:

1
2
3
[mysqld]
user=mysql
…………

   数据目录 path-on-host-machine/datadir 必须已存在。要进行服务器初始化,目录必须为空。还可以安装预先填充数据的目录并启动服务器; 但是必须确保使用与创建数据的服务器相同的配置来启动Docker容器,并在启动容器时装入所需的任何主机文件或目录。

运行其他初始化脚本

如果在创建数据库后立即要在数据库上运行任何.sh或 .sql脚本,则可以将它们放入主机目录,然后将目录 /docker-entrypoint-initdb.d/挂载在容器内部。例如,对于MySQL Server容器:

1
2
3
docker run --name=mysql1 \
--mount type=bind,src=/path-on-host-machine/scripts/,dst=/docker-entrypoint-initdb.d/ \
-d mysql/mysql-server:tag

从另一个Docker容器中的应用程序连接到MySQL

   通过设置Docker网络,您可以允许多个Docker容器相互通信,以便另一个Docker容器中的客户端应用程序可以访问服务器容器中的MySQL Server。首先,创建一个Docker网络:

1
2
3
[root@docker-study ~]# docker network create my-custom-net
e78c79012d0e865acc06f043f03e9a900a5a478780fc0d7fb30a82ae0c644303
[root@docker-study ~]#

   然后,在创建和启动服务器和客户端容器时,使用该–network选项将它们放在您创建的网络上。例如:

1
2
3
4
5
[root@docker-study ~]# docker run --name=mysql2 --network=my-custom-net -d mysql/mysql-server:5.6
80415ae4ba16a3e89f3b7afc5d1f4ffde028fc65a66ff7f03810828070e6a17f
[root@docker-study ~]# docker run --name=web --network=my-custom-net -d httpd
264833168ac671eda95d0dd10547ce9bfa18bf83bc97531f85de202f72886088
[root@docker-study ~]#

  在mysql容器中设置web用户

1
2
3
4
5
mysql> create user web@172.19.0.3 identified by '123456';
Query OK, 0 rows affected (0.00 sec)

mysql> grant all privileges on *.* to web@172.19.0.3;
Query OK, 0 rows affected (0.00 sec)

   然后,web容器可以使用mysql2主机名连接到mysql2容器, 反之亦然,因为Docker会自动为给定的容器名称设置DNS。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@docker-study var]# docker exec -it web  mysql --host=mysql2 --user=web --password
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 37
Server version: 5.6.43 MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

服务器错误日志

   首次使用服务器容器启动MySQL服务器时, 如果满足以下任一条件,则不会生成服务器错误日志:

  • 已装入主机的服务器配置文件,但该文件不包含系统变量 log_error。
  • 尚未安装主机的服务器配置文件,但Docker环境变量 MYSQL_LOG_CONSOLE 是true(MySQL 5.6服务器容器的变量的默认状态false)。然后将MySQL服务器的错误日志重定向到 stderr,以便错误日志进入Docker容器的日志,并使用docker logs mysqld-container 命令查看 。

   要使MySQL Server在两个条件之一为真时生成错误日志,请使用该 –log-error 选项 ,配置服务器以在容器内的特定位置生成错误日志。要保留错误日志,请将主机文件挂载到容器内错误日志的位置,如上文中所述。但是必须确保其容器内的MySQL Server具有对挂载的主机文件有写访问权。

Docker环境变量

   创建MySQL Server容器时,可以使用–env选项(-e简而言之)配置MySQL实例,并指定以下一个或多个环境变量。

注意

   如果挂载的数据目录不为空,则以下变量都不会产生任何影响,因为之后不会尝试进行服务器初始化。在容器启动期间,不会修改文件夹中任何预先存在的内容,包括任何旧服务器设置。

   布尔变量包括 MYSQL_RANDOM_ROOT_PASSWORD, MYSQL_ONETIME_PASSWORD和MYSQL_ALLOW_EMPTY_PASSWORD, MYSQL_LOG_CONSOLE 通过使用任何非零长度的字符串设置它们来实现。
例如”0”,”false”或 “no”不会使它们为假,但实际上使它们成立。这是MySQL Server容器的已知问题。

  • MYSQL_RANDOM_ROOT_PASSWORD:当此变量为true(这是默认状态,除非 MYSQL_ROOT_PASSWORD 或MYSQL_ALLOW_EMPTY_PASSWORD 设置为true)时,将在启动Docker容器时生成服务器root用户的随机密码。密码打印到stdout容器中,可以通过查看容器的日志找到。
  • MYSQL_ONETIME_PASSWORD:当变量为true(这是默认状态,除非 MYSQL_ROOT_PASSWORD 已设置或MYSQL_ALLOW_EMPTY_PASSWORD 设置为true)时,root用户的密码设置为expired,必须先更改才能正常使用MySQL。
  • MYSQL_DATABASE:此变量允许指定要在镜像启动时创建的数据库的名称。如果用户名和密码均由 MYSQL_USER 和MYSQL_PASSWORD提供,创建用户并授予该数据库(对应于超级用户权限GRANT ALL)。指定的数据库由 CREATE DATABASE IF NOT EXIST语句创建,因此如果数据库已存在,则该变量无效。
  • MYSQL_USER, MYSQL_PASSWORD:这些变量结合使用来创建用户并设置该用户的密码,并为该用户授予该MYSQL_DATABASE 变量指定的数据库的超级用户权限 。MYSQL_USER 和 MYSQL_PASSWORD 用于创建用户,如果这两个变量没有设置,则忽略。如果两个变量都已设置但未设置 MYSQL_DATABASE ,则创建用户时没有任何权限。

注意

  没有必要使用这种机制创建root用户,这是MYSQL_ROOT_PASSWORD 和 MYSQL_RANDOM_ROOT_PASSWORD两种机制默认创建的,除非 MYSQL_ALLOW_EMPTY_PASSWORD = ture。

  • MYSQL_ROOT_HOST:默认情况下,MySQL会创建 ‘root‘@’localhost’帐户。此帐户只能从容器内部连接。要允许来自其他主机的根连接,请设置此环境变量。例如,该值 为172.17.0.1允许来自运行容器的主机的连接。该选项仅接受一个参数,但允许使用通配符(例如, MYSQL_ROOT_HOST=172...*或MYSQL_ROOT_HOST=%)。
  • MYSQL_LOG_CONSOLE:当变量为true(变量的MySQL 5.6服务器容器的默认状态为false)时,MySQL服务器的错误日志被重定向到 stderr,以便错误日志进入Docker容器的日志,并且可以使用docker logs mysqld-container 命令查看 。

注意

   如果已挂载主机的服务器配置文件,则该变量无效。
MYSQL_ROOT_PASSWORD:此变量指定为MySQL root帐户设置的密码。

警告

   在命令行上设置MySQL root用户密码是不安全的。作为显式指定密码的替代方法,可以使用容器文件路径为密码文件设置变量,然后从主机中装入包含容器文件路径密码的文件。这仍然不是很安全,因为密码文件的位置仍然暴露。最好使用默认设置, MYSQL_RANDOM_ROOT_PASSWORD=true 并且 MYSQL_ONETIME_PASSWORD=true。

  • MYSQL_ALLOW_EMPTY_PASSWORD。将其设置为true以允许使用root用户的空密码启动容器。

警告

   将此变量设置为true是不安全的,因为它会使MySQL实例完全不受保护,从而允许任何人获得完整的超级用户访问权限。最好使用默认设置, MYSQL_RANDOM_ROOT_PASSWORD=true 并且MYSQL_ONETIME_PASSWORD=true 。

------ end ------
0%