基于Docker的持续集成方案(安装和配置MySql) - Part.3
这篇文章介绍了使用Docker安装MySql数据库的操作步骤,以及安装完成后如何对MySql进行配置。
关于使用docker安装数据库的一些理解
部分开发人员对于使用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。
使用Docker安装MySql
然而,我自己的Linux服务器,是一台学习和测试用的服务器,既运行了这个博客程序,也运行了很多其他的东西。同时,这台服务器并没有什么太大的访问量,因此,不管是出于实际使用,还是出于docker的应用练习,运行MySql数据库都没有任何问题。
接下来,就一步步演示如何使用Docker来安装MySql。
选择要安装的MySql版本
打开hub.docker.com,搜索MySql,排在最上面会有两个库,一个是 mysql,一个是 mysql/mysql-server。第一个是docker提供的官方库,第二个是mysql团队提供的针对docker优化过的mysql镜像。这里我选择的是mysql/mysql-server。
进入 mysql/mysql-server 后,点击Tags,可以看到有很多不同的版本,我选择的5.7。
之前安装过最新的8.0,出现一个权限的问题没能解决,导致无法通过互联网远程连接,就暂时先用回了上一个主要版本,5.7。
在Linux上下载mysql镜像
我一般不直接使用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命令重命名镜像:
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数据库
在运行MySql数据库之前,可以先用docker images查看一下本地镜像,正常应该看到如下所示:
docker images REPOSITORY TAG IMAGE ID CREATED SIZE mysql 5.7 3cc9613ef3ba 6 weeks ago 244MB
创建my.cnf配置文件和data数据文件夹
接下来,在使用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命令极其复杂,可以通过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
下面是对参数的一个简要说明:
- -d,说明容器在后台运行。
- -p,将操作系统的端口与容器的端口进行映射,这里是用操作系统的3306端口,去映射容器的3306端口(MySql默认端口)。
- -e,容器运行的环境变量,这里设置了初始的管理员密码root123。
- --name,容器名称,mydb
- -v,程序挂载的映射,将操作系统中的/docker/mysql/data文件夹和容器内的/var/lib/mysql文件夹做一个映射。
- mysql:5.7,这个是运行的镜像的全名(我们之前是用tag将名称简化为了mysql:5.7)。
- --default-authentication-plugin=mysql_native_password,出现在镜像mysql:5.7之后的命令均为mysql的指令,而与docker无关了。
容器拥有自己的网络和端口号,因此,如果程序在容器内部运行,使用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
配置MySql数据库
配置MySql用户
此时如果在客户机(开发用的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后,执行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相关的资料了。
感谢阅读,希望这篇文章能给你带来帮助!