Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  More Topics on Deploying MySQL Server with Docker

2.5.6.2 Docker 部署 MySQL 服务器的更多主题

Note

以下大多数示例命令使用container-registry.oracle.com/mysql/community-server作为 Docker 镜像(如同使用docker pulldocker run命令);如果您的镜像来自其他存储库,请将其更改为container-registry.oracle.com/mysql/enterprise-server,用于从 Oracle 容器注册中心(OCR)下载的 MySQL Enterprise Edition 镜像,或者mysql/enterprise-server,用于从My Oracle Support下载的 MySQL Enterprise Edition 镜像。

MySQL 的 Docker 镜像经过优化,以便减少代码大小,仅包含大多数用户在 Docker 容器中运行 MySQL 实例所需的关键组件。与常见的非 Docker 安装不同的是:

  • 只包括有限数量的可执行文件。

  • 所有可执行文件都被删除;它们不包含调试信息。

Warning

用户对 Docker 容器(包括 MySQL 组件)进行软件更新或安装可能会与优化的 MySQL 安装冲突。Oracle 不提供对在这种已被修改容器中运行的 MySQL 产品或来自已被修改 Docker 镜像的容器提供支持。

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

docker run --name mysql1 -d container-registry.oracle.com/mysql/community-server:tag --character-set-server=utf8mb4 --collation-server=utf8mb4_col

命令启动 MySQL 服务器,以 utf8mb4 作为默认字符集和 utf8mb4_ col 作为默认排序规则。

另一种配置 MySQL 服务器的方法是准备一个配置文件,并将其挂载到容器内的服务器配置文件位置。请参阅 Persisting Data and Configuration Changes以获取详细信息。

Docker 容器本质上是临时的,任何数据或配置都将被删除或损坏(请参阅这里)。Docker 卷提供了一个机制来 persist 数据创建在 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,在主机上 persist 数据的目录,已经被挂载到容器内的服务器数据目录/var/lib/mysql中。

另一种方式是使用bind-mount将主机目录绑定到容器中,使用--mount选项创建容器。同样,可以用于 persist 服务器配置文件。以下命令创建了一个 MySQL Server 容器,并 bind- mounted 数据目录和服务器配置文件:

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 container-registry.oracle.com/mysql/community-server:tag

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

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

    [mysqld]
    user=mysql

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

  • 数据目录path-on-host-machine/datadir必须已经存在。为了服务器初始化,可以将目录设置为空。您也可以将预先填充了数据的目录 mount 到容器中,并使用该目录启动服务器;但是,您必须确保在启动容器时使用与创建数据的服务器相同的配置,并且所有主机文件或目录都被mount 到容器中。

如果您想在数据库创建后立即运行的.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 container-registry.oracle.com/mysql/community-server:tag

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

docker network create my-custom-net

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

docker run --name=mysql1 --network=my-custom-net -d container-registry.oracle.com/mysql/community-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

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

当 MySQL 服务器首次启动时,如果满足以下任何一个条件,server error log将不会生成:

  • 主机上的服务器配置文件已经挂载,但是该文件不包含系统变量log_error(请参阅 Persisting Data and Configuration Changes关于挂载服务器配置文件的详细信息)。

  • 主机上的服务器配置文件没有被挂载,但是 Docker 环境变量MYSQL_LOG_CONSOLEtrue(这是 MySQL 8.4 服务器容器的默认状态),MySQL Server 的错误日志将被重定向到stderr,因此错误日志将出现在 Docker 容器的日志中,可以使用docker logs mysqld-container命令查看。

要使 MySQL Server 在满足任何一个条件时生成错误日志,请使用--log-error选项来配置服务器,以便在容器内的特定位置生成错误日志。要 persist 错误日志,挂载主机文件到容器内错误日志的位置,如 Persisting Data and Configuration Changes中所述。然而,您必须确保 MySQL Server 内容器中的写入权限。

MySQL企业备份是MySQL Server的商业许可证备份工具,仅在MySQL Enterprise Edition中提供。 MySQL Enterprise Backup也包含在MySQL Enterprise Edition Docker安装中。

