Documentation Home
MySQL 8.0 参考手册  / 第 2 章安装和升级 MySQL  / 2.5 在 Linux 上安装 MySQL  / 2.5.6 使用Docker在Linux上部署MySQL  /  2.5.6.2 更多关于使用 Docker 部署 MySQL 服务器的主题

2.5.6.2 更多关于使用 Docker 部署 MySQL 服务器的主题

笔记

mysql/mysql-server当必须指定时, 以下大多数示例命令都具有 Docker 映像存储库(例如docker pulldocker run命令);如果您的图像来自另一个存储库,请更改它——例如,将其替换 container-registry.oracle.com/mysql/enterprise-server 为从 Oracle Container Registry (OCR) 下载的 MySQL Enterprise Edition 图像,或mysql/enterprise-serverMy Oracle Support下载的 MySQL Enterprise Edition 图像。

为 Docker 优化的 MySQL 安装

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

  • 包含的二进制文件仅限于:

    • /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(仅适用于 MySQL 企业版 8.0)

    • /usr/sbin/mysqld

  • 所有二进制文件都被剥离;它们不包含调试信息。

配置 MySQL 服务器

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

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

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

配置MySQL Server的另一种方法是准备一个配置文件并将其挂载到容器内服务器配置文件的位置。有关详细信息,请参阅 持久化数据和配置更改

持久化数据和配置更改

Docker 容器原则上是短暂的,如果容器被删除或损坏,任何数据或配置都将丢失(参见 此处的讨论)。 Docker 卷提供了一种机制来保存在 Docker 容器内创建的数据。在初始化时,MySQL 服务器容器为服务器数据目录创建一个 Docker 卷。容器上docker inspect命令的 JSON 输出包含一个 Mount键,其值提供有关数据目录卷的信息:

$> 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 服务器容器并绑定挂载数据目录和服务器配置文件:

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。在以下示例中,我们 从容器内部运行mysqlmyapp1客户端以连接到mysql1其自己容器中的主机:

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

有关容器的其他网络技术,请参阅 Docker 文档中的 Docker 容器网络部分。

服务器错误日志

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

  • 来自主机的服务器配置文件已挂载,但该文件不包含系统变量 log_error(请参阅 有关绑定挂载服务器配置文件的 持久数据和配置更改)。

  • 来自主机的服务器配置文件尚未挂载,但 Docker 环境变量已挂载 MYSQL_LOG_CONSOLEtrue这是 MySQL 8.0 服务器容器变量的默认状态)。然后将 MySQL Server 的错误日志重定向到stderr,以便错误日志进入 Docker 容器的日志,并可以使用docker logs mysqld-container 命令查看。

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

将 MySQL 企业备份与 Docker 结合使用

MySQL Enterprise Backup是 MySQL Server 的商业许可备份实用程序,可用于 MySQL Enterprise Edition。MySQL Enterprise Backup 包含在 MySQL Enterprise Edition 的 Docker 安装中。

在以下示例中,我们假设您已经在 Docker 容器中运行了一个 MySQL 服务器( 有关如何使用 Docker 启动 MySQL 服务器实例,请参阅第 2.5.6.1 节“使用 Docker 部署 MySQL 服务器的基本步骤” )。对于备份 MySQL 服务器的 MySQL Enterprise Backup,它必须能够访问服务器的数据目录。例如,这可以通过 在启动服务器时 在 MySQL 服务器的数据目录上绑定挂载主机目录来实现:

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

使用此命令,MySQL 服务器以 MySQL 企业版的 Docker 映像启动,主机目录 /path-on-host-machine/datadir/已挂载到/var/lib/mysql服务器容器内的服务器数据目录 ( ) 中。我们还假设,在服务器启动后,MySQL Enterprise Backup 访问服务器所需的权限也已设置(有关详细信息,请参阅 向备份管理员授予 MySQL 权限)。使用以下步骤备份和还原 MySQL 服务器实例。

要使用带有 Docker 的 MySQL Enterprise Backup 备份在 Docker 容器中运行的 MySQL Server 实例,请按照此处列出的步骤操作:

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

    $> 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使用用于启动它的选项,在退出后将其删除。已经创建了镜像备份,可以在上一步挂载的用于存放备份的host目录下找到,如下所示:

    $> 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 Edition 的映像启动容器以使用 MySQL Enterprise Backup 命令执行还原 copy-back-and-apply-log。绑定挂载服务器的数据目录和备份的存储文件夹,就像我们备份服务器时所做的那样:

    $> 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 服务器,如下所示:

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

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

mysqldump与 Docker 结合使用

除了使用 MySQL Enterprise Backup 备份在 Docker 容器中运行的 MySQL 服务器外,您还可以使用mysqldump实用程序在 Docker 容器中运行 ,对服务器执行逻辑备份 。

以下说明假设您已经在 Docker 容器中运行了一个 MySQL 服务器,并且当容器首次启动时,主机目录 /path-on-host-machine/datadir/已挂载到服务器的数据目录 /var/lib/mysql(请参阅 绑定挂载主机目录到数据目录MySQL Server for details),其中包含 Unix 套接字文件,mysqldumpmysql可以通过该文件连接到服务器。我们还假设,在服务器启动后,已经创建了一个具有适当权限的用户(admin在本例中),mysqldump使用该用户可以访问服务器。使用以下步骤备份和恢复 MySQL 服务器数据:

