第12章 Docker 中 MySQL 的安装与配置

第12章 Docker 中 MySQL 的安装与配置

前言

  • 为什么要使用 MySQL?

请访问官方网址了解www.mysql.com.

  • 什么是 MySQL?

MySQL是世界上最流行的开源数据库。凭借其久经考验的性能,可靠性和易用性,MySQL已成为基于Web的应用程序的领先数据库选择,涵盖从个人项目和网站,电子商务和信息服务到高知名度的整个范围。网站属性包括Facebook,Twitter,YouTube,Yahoo!还有很多。

有关MySQL Server和其他MySQL产品的更多信息和相关下载,请访问www.mysql.com.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R3rBDtwe-1599611781370)(assets/logo.png)]

  • 什么是 Docker?

具体请参考我的第08章内容。

  • 为什么要在 Docker 中安装 MySQL?

为了开发环境一致性、可移植性、易于管理和维护性。

目标

  • 完成 MySQL 在 Docker 中的安装与配置。
  • 安装在 Docker 中的 MySQL 能正常对外提供服务。
  • 在外部开发环境中能正常访问和使用 MySQL 服务。

环境

  • **VMware:**VMware Workstation 14 Pro
  • **Linux:**CentOS7.4
  • **Docker:**18.06.0-ce, build 0ffa825
  • **MySQL: **5.7.23
  • **JDK:**jdk1.8.0_172

支持的不同版本 Tag 和相应的Dockerfile链接

安装

MySQL是一种广泛使用的开源关系数据库管理系统(RDBMS)。

如何使用镜像安装?

查找可安装对镜像

$ sudo docker search mysql

下载镜像

$ sudo docker pull mysql:5.7.23

启动一个mysql服务器实例

$ sudo docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

$ sudo docker run --name mysql -p 3306:3306 -d konylrs/mysql:5.7.23

… some-mysql是要分配给容器的名称,my-secret-pw是为MySQL root用户设置的密码,tag是指定所需MySQL版本的标记。请参阅上面的列表以获取相关标签。

启动一个带数据卷对mysql服务器容器实例

$ sudo docker volume create --name mysql-datadir
$ sudo docker run -d --name mysql -p 3306:3306 -v /var/lib/docker/volumes/mysql-datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=mysql123 -d mysql:5.7.23

命令的-v /my/own/datadir:/var/lib/mysql部分将/my/own/datadir目录从底层主机系统挂载到容器内的/var/lib/mysql,默认情况下MySQL将写它的数据文件。

请注意,启用了SELinux的主机系统上的用户可能会遇到此问题。当前的解决方法是将相关的SELinux策略类型分配给新数据目录,以便允许容器访问它:

$ sudo chcon -Rt svirt_sandbox_file_t /var/lib/docker/volumes/mysql-datadir

打开访问端口

$ sudo firewall-cmd --zone=public --add-port=3306/tcp --permanent 
## 重启防火墙
$ sudo firewall-cmd --reload 
$ sudo firewall-cmd --list-port

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

此镜像公开标准MySQL端口(3306),因此容器链接使MySQL实例可用于其他应用程序容器。像这样启动你的应用程序容器,以便将它链接到MySQL容器:

$ docker run --name some-app --link some-mysql:mysql -d application-that-uses-mysql

从MySQL命令行客户端连接到MySQL

以下命令启动另一个mysql容器实例并对原始mysql容器运行mysql命令行客户端,允许您对数据库实例执行SQL语句:

$ sudo docker run -it --link some-mysql:mysql --rm mysql sh -c 'exec mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD"'

… some-mysql是原始mysql容器的名称。

此镜像还可以用作非Docker或远程MySQL实例的客户端:

$ docker run -it --rm mysql mysql -hsome.mysql.host -usome-mysql-user -p

有关MySQL命令行客户端的更多信息可以在MySQL documentation 中找到

…通过docker stack deploy或docker-compose

mysql的stack.yml示例:

# Use root/example as user/password credentials
version: '3.1'

services:

  db:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: example

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080

运行docker stack deploy -c stack.yml mysql(或docker-compose -f stack.yml up),等待它完全初始化,然后访问http://swarm-ip:8080http://localhost:8080,或http://host-ip:8080(视情况而定)。

容器shell访问和查看MySQL日志