以下示例假设您已经在Docker容器中启动了MySQL Server(请参阅第2.5.6.1节,“基本步骤:使用Docker部署MySQL Server”,了解如何使用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.4

使用以下命令,MySQL Server将使用MySQL Enterprise Edition Docker映像启动,并将主机目录/path-on-host-machine/datadir/挂载到服务器容器中的数据目录(/var/lib/mysql)内。我们还假设,服务器已经启动后,MySQL Enterprise Backup也已经设置了所需的权限来访问服务器(请参阅Grant MySQL Privileges to Backup Administrator,了解详细信息)。使用以下步骤备份和恢复MySQL Server实例。

使用 Docker 中的 MySQL Enterprise Backup 将 MySQL 服务器实例备份,按照以下步骤操作:

  1. 在 MySQL 服务器容器运行的同一主机上,启动另一个容器,以使用 MySQL Enterprise Backup 命令backup-to-image进行备份。提供对服务器数据目录的访问,使用我们在上一步创建的 bind 挂载。同时,将主机目录(例如:/path-on-host-machine/backups/)挂载到容器中的存储备份文件夹(例如:/data/backups)以 persist 创建的备份。以下是一个 sample 命令,使用 Docker 映像从My Oracle Support下载 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.4 \
    mysqlbackup -umysqlbackup -ppassword --backup-dir=/tmp/backup-tmp --with-timestamp \
    --backup-image=/data/backups/db.mbi backup-to-image

    重要的是,在mysqlbackup输出的末尾检查,以确保备份已经成功完成。

  2. 容器在备份作业完成后退出,并且使用--rm选项启动它,它将在退出时被删除。一个图像备份已经创建,位于上一步中用于存储备份的主机目录中,如下所示:

    $> ls /tmp/backups
    db.mbi

使用 MySQL Enterprise Backup with Docker 将 MySQL 服务器实例恢复到 Docker 容器中,按照以下步骤操作:

  1. 停止 MySQL 服务器容器,这也将停止运行在其中的 MySQL 服务器:

    docker stop mysqlserver
  2. 在主机上,删除 MySQL 服务器数据目录 bind 挂载中的所有内容:

    rm -rf /path-on-host-machine/datadir/*
  3. 使用 MySQL Enterprise Edition 的图像启动一个容器,使用 MySQL Enterprise Backup 命令copy-back-and-apply-log 进行恢复。将服务器的数据目录和备份存储文件夹绑定-mount,类似于我们在备份服务器时所做的:

    $> 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.4 \
    mysqlbackup --backup-dir=/tmp/backup-tmp --with-timestamp \
    --datadir=/var/lib/mysql --backup-image=/data/backups/db.mbi copy-back-and-apply-log
    
    mysqlbackup completed OK! with 3 warnings

    容器退出后显示“mysqlbackup completed OK!”消息,一旦备份作业完成,并且使用了 --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.4

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

除了使用 MySQL Enterprise Backup 将 MySQL 服务器在 Docker 容器中备份之外,您还可以使用mysqldump实用工具在 Docker 容器中执行逻辑备份。

以下步骤假设您已经在 Docker 容器中运行了 MySQL 服务器,并且在容器启动时,将主机目录/path-on-host-machine/datadir/挂载到服务器的数据目录/var/lib/mysql中(请参阅在 MySQL 服务器上 bind-mount 主机目录的详细信息),该目录包含 Unix 套接字文件,用于mysqldumpmysql连接到服务器。我们还假设,在服务器启动后,一名拥有合适权限(在本例中为admin)的用户已经被创建,以便mysqldump可以访问服务器。使用以下步骤备份和恢复 MySQL 服务器数据:

使用 Docker 将 MySQL 服务器数据备份到mysqldump:

  1. 在 MySQL Server 容器运行的同一主机上,启动另一个容器,以使用mysqldump实用工具(见实用工具的文档、选项和限制)进行备份。将服务器的数据目录提供给容器,通过 bind 挂载/path-on-host-machine/datadir/。同时,将主机目录(/path-on-host-machine/backups/在本例中)挂载到容器中的备份存储文件夹(/data/backups在本例中),以 persistently 保存您创建的备份。以下是一个使用该设置备份所有服务器数据库的示例命令:

    $> 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 container-registry.oracle.com/mysql/community-server:8.4 \
    -c "mysqldump -uadmin --password='password' --all-databases > /data/backups/all-databases.sql"

    在命令中,使用--entrypoint选项,以便在容器启动后invoke系统shell,并使用-c选项指定mysqldump命令在shell中运行,输出重定向到文件all-databases.sql在备份目录中。

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

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

使用mysqldump Docker 进行 MySQL Server 数据恢复:

  1. 确保您已经启动了一个MySQL Server容器,用于将备份数据恢复到其中。

  2. 使用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 container-registry.oracle.com/mysql/community-server:8.4 \
    mysql -uadmin --password='password' -e "source /data/backups/all-databases.sql"

    容器在备份任务完成后退出,并且使用--rm选项启动时,它将在退出后被删除。

  3. 登录服务器以检查恢复后的数据现在是否已经在服务器上。

  • 使用服务器系统变量audit_log_file配置审核日志文件名时,使用loose选项修饰符;否则,Docker无法启动服务器。

Docker 环境变量

当您创建一个MySQL Server容器时,可以使用--env选项(简写为-e)和指定一个或多个环境变量来配置MySQL实例。如果已mounted的数据目录不为空,服务器将不会初始化,在这种情况下设置这些变量没有效果(请参阅 Persisting Data and Configuration Changes),并且在容器启动时不会修改目录中的任何内容,包括服务器设置。

可以用于配置MySQL实例的环境变量列表如下:

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

  • MYSQL_RANDOM_ROOT_PASSWORD:当这个变量为真(除非MYSQL_ROOT_PASSWORD被设置或MYSQL_ALLOW_EMPTY_PASSWORD被设置为真)时,Docker容器启动时将生成服务器的root用户随机密码。密码将被打印到容器的stdout中,可以在容器的日志中找到(见Starting a MySQL Server Instance)。

  • MYSQL_ONETIME_PASSWORD: 当变量为真(除非MYSQL_ROOT_PASSWORDMYSQL_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_USERMYSQL_PASSWORD都需要设置,以创建用户—if任何一个变量未设置,另一个将被忽略。如果两个变量都设置,但MYSQL_DATABASE未设置,则用户将被创建无权限。

    Note

    不需要使用这个机制来创建root超级用户,因为root超级用户默认情况下由一个或多个机制(如MYSQL_ROOT_PASSWORDMYSQL_RANDOM_ROOT_PASSWORD)创建,除非MYSQL_ALLOW_EMPTY_PASSWORD为true。

  • MYSQL_ROOT_HOST: 默认情况下,MySQL 创建了 'root'@'localhost' 帐户。这个帐户只能从容器内部连接,如Connecting to MySQL Server from within the Container中所述。要允许来自其他主机的 root 连接,设置这个环境变量。例如,值 172.17.0.1 允许来自运行容器的主机的连接。该选项只接受一个入口,但允许使用通配符(例如 MYSQL_ROOT_HOST=172.*.*.*MYSQL_ROOT_HOST=%)。

  • MYSQL_LOG_CONSOLE: 当变量为 true(MySQL 8.4 服务器容器的默认状态)时,MySQL Server 的错误日志将被重定向到 stderr,因此错误日志将出现在 Docker 容器的日志中,可以使用docker logs mysqld-container 命令查看。

    Note

    如果从主机挂载了服务器配置文件(见Persisting Data and Configuration Changes关于 bind-mounting 配置文件),那么变量将无效。

  • MYSQL_ROOT_PASSWORD: 设置 MySQL root 账户的密码。

    Warning

    在命令行中设置 MySQL root 用户密码不安全。相反,您可以将变量设置为容器文件路径,以便存储密码文件,然后在容器文件路径下挂载主机上的文件,该文件包含密码。这仍然不是很安全,因为密码文件的位置仍然暴露出来。更好的选择是使用默认设置,MYSQL_RANDOM_ROOT_PASSWORDMYSQL_ONETIME_PASSWORD 都设置为 true。

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

    Warning

    将变量设置为 true 是不安全的,因为这将使您的 MySQL 实例完全无保护,任何人都可以获得超级用户访问权限。更好的选择是使用默认设置,MYSQL_RANDOM_ROOT_PASSWORDMYSQL_ONETIME_PASSWORD 都设置为 true。