Docker之十九: 使用 Docker 在 Linux上 部署 MySQL

Docker之十九: 使用 Docker 在 Linux上 部署 MySQL

  • 使用 Docker 部署 MySQL Server 的基本步骤
    • 下载 MySQL Server 镜像
      • 下载 MySQL Community Edition 镜像
      • 下载 MySQL Enterprise Edition 镜像
    • 启动 MySQL Server 实例
    • 从容器内连接到 MySQL Server
    • 进入容器命令
    • 停止或删除 Mysql 容器
    • 升级 MySQL Server 容器
  • 有关使用 Docker 部署 MySQL Server 的更多主题
    • 针对 Docker 的优化 MySQL 安装
    • 配置 MySQL Server
    • 持久化数据和配置更改
    • 运行其他初始化脚本
    • 从另一个 Docker 容器中的应用程序连接到 MySQL
    • 服务器错误日志
    • 将 MySQL Enterprise Backup 与Docker配合使用
    • 已知问题
    • Docker 环境变量
  • 使用Docker在Windows和其他非Linux平台上部署MySQL

使用 Docker 部署 MySQL Server 的基本步骤

MySQL Docker 镜像是专门为 Linux 平台构建的。其他平台不受支持,用户在这些平台上使用 MySQL Docker 镜像是有风险的。

下载 MySQL Server 镜像

下载 MySQL Community Edition 镜像

docker pull mysql/mysql-server:tag

下载 MySQL Enterprise Edition 镜像

要下载 MySQL Enterprise Edition 映像,请访问 My Oracle Support 网站,登录到您的 Oracle 帐户,然后在登录页上执行以下步骤:

  • 选择 Patches and Updates 选项卡。
  • 选择 Patch Search -> Search -> Product or Family (Advanced)
  • Product 字段中输入“MySQL Server“,在 Release 字段中输入所需要的版本号。
  • 使用其他过滤器的下拉列表选择 Descriptioncontains,然后在文本字段中输入”Docker“。
  • 单击 search 按钮,然后从结果列表中选择所需的版本,然后单击 ***Download***按钮。
  • 在出现的文件下载对话框中,单击并下载 Docker 映像的 .zip 文件。
    Docker之十九: 使用 Docker 在 Linux上 部署 MySQL_第1张图片
    解压下载的 .zip 压缩包以获得其中的 mysql-enterprise-server-version.tar,然后执行下面的命令加载镜像:
docker load -i mysql-enterprise-server-version.tar

加载完成后,查看镜像:

shell> docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
mysql/mysql-server   latest              3157d7f55f8d        4 weeks ago         241MB

启动 MySQL Server 实例

为 MySQL Server 启动新的 Docker 容器,请使用以下命令:

docker run --name=container_name  --restart on-failure -d image_name:tag
# --name=container_name 自定义容器名称
# --restart on-failure 设置 Mysql Server 的重启策略 on-failure

实例:

docker run --name=mysql1 --restart on-failure -d mysql/enterprise-server:8.0

查看 Mysql 容器运行状态:

docker ps

监视 Mysql 后台容器输出:

docker logs mysql1

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

shell> docker logs mysql1 2>&1 | grep GENERATED
GENERATED ROOT PASSWORD: Axegh3kAJyDLaRuBemecis&EShOs

从容器内连接到 MySQL Server

一旦服务器准备就绪,您就可以在刚刚启动的 MySQL Server 容器中运行 MySQL 客户端,并将其连接到 MySQL Server。使用 docker exec-it 命令在您已经启动的 Docker 容器中启动 MySQL 客户端,如下所示:

docker exec -it mysql1 mysql -uroot -p

系统提示时,输入生成的 root 密码。由于 MYSQL_ONETIME_PASSWORD 选项在默认情况下为 TRUE,因此在将 MySQL 客户端连接到服务器后,必须通过发出以下语句来重置服务器根密码:

mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'password';

进入容器命令

shell> docker exec -it mysql1 bash
bash-4.2#

停止或删除 Mysql 容器

# 停止 MySQL Server 容器
docker stop mysql1
# 开启 MySQL Server 容器
docker start mysql1
# 重启 MySQL Server 容器
docker restart mysql1

# 删除 MySQL Server 容器,先停止,再删除
docker stop mysql1
docker rm mysql1