使用带有 Docker的mysqldump备份 MySQL 服务器数据

  1. 在运行 MySQL Server 容器的同一主机上,启动另一个带有 MySQL Server 映像的容器,以使用 mysqldump实用程序执行备份(请参阅该实用程序的文档以了解其功能、选项和限制)。通过绑定挂载提供对服务器数据目录的访问 /path-on-host-machine/datadir/。此外,将主机目录(/path-on-host-machine/backups/ 在本例中)挂载到容器内的备份存储文件夹(/data/backups在本例中使用)以保留您正在创建的备份。以下是使用此设置备份服务器上所有数据库的示例命令:

    $> docker run --entrypoint "/bin/sh" \ 
    --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/mysql-server:8.0 \
    -c "mysqldump -uadmin --password='password' --all-databases > /data/backups/all-databases.sql"

    该命令中--entrypoint使用option使容器启动后调用系统shell,-coption用于指定在shell中运行mysqldump命令,输出重定向到all-databases.sql备份目录下的文件。

  2. 一旦备份作业完成,容器就会退出,并--rm使用用于启动它的选项,在退出后将其删除。逻辑备份已创建,可以在挂载用于存储备份的主机目录中找到,如下所示:

    $> ls /path-on-host-machine/backups/
    all-databases.sql

使用带有 Docker的mysqldump恢复 MySQL 服务器数据

  1. 确保您有一个在容器中运行的 MySQL 服务器,您希望将备份数据恢复到该容器中。

  2. 使用 MySQL 服务器的映像启动容器以使用mysql客户端执行恢复。绑定安装服务器的数据目录,以及包含备份的存储文件夹:

    $> 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/mysql-server:8.0 \
    mysql -uadmin --password='password' -e "source /data/backups/all-databases.sql"

    一旦备份作业完成,容器就会退出,并且--rm使用启动时使用的选项,在退出后将其删除。

  3. 登录到服务器以检查恢复的数据现在在服务器上。

已知的问题
Docker 环境变量

当您创建 MySQL 服务器容器时,您可以使用--env选项(简称-e)并指定一个或多个环境变量来配置 MySQL 实例。如果安装的数据目录不为空,则不会执行服务器初始化,在这种情况下,设置任何这些变量都无效(请参阅 持久数据和配置更改),并且在容器期间不会修改目录的现有内容,包括服务器设置启动。

此处列出了可用于配置 MySQL 实例的环境变量:

  • 布尔变量包括 MYSQL_RANDOM_ROOT_PASSWORDMYSQL_ONETIME_PASSWORDMYSQL_ALLOW_EMPTY_PASSWORDMYSQL_LOG_CONSOLE 通过使用非零长度的任何字符串设置它们来实现。因此,将它们设置为例如0falseno不会使它们为假,而是实际上使它们为真。这是一个已知的问题。

  • MYSQL_RANDOM_ROOT_PASSWORD:当这个变量为真时(这是它的默认状态,除非 MYSQL_ROOT_PASSWORD 被设置或被 MYSQL_ALLOW_EMPTY_PASSWORD 设置为真),在启动Docker容器时为服务器的root用户生成一个随机密码。密码打印到stdout容器中,可以通过查看容器的日志找到(请参阅启动 MySQL 服务器实例)。

  • MYSQL_ONETIME_PASSWORD:当该变量为true时(这是它的默认状态,除非 MYSQL_ROOT_PASSWORD 被设置或 MYSQL_ALLOW_EMPTY_PASSWORD 设置为true),root用户的密码被设置为过期,必须更改才能正常使用MySQL。

  • MYSQL_DATABASE:此变量允许您指定要在图像启动时创建的数据库的名称。如果使用 和 提供用户名和密码 MYSQL_USERMYSQL_PASSWORD则创建用户并授予超级用户访问该数据库的权限(对应于GRANT ALL)。指定的数据库由 CREATE DATABASE IF NOT EXIST语句创建,因此如果数据库已经存在,则该变量无效。

  • MYSQL_USER, MYSQL_PASSWORD: 这些变量结合使用来创建用户并设置该用户的密码,并且该用户被授予该 MYSQL_DATABASE 变量指定的数据库的超级用户权限。MYSQL_USER 和 都是 MYSQL_PASSWORD 创建用户所必需的——如果两个变量中的任何一个未设置,另一个将被忽略。如果两个变量都已设置但未设置 MYSQL_DATABASE ,则创建的用户没有任何权限。

    笔记

    不需要使用此机制来创建 root 超级用户,默认情况下,它是使用由 和 的描述中讨论的任一机制设置的密码创建的 MYSQL_ROOT_PASSWORDMYSQL_RANDOM_ROOT_PASSWORD除非 MYSQL_ALLOW_EMPTY_PASSWORD 是 true。

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

  • MYSQL_LOG_CONSOLE:当变量为 true(这是 MySQL 8.0 服务器容器的默认状态)时,MySQL 服务器的错误日志将重定向到stderr,这样错误日志就会进入 Docker 容器的日志,并且可以使用docker logs mysqld-container 命令查看。

    笔记

    如果已安装来自主机的服务器配置文件,则该变量无效(请参阅 有关绑定安装配置文件的 持久数据和配置更改)。

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

    警告

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

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

    警告

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