docker exec命令允许您在Docker容器内运行命令。以下命令行将在mysql容器中为您提供一个bash shell:

$ sudo docker exec -it some-mysql bash

MySQL Server日志可通过Docker的容器日志获得:

$ sudo docker logs some-mysql

配置

使用自定义MySQL配置文件

MySQL的默认配置可以在/etc/mysql/my.cnf中找到,它可以包含其他目录,例如/etc/mysql/conf.d/etc/mysql/mysql.conf.d。请检查mysql镜像本身中的相关文件和目录以获取更多详细信息。

如果/my/custom/config-file.cnf是自定义配置文件的路径和名称,则可以像这样启动mysql容器(请注意,此命令中仅使用自定义配置文件的目录路径):

$ sudo docker run --name some-mysql -v /my/custom:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

这将启动一个新容器some-mysql,其中MySQL实例使用/etc/mysql/my.cnf和/etc/mysql/conf.d/config-file.cnf中的组合启动设置,后者的设置优先。

请注意,启用了SELinux的主机系统上的用户可能会遇到此问题。当前的解决方法是将相关的SELinux策略类型分配给新的配置文件,以便允许容器装入它:

$ sudo chcon -Rt svirt_sandbox_file_t /my/custom

没有cnf文件的配置

许多配置选项可以作为标志传递给mysqld。这将使您可以灵活地自定义容器,而无需cnf文件。例如,如果要更改所有表的默认编码和排序规则以使用UTF-8(utf8mb4),只需运行以下命令:

$ sudo docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

如果您想查看可用选项的完整列表,请运行:

$ docker run -it --rm mysql:tag --verbose --help

环境变量

启动mysql镜像时,可以通过在docker run命令行上传递一个或多个环境变量来调整MySQL实例的配置。请注意,如果使用已包含数据库的数据目录启动容器,则以下任何变量都不会产生任何影响:任何预先存在的数据库在容器启动时始终保持不变。

另请参阅https://dev.mysql.com/doc/refman/5.7/en/environment-variables.html以获取MySQL本身所遵循的环境变量的文档(尤其是MYSQL_HOST等变量,已知这些变量在与此一起使用时会导致镜像问题)。

MYSQL_ROOT_PASSWORD

此变量是必需的,并指定将为MySQL root超级用户帐户设置的密码。在上面的例子中,它被设置为my-secret-pw

MYSQL_DATABASE

此变量是可选的,允许您指定要在镜像启动时创建的数据库的名称。如果提供了用户/密码(见下文),则该用户将被授予此数据库的超级用户访问权限(corresponding to对应于 GRANT ALL)  。

MYSQL_USER, MYSQL_PASSWORD

这些变量是可选的,可以结合使用来创建新用户并设置该用户的密码。此用户将被授予MYSQL_DATABASE变量指定的数据库的超级用户权限(参见上文)。这两个变量都是创建用户所必需的。

请注意,不需要使用此机制来创建超级用户,默认情况下会使用MYSQL_ROOT_PASSWORD变量指定的密码创建该用户。

MYSQL_ALLOW_EMPTY_PASSWORD

这是一个可选变量。设置为yes以允许使用root用户的空密码启动容器。注意:建议不要将此变量设置为yes,除非您确实知道自己在做什么,因为这会使您的MySQL实例完全不受保护,从而允许任何人获得完整的超级用户访问权限。

MYSQL_RANDOM_ROOT_PASSWORD

这是一个可选变量。设置为yes以为root用户生成随机初始密码(使用pwgen)。生成的root密码将打印到stdout(GENERATED ROOT PASSWORD:.....)。

MYSQL_ONETIME_PASSWORD

初始化完成后,将root(不是MYSQL_USER中指定的用户!)用户设置为已过期,在首次登录时强制更改密码。注意:此功能仅在MySQL 5.6+上受支持。在MySQL 5.5上使用此选项将在初始化期间抛出适当的错误。

Docker Secrets

作为通过环境变量传递敏感信息的替代方法,_FILE可以附加到先前列出的环境变量,从而使初始化脚本从容器中存在的文件加载这些变量的值。特别是,这可以用于从存储在/run/secrets/<secret_name>文件中的Docker机密加载密码。例如:

$ sudo docker run --name some-mysql -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql-root -d mysql:tag