# 如果希望同时删除服务器数据目录的 Docke r卷,请在 docker rm 命令中添加 -v 选项。

升级 MySQL Server 容器

本节我们将讨论当服务器的数据和配置已保存在主机上,如何升级 Mysql。

按照以下步骤将 Docker 安装的 MySQL 5.7 升级到 8.0

  • 停止 MySQL 5.7 服务器(本例中容器名称为 mysql57):

    docker stop mysql57
    
  • 下载 MySQL 8.0 Server Docker 镜像。

  • 启动一个新的 MySQL 8.0 Docker 容器(在本例中名为 mysql80),并使用主机上保存的旧服务器数据和配置:

    docker run --name=mysql80 \
       --mount type=bind,src=/path-on-host-machine/my.cnf,dst=/etc/my.cnf \
       --mount type=bind,src=/path-on-host-machine/datadir,dst=/var/lib/mysql \
       -d mysql/mysql-server:8.0
    

    如果需要,请将 mysql/mysql-server 调整为正确的存储库名称-例如,将其替换为从 My Oracle Support 下载的 MySQL/Enterprise-server for MySQL Enterprise Edition 映像。

  • 等待服务器完成启动。您可以使用 docker ps 命令检查服务器的状态。

  • 对于 MySQL 8.0.15 和更低版本:在 MySQL 8.0 服务器容器中运行 MySQL_Upgrade 程序(MySQL 8.0.16 和更高版本不需要):

    docker exec -it mysql80 mysql_upgrade -uroot -p
    

    出现提示时,输入旧 MySQL5.7 服务器的超级用户密码。

  • 通过重新启动MySQL 8.0服务器容器完成升级:

    docker restart mysql80
    

有关使用 Docker 部署 MySQL Server 的更多主题

针对 Docker 的优化 MySQL 安装

MySQL的Docker镜像针对代码大小进行了优化,这意味着它们只包含预计与在Docker容器中运行MySQL实例的大多数用户相关的关键组件。MySQL Docker安装与普通的非Docker安装在以下方面不同:

  • Included binaries are limited to:

    • /usr/bin/my_print_defaults
    • /usr/bin/mysql
    • /usr/bin/mysql_config
    • /usr/bin/mysql_install_db
    • /usr/bin/mysql_tzinfo_to_sql
    • /usr/bin/mysql_upgrade
    • /usr/bin/mysqladmin
    • /usr/bin/mysqlcheck
    • /usr/bin/mysqldump
    • /usr/bin/mysqlpump
    • /usr/bin/mysqlbackup (for MySQL Enterprise Edition 8.0 only)
    • /usr/sbin/mysqld
  • All binaries are stripped; they contain no debug information.

配置 MySQL Server

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

docker run --name mysql1 -d mysql/mysql-server:tag --character-set-server=utf8mb4 --collation-server=utf8mb4_col

该命令启动 MySQL Server 时,将 utf8mb4 作为默认字符集,utf8mb4_ol 作为数据库的默认排序规则。

配置 MySQL Server 的另一种方法是准备一个配置文件,并将其挂载到容器内服务器配置文件的位置。具体方法参考下一节”持久化数据和配置更改“。

持久化数据和配置更改

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

