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

2.5.7.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/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 volumes提供了一种机制来保存在 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_CONSOLEtrueMySQL 5.7 服务器容器的变量默认状态为 false)。然后将 MySQL Server 的错误日志重定向到stderr,以便错误日志进入 Docker 容器的日志,并可以使用docker logs mysqld-container 命令查看。

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

已知的问题
  • 在使用server系统变量 audit_log_file配置审计日志文件名时,使用loose option修饰符,否则Docker将无法启动服务器。

Docker 环境变量

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

笔记
  • 如果您挂载的数据目录不为空,则以下变量均无效,因为届时将不会尝试进行服务器初始化(有关更多详细信息,请参阅 持久数据和配置更改 )。文件夹中任何预先存在的内容,包括任何旧的服务器设置,在容器启动期间都不会被修改。

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

  • 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:当变量为真时(MySQL 5.7 服务器容器变量的默认状态为 false),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 两者都为真。