目前,仅支持MYSQL_ROOT_PASSWORDMYSQL_ROOT_HOSTMYSQL_DATABASEMYSQL_USERMYSQL_PASSWORD

初始化一个新实例

首次启动容器时,将创建具有指定名称的新数据库,并使用提供的配置变量进行初始化。此外,它将执行扩展名为.sh.sql.sql.gz的文件,这些文件位于/docker-entrypoint-initdb.d中。文件将按字母顺序执行。您可以通过将SQL转储装入该目录 mounting a SQL dump into that directory 并使用提供的数据提供 custom images 来轻松填充您的mysql服务。默认情况下,SQL文件将导入到MYSQL_DATABASE变量指定的数据库中。

注意事项(Caveats)

存储数据的位置

重要说明:有几种方法可以存储在Docker容器中运行的应用程序使用的数据。我们鼓励mysql镜像的用户熟悉可用的选项,包括:

  • 让Docker通过使用自己的内部卷管理将数据库文件写入主机系统上的磁盘来管理数据库数据的存储by writing the database files to disk on the host system using its own internal volume management 。这是默认设置,对用户来说简单且相当透明。缺点是文件可能很难找到直接在主机系统上运行的工具和应用程序,即外部容器。

  • 在主机系统(容器外部)上创建数据目录,并将其安装到容器内可见的目录中 mount this to a directory visible from inside the container 。这会将数据库文件放在主机系统上的已知位置,并使主机系统上的工具和应用程序可以轻松访问这些文件。缺点是用户需要确保目录存在,例如目录权限和主机系统上的其他安全机制已正确设置。

Docker文档是理解不同存储选项和变体的一个很好的起点,并且有多个博客和论坛帖子在这个领域讨论并提供建议。我们将在上面针对后一个选项简单地显示基本过程:

  1. 在主机系统上的适当卷上创建数据目录,例如/my/own/datadir
  2. 像这样启动你的mysql容器:
$ sudo docker run --name some-mysql -v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

命令的-v /my/own/datadir:/var/lib/mysql部分将/my/own/datadir目录从底层主机系统挂载到容器内的/var/lib/mysql,默认情况下MySQL将写它的数据文件。

请注意,启用了SELinux的主机系统上的用户可能会遇到此问题。当前的解决方法是将相关的SELinux策略类型分配给新数据目录,以便允许容器访问它:

$ sudo chcon -Rt svirt_sandbox_file_t /my/own/datadir

在MySQL 初始化完成之前没有连接

如果容器启动时没有初始化数据库,则将创建默认数据库。虽然这是预期的行为,但这意味着在初始化完成之前它不会接受传入的连接。当使用自动化工具(例如docker-compose)同时启动多个容器时,这可能会导致问题。

如果您尝试连接到MySQL的应用程序无法处理MySQL停机或等待MySQL正常启动,那么在服务启动之前放置连接重试循环可能是必要的。有关官方镜像中此类实现的示例,请参阅 WordPress or Bonita

针对现有数据库的用法

如果使用已包含数据库的数据目录(特别是mysql子目录)启动mysql容器实例,则应从运行命令行中省略$ MYSQL_ROOT_PASSWORD变量。在任何情况下都会被忽略,并且不会以任何方式更改预先存在的数据库。

创建数据库存储

大多数普通工具都可以使用,尽管在某些情况下它们的使用可能有点复杂,以确保它们可以访问mysqld服务器。确保这一点的一种简单方法是使用docker exec并从同一容器运行该工具,类似于以下内容:

$ sudo docker exec some-mysql sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /some/path/on/your/host/all-databases.sql

License

View license information for the software contained in this image.

与所有Docker映像一样,这些映像也可能包含其他许可证(例如来自基本分发版的Bash等,以及所包含的主要软件的任何直接或间接依赖关系)。

Some additional license information which was able to be auto-detected might be found in the repo-inforepository’s mysql/ directory.

对于任何预先构建的图像使用,图像用户有责任确保对此图像的任何使用都符合其中包含的所有软件的任何相关许可。

测试安装和配置

使用MyCat客户端测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-flLUcA0q-1599611781374)(assets/1534060461039.png)]

测试连接成功,可以开始使用数据库了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DWicixrK-1599611781377)(assets/1534060533977.png)]

注意:在外部连接对时候,防火墙中打开数据库3306端口。

小结