shell> docker inspect mysql1
...
 "Mounts": [
            {
                "Type": "volume",
                "Name": "4f2d463cfc4bdd4baebcb098c97d7da3337195ed2c6572bc0b89f7e845d27652",
                "Source": "/var/lib/docker/volumes/4f2d463cfc4bdd4baebcb098c97d7da3337195ed2c6572bc0b89f7e845d27652/_data",
                "Destination": "/var/lib/mysql",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
...

输出显示,在主机上持久化数据的源文件夹 /var/lib/docker/volumes/4f2d463cfc4bdd4baebcb098c97d7da3337195ed2c6572bc0b89f7e845d27652/_data,已经挂载在容器内的服务器数据目录 /var/lib/mysql 中。

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

docker run --name=mysql1 \
	--mount type=bind,src=/path-on-host-machine/my.cnf,dst=/etc/my.cnf \
	--mount type=bind,src=/path-on-host-machine/datadir,dst=/var/lib/mysql \
	-d mysql/mysql-server:tag

该命令将 path-on-host-machine/my.cnf 挂载到 /etc/my.cnf (容器内的服务器配置文件),将 path-on-host-machine/datadir 挂载到 /var/lib/mysql(容器内的数据目录)。要使绑定安装正常工作,必须满足以下条件:

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

    [mysqld]
    user=mysql
    

    您还可以在该文件中包含其他服务器配置选项。

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

运行其他初始化脚本

如果您希望在创建数据库后立即在数据库上运行任何 .sh.sql 脚本,可以将它们放入主机目录中,然后在容器内的 /docker-entrypoint-initdb.d/ 挂载该目录。例如:

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 网络:

docker network create my-custom-net

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

docker run --name=mysql1 --network=my-custom-net -d mysql/mysql-server
docker run --name=myapp1 --network=my-custom-net -d myapp

然后,myapp1 容器可以使用 mysql1 主机名连接到 mysql1 容器,反之亦然,因为 Docker 会自动为给定的容器名称设置 DNS。在下面的示例中,我们从 myapp1 容器内部运行 MySQL 客户端,以连接到自己容器中的主机 mysql1

docker exec -it myapp1 mysql --host=mysql1 --user=myuser --password

服务器错误日志

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

  • 已挂载来自主机的服务器配置文件,但该文件不包含系统变量 LOG_ERROR。
  • 尚未装载主机中的服务器配置文件,但 Docker 环境变量 MYSQL_LOG_CONSOLETRUE(这是该变量在 MySQL 8.0 服务器容器中的默认状态)。然后,MySQL Server 的错误日志被重定向到 stderr,以便错误日志进入 Docker 容器的日志,并可使用 docker logs mysqld-tainer 命令查看。

要使 MySQL Server 在这两个条件之一为真时生成错误日志,请使用 –log-error 选项将服务器配置为在容器内的特定位置生成错误日志。要持久化错误日志,请按照持久化数据和配置更改中的说明,在容器内的错误日志位置装载主机文件。但是,您必须确保其容器内的 MySQL Server 对挂载的主机文件具有写入权限。

将 MySQL Enterprise Backup 与Docker配合使用

MySQL Enterprise BackupMySQL Server 的商业许可备份实用程序,随 MySQL Enterprise Edition 提供。MySQL Enterprise Backup 包含在 MySQL Enterprise EditionDocker 安装中。

在下面的示例中,我们假设您已经在Docker容器中运行了 MySQL Server。要让 MySQL Enterprise Backup 备份 MySQL Server,它必须有权访问服务器的数据目录。例如,这可以通过在启动服务器时在 MySQL Server 的数据目录上绑定挂载主机目录来实现:

docker run --name=mysqlserver \
	--mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \
	-d mysql/enterprise-server:8.0

使用该命令,MySQL Server 使用 MySQL Enterprise EditionDocker 映像启动,并且主机目录 /path-on-host-machine/datadir/ 已经挂载到服务器容器内的服务器数据目录(/var/lib/mysql)上。我们还假设在服务器启动后,还设置了 MySQL Enterprise Backup 访问服务器所需的权限。然后使用以下步骤备份和恢复 MySQL Server 实例。

要使用MySQL Enterprise Backup with Docker备份在Docker容器中运行的MySQL Server实例,请执行以下操作:

  1. 在运行 MySQL Server 容器的同一主机上,使用 MySQL Enterprise Edition 的映像启动另一个容器,以使用 MySQL Enterprise Backup 命令 BACKUP-TO-IMAGE执行备份。使用我们在上一步中创建的绑定挂载提供对服务器数据目录的访问。另外,将主机目录(在本例中为 /path-on-host-machine/backups/)挂载到容器中用于备份的存储文件夹(在本例中为 /data/backups),以持久化我们正在创建的备份。以下是此步骤的示例命令,其中 MySQL Enterprise Backup 使用从 My Oracle Support 下载的 Docker 映像启动):

    shell> docker run \
    	--mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \
    	--mount type=bind,src=/path-on-host-machine/backups/,dst=/data/backups \
    	--rm mysql/enterprise-server:8.0 \
    	mysqlbackup -umysqlbackup -ppassword --backup-dir=/tmp/backup-tmp --with-timestamp \
    	--backup-image=/data/backups/db.mbi backup-to-image
    
    [Entrypoint] MySQL Docker Image 8.0.11-1.1.5
    MySQL Enterprise Backup version 8.0.11 Linux-4.1.12-61.1.16.el7uek.x86_64-x86_64 [2018-04-08  07:06:45]
    Copyright (c) 2003, 2018, Oracle and/or its affiliates. All Rights Reserved.
    
    180921 17:27:25 MAIN    INFO: A thread created with Id '140594390935680'
    180921 17:27:25 MAIN    INFO: Starting with following command line ...
    ...
    
    -------------------------------------------------------------
       Parameters Summary
    -------------------------------------------------------------
       Start LSN                  : 29615616
       End LSN                    : 29651854
    -------------------------------------------------------------
    
    mysqlbackup completed OK!
    

    通过 mysqlbackup 检查输出的末尾,以确保备份已成功完成,这一点很重要。

  2. 备份作业完成后,容器将退出,使用 –rm 选项启动它,退出后将其删除。已经创建了映像备份,可以在上一步挂载的用于存储备份的主机目录中找到:

    shell> ls /tmp/backups
    db.mbi
    

要使用带有 Docker 的 MySQL Enterprise Backup 还原 Docker 容器中的 MySQL Server 实例,请执行以下操作:

  1. 停止MySQL Server容器,这也会停止MySQL Server在其中运行:

    docker stop mysqlserver
    
  2. 在主机上,删除MySQL Server数据目录的绑定装载中的所有内容:

    rm -rf /path-on-host-machine/datadir/*
    
  3. 使用 MySQL Enterprise Backup 命令 copy-back-and-apply-log 启动包含 MySQL Enterprise Edition 映像的容器以执行恢复。绑定-装载服务器的数据目录和备份的存储文件夹,就像我们备份服务器时所做的那样:

    shell> docker run \
    	--mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \
    	--mount type=bind,src=/path-on-host-machine/backups/,dst=/data/backups \
    	--rm mysql/enterprise-server:8.0 \
    	mysqlbackup --backup-dir=/tmp/backup-tmp --with-timestamp \
    	--datadir=/var/lib/mysql --backup-image=/data/backups/db.mbi copy-back-and-apply-log
    
    [Entrypoint] MySQL Docker Image 8.0.11-1.1.5
    MySQL Enterprise Backup version 8.0.11 Linux-4.1.12-61.1.16.el7uek.x86_64-x86_64 [2018-04-08  07:06:45]
    Copyright (c) 2003, 2018, Oracle and/or its affiliates. All Rights Reserved.
    
    180921 22:06:52 MAIN    INFO: A thread created with Id '139768047519872'
    180921 22:06:52 MAIN    INFO: Starting with following command line ...
    ...
    180921 22:06:52 PCR1    INFO: We were able to parse ibbackup_logfile up to
              lsn 29680612.
    180921 22:06:52 PCR1    INFO: Last MySQL binlog file position 0 155, file name binlog.000003
    180921 22:06:52 PCR1    INFO: The first data file is '/var/lib/mysql/ibdata1'
                                  and the new created log files are at '/var/lib/mysql'
    180921 22:06:52 MAIN    INFO: No Keyring file to process.
    180921 22:06:52 MAIN    INFO: Apply-log operation completed successfully.
    180921 22:06:52 MAIN    INFO: Full Backup has been restored successfully.
    
    mysqlbackup completed OK! with 3 warnings
    

    备份作业完成后,容器将退出,在启动容器时使用 –rm 选项,在退出后将其删除。

  4. 重新启动服务器容器,这也会重新启动恢复的服务器:

    docker restart mysqlserver
    

    或者,在还原的数据目录上启动新的MySQL Server:

    docker run --name=mysqlserver2 \
    	--mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \
    	-d mysql/enterprise-server:8.0
    

    登录到服务器以检查服务器是否正在使用还原的数据运行。

已知问题

使用服务器系统变量 audit_log_file 配置审计日志文件名时,请将 loose option 修饰符与其配合使用,否则 Docker 将无法启动服务器。

Docker 环境变量

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

  • 如果您挂载的数据目录不是空的,下面的变量都不会有任何影响,因为那时不会尝试服务器初始化。在容器启动期间,不会修改文件夹中的任何预先存在的内容,包括任何旧的服务器设置。
  • 包括 MYSQL_RANDOM_ROOT_PASSWORD、MYSQL_ONIME_PASSWORD、MYSQL_ALLOW_EMPTY_PASSWORD 和 MYSQL_LOG_CONSOLE 在内的布尔变量通过使用任意非零长度的字符串设置为真。因此,例如,将它们设置为“0”、“false”或“no”并不会使其为假,而实际上会使其为真。
  • MYSQL_RANDOM_ROOT_PASSWORD当该变量为 TRUE(默认状态,除非设置了 MYSQL_ROOT_PASSWORD 或 MYSQL_ALLOW_EMPTY_PASSWORD 为TRUE),启动Docker容器时会为服务器的 root 用户随机生成密码。密码被打印到容器的 stdout 中,可以通过查看容器的日志找到该密码。

  • MYSQL_ONE TIME_PASSWORD当变量为 TRUE 时(这是其默认状态,除非设置了 MYSQL_ROOT_PASSWORD 或 MYSQL_ALLOW_EMPTY_PASSWORD 设置为 TRUE),则 root 用户的密码设置为过期,必须更改才能正常使用 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,则创建用户时没有任何权限。

    Note

    无需使用此机制创建超级用户,除非 MYSQL_ALLOW_EMPTY_PASSWORD 为 TRUE,否则默认情况下会使用 MYSQL_ROOT_PASSWORD 和MYSQL_RANDOM_ROOT_PASSWORD 中的任何一种机制设置密码来创建超级用户。

  • MYSQL_ROOT_HOST默认情况下,MySQL 创建 ‘root’@‘localhost’ 帐户。此帐户只能从容器内部连接,如从容器内连接到 MySQL Server 中所述。要允许来自其他主机的根连接,请设置此环境变量。例如,值 172.17.0.1 是默认的 Docker 网关 IP,允许从运行容器的主机进行连接。该选项只接受一个条目,但允许使用通配符(例如,MYSQL_ROOT_HOST=172.* 或 MYSQL_ROOT_HOST=%)。

  • MYSQL_LOG_CONSOLE当变量为 TRUE 时(这是 MySQL 8.0 服务器容器的默认状态),MySQL Server 的错误日志被重定向到 stderr,以便错误日志进入Docker 容器的日志,并且可以使用 docker logs mysqld-taine r命令查看。

    Note

    如果已挂载来自主机的服务器配置文件,则该变量不起作用.

  • MYSQL_ROOT_PASSWORD该变量指定为 MySQL root 帐户设置的密码。

    Warning

    在命令行上设置 MySQL root 用户密码是不安全的。作为显式指定密码的替代方法,您可以使用密码文件的容器文件路径设置变量,然后在容器文件路径下从主机挂载包含密码的文件。这仍然不是很安全,因为密码文件的位置仍然是暴露的。最好使用 MYSQL_RANDOM_ROOT_PASSWORD 和MYSQL_ONAME_TIME_PASSWORD,两者的默认设置均为 true。

  • MySQL_ALLOW_EMPTY_PASSWORD将其设置为 true 可允许使用根用户的空密码启动容器。

    Warning

    将此变量设置为 TRUE 是不安全的,因为它将使您的 MySQL 实例完全不受保护,从而允许任何人获得完全的超级用户访问权限。最好使用MYSQL_RANDOM_ROOT_PASSWORD 和 MYSQL_ONAME_TIME_PASSWORD, 两者的默认设置均为true。

使用Docker在Windows和其他非Linux平台上部署MySQL

Warning

Oracle提供的MySQL Docker镜像是专门为Linux平台构建的。其他平台不受支持,在这些平台上运行Oracle中的MySQL Docker映像的用户要自负风险。本节讨论在非Linux平台上使用这些映像时的一些已知问题。

在 Windows 上使用 Oracle 中的 MySQL Server Docker 映像的已知问题包括:

  • 如果要绑定挂载到容器的 MySQL 数据目录上,则必须使用 –socket 选项将服务器套接字文件的位置设置为 MySQL 数据目录之外的某个位置;否则,服务器将无法启动。这是因为 Docker for Windows 处理文件装载的方式不允许将主机文件绑定装载到套接字文件上。

你可能感兴趣的:(Docker,mysql,docker)