2018-6-10 作者: 张子阳 分类: 分布式系统
这篇文章介绍了使用Docker安装MySql数据库的操作步骤,以及安装完成后如何对MySql进行配置。
部分开发人员对于使用docker运行数据库持有疑虑,认为多了一层容器,必然带来性能的损耗。在国外有人专门将容器与物理机的性能进行了对比测试,结论是:Docker containerization has a negligible impact on the execution performance of common genomic pipelines where tasks are generally very time consuming.(对于长时间运行的任务而言,docker容器的影响可以忽略不计),论文地址:https://peerj.com/articles/1273/。
除此以外,查看docker的官方文档,docker容器本身在默认情况下对于宿主机器的资源使用没有任何限制,可以访问全部的CPU、内存资源。(By default, a container has no resource constraints and can use as much of a given resource as the host’s kernel scheduler allows. Docker provides ways to control how much memory, CPU, or block IO a container can use, setting runtime configuration flags of the docker run command. ),官网文档地址:https://docs.docker.com/config/containers/resource_constraints/
基于上面两点,可以认为:大多数情况下,使用docker运行数据库是可行的。
然而,使用Docker的一个主要目的是:将程序和其依赖的运行环境打包起来运行,以方便部署,同时避免和其他程序冲突。而数据库通常都是企业的核心应用,数据库服务器几乎就只运行数据库引擎,不干任何其他事情。此时,数据库服务器已经是职能单一了,不会和其他环境或者程序产生冲突,这种情况下,可以认为没有必要使用docker。
然而,我自己的Linux服务器,是一台学习和测试用的服务器,既运行了这个博客程序,也运行了很多其他的东西。同时,这台服务器并没有什么太大的访问量,因此,不管是出于实际使用,还是出于docker的应用练习,运行MySql数据库都没有任何问题。
接下来,就一步步演示如何使用Docker来安装MySql。
打开hub.docker.com,搜索MySql,排在最上面会有两个库,一个是 mysql,一个是 mysql/mysql-server。第一个是docker提供的官方库,第二个是mysql团队提供的针对docker优化过的mysql镜像。这里我选择的是mysql/mysql-server。
进入 mysql/mysql-server 后,点击Tags,可以看到有很多不同的版本,我选择的5.7。
选择mysql版本
之前安装过最新的8.0,出现一个权限的问题没能解决,导致无法通过互联网远程连接,就暂时先用回了上一个主要版本,5.7。
我一般不直接使用docker run命令,而是先手动执行docker pull,然后再单独执行一遍docker run。
使用docker pull命令下载mysql镜像
docker pull registry.docker-cn.com/mysql/mysql-server:5.7
这里我没有直接执行docker pull mysql/mysql-server:5.7,而是加了国内的镜像站点前缀registry.docker-cn.com,是因为hub.docker.com国内访问有时不稳定,
为了后续使用方面,可以使用docker tag命令重命名镜像:
docker tag registry.docker-cn.com/mysql/mysql-server:5.7 mysql:5.7; \
docker rmi registry.docker-cn.com/mysql/mysql-server:5.7
这样后面使用镜像时,用mysql:5.7就可以了,更简洁一些。在重命名后,我们用docker rmi命令删除了之前下载的镜像(其实只删除了引用)。
在运行MySql数据库之前,可以先用docker images查看一下本地镜像,正常应该看到如下所示:
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 3cc9613ef3ba 6 weeks ago 244MB
接下来,在使用docker run命令来运行mysql容器之前,我们需要做一点额外工作,先在系统下创建几个文件夹:
mkdir -p /docker/mysql/config; mkdir -p /docker/mysql/data
上面的命令创建了这样两个路径下的文件夹:/docker/mysql/config 和 /docker/mysql/data。config文件夹下的my.cnf用于存储配置,data文件夹用于存储数据。因为在默认情况下,当docker容器被销毁(不是停止运行,而是执行docker rm进行删除)时,容器内的所有文件都会丢失,我们当然不希望数据库的数据也会被删除,因此,在执行docker run命令时,可以通过-v标签将操作系统中的文件夹挂载到容器内(相当于做一个映射)。这样,当容器销毁时,配置和数据依然还在,我们可以将这些配置和数据重新再挂载到另一个mysql容器中。
创建my.cnf文件,并拷贝到/docker/mysql/config下:
my.cnf是mysql的配置文件,我们需要预先创建一个:
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html
[mysqld]
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
secure-file-priv=/var/lib/mysql-files
user=mysql
character-set-server=utf8
collation-server=utf8_general_ci
max_connections=1000
thread_cache_size=256
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
这里的两个关键配置是:character-set-server=utf8、collation-server=utf8_general_ci,配置数据库使用的字符集。
docker run命令极其复杂,可以通过docker run --help查看命令帮助。运行本文中的mysql容器,需要执行的命令如下:
docker run -d \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD="root123" \
--name mydb \
-v=/docker/mysql/config/my.cnf:/etc/my.cnf \
-v=/docker/mysql/data:/var/lib/mysql \
mysql:5.7 \
--default-authentication-plugin=mysql_native_password
下面是对参数的一个简要说明:
容器拥有自己的网络和端口号,因此,如果程序在容器内部运行,使用localhost是无法访问到容器外部同一台主机上的其他程序的。需要使用IP地址。上面命令中的 -p 3306:3306,则是将主机的3306端口映射到容器内部的3306端口,因为mysql端口是在容器内开放的,如果不做外部映射,就只有在容器内部才能访问了。
执行完成后,运行docker ps,可以看到数据库正在启动:
[root@mylinux ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
99005f75492c mysql:5.7 "/entrypoint.sh mysq…" 3 seconds ago Up 2 seconds (health: starting) 0.0.0.0:3306->3306/tcp, 33060/tcp mydb
此时如果在客户机(开发用的Windows或者Mac机器)上,使用Navicat去连接MySql,会发现依然连接不上,因为默认情况下,安装完成后,root用户只有本地连接的权限,而没有远程连接的权限。除了修改root用户权限外,更通常的做法是创建一个新的用户。
要创建用户,首先需要执行mysql的命令,而要执行mysql命令,我们需要进入到容器内。因此,先登录Linux(我的是CentOS7),然后执行下面的命令进入容器内:
docker exec -it mydb bash
进入容器后,在控制台执行ls命令,查看目录结构,会发现仿佛又进入了一个微型的Linux系统,麻雀虽小五脏俱全,该有的系统文件夹全都有。
[root@mylinux ~]# docker exec -it mydb bash
bash-4.2# ls
bin etc lib64 proc sys
boot healthcheck.cnf media root tmp
dev healthcheck.sh mnt run usr
docker-entrypoint-initdb.d home mysql-init-complete sbin var
entrypoint.sh lib opt srv
在容器内,登录mysql:
mysql -u root -p
输入密码:root123,进入到mysql命令行。首先执行 use mysql;
切换当前数据库。然后,执行下面的命令,创建一个名为zhangzy的用户,并授予本地和远程访问的全部权限。
授予本地访问权限:
CREATE USER 'zhangzy'@'localhost' IDENTIFIED WITH mysql_native_password BY 'user123' PASSWORD EXPIRE NEVER;
GRANT ALL PRIVILEGES ON *.* TO 'zhangzy'@'localhost' WITH GRANT OPTION;
FlUSH PRIVILEGES;
授予远程访问权限:
CREATE USER 'zhangzy'@'%' IDENTIFIED WITH mysql_native_password BY 'user123' PASSWORD EXPIRE NEVER;
GRANT ALL PRIVILEGES ON *.* TO 'zhangzy'@'%' WITH GRANT OPTION;
FlUSH PRIVILEGES;
之后,执行下面的mysql语句,查看当前用户。正常可以看到下面的输出:
mysql> use mysql; select user, host from user;
+---------------+-----------+
| user | host |
+---------------+-----------+
| zhangzy | % |
| healthchecker | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
| zhangzy | localhost |
+---------------+-----------+
6 rows in set (0.00 sec)
验证连接
此时,打开navicat数据库管理软件,连接MySql,输入相关的数值,可以看到可以成功连接。
成功连接MySql数据库
连接到MySql后,执行select now(),会看到返回的时间比当前时间早了8个小时,因为系统默认时区是UTC,而国内时间是UTC+8。
执行下面的语句,修改系统的默认时区:
set global time_zone = '+8:00';
set time_zone = '+8:00';
flush privileges;
之后再运行 select now(),会看到日期已经与国内时间相同。
至此,在Docker下安装并配置MySql便告一段落。对于MySql的详细配置,则已经不属于Docker的范畴,需要查阅MySql相关的资料了。
感谢阅读,希望这篇文章能给你带来帮助!