安装和配置来自 MySQL 官方在 docker hub 上提供对镜像安装和配置的说明。

docker修改mysql配置

MySQL根据配置文件会限制Server接受的数据包大小。有时候插入、更新或查询时数据包的大小,会受 max_allowed_packet 参数限制,导致操作失败。

查看 max_allowed_packet 参数:

在客户端执行:

show VARIABLES like '%max_allowed_packet%';

得到结果如下:

宿主机修改配置

进入容器

docker exec -it 1383f2e49cb7 /bin/bash

退出容器

Ctrl+P+Q

查看配置

more /etc/mysql/mysql.conf.d/mysqld.cnf

(* 如果你执行到这步提示没有该文件,别着急,往下看)

编辑配置

第一种方式:将配置从容器中copy到宿主机(之前文章讲到过,可以去看下,如果没有该文件,那这一步省略,稍后直接将我写好的配置放到容器中就好)

docker cp mysql-service:/etc/mysql/mysql.conf.d/mysqld.cnf /opt/mysql/mysqld.cnf

mysqld.cnf脚本如下:

# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA

#
# The MySQL  Server configuration file.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html

[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
#log-error      = /var/log/mysql/error.log
# By default we only accept connections from localhost
#bind-address   = 127.0.0.1
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
character_set_server=utf8
init_connect='SET NAMES utf8'
max_allowed_packet = 20M

[mysql]
default-character-set = utf8

[mysql.server]
default-character-set = utf8

[mysqld_safe]
default-character-set = utf8

[client]
default-character-set = utf8






#兼容表情
character_set_server=utf8mb4
init_connect='SET NAMES utf8mb4'
#处理查询错误
max_allowed_packet = 40M

[mysql]
default-character-set = utf8mb4

[mysql.server]
default-character-set = utf8mb4

[mysqld_safe]
default-character-set = utf8mb4

[client]
default-character-set = utf8mb4


(* 请注意做好备份)

## 将修改后的配置copy到容器
docker cp /opt/mysql/mysqld.cnf mysql-service:/etc/mysql/mysql.conf.d/

容器直接编辑

在使用docker容器时,有时候里边没有安装vim,敲vim命令时提示说:vim: command not found,这个时候就需要安装vim,可是当你敲apt-get install vim命令时,提示:
Reading package lists… Done
Building dependency tree
Reading state information… Done
E: Unable to locate package vim
这时候需要敲:

apt-get update

这个命令的作用是:同步 /etc/apt/sources.list 和 /etc/apt/sources.list.d 中列出的源的索引,这样才能获取到最新的软件包。
等更新完毕以后再敲命令:

apt-get install vim
vim /etc/mysql/mysql.conf.d/mysqld.cnf

接下来重启容器就可以了(可以参考之前的文章)

docker restart mysql-service 

(* 1383f2e49cb7是容器的CONTAINER ID,可以通过docker ps看到 )

windows 配置

# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html
# *** DO NOT EDIT THIS FILE. It's a template which will be copied to the
# *** default location during install, and will be replaced if you
# *** upgrade to a newer version of MySQL.

[mysqld]

# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M

# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin

# These are commonly set, remove the # and set as required.
# basedir = .....
# datadir = .....
# port = .....
# server_id = .....

# 绑定IPv4和3306端口
bind-address = 0.0.0.0
port = 3306

# 设置mysql的安装目录
basedir=E:/mysql

# 设置mysql数据库的数据的存放目录
datadir=E:/mysql/data

# 允许最大连接数
max_connections=200

default-storage-engine=INNODB
# default-storage-engine=MyISAM

# 设置mysql的字符集,gbk或utf-8,根据需要
# set character set
# default-character-set=utf8

# set character collation
# default-collation=gbk_chinese_ci


# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

wait_timeout=2886400
interactive_timeout =2886400
max_allowed_packet=40M

设置mysql的字符集,gbk或utf-8,根据需要

set character set

default-character-set=utf8

set character collation

default-collation=gbk_chinese_ci

Remove leading # to set options mainly useful for reporting servers.

The server defaults are faster for transactions and fast SELECTs.

Adjust sizes as needed, experiment to find the optimal values.

join_buffer_size = 128M

sort_buffer_size = 2M

read_rnd_buffer_size = 2M

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

wait_timeout=2886400
interactive_timeout =2886400
max_allowed_packet=40M


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值