Linux 使用docker搭建MySQL服务的一些细节问题
前言:docker目前已经在实际的生产活动中应用非常广泛了,但在生产方面,我们使用docker需要考虑的地方就需要比测试更多了,比如,时区问题,CPU亲和度问题,服务依赖关系问题,网络配置和管理问题,数据持久化问题,日志管理问题。以上问题产生的根本原因是由于docker自身的架构和设计所产生的。比如,时区问题,是由于我们使用的镜像基本都是由国外的docker官方网站所制作的,当然了,基础镜像也就会
前言:
docker目前已经在实际的生产活动中应用非常广泛了,但在生产方面,我们使用docker需要考虑的地方就需要比测试更多了,比如,时区问题,CPU亲和度问题,服务依赖关系问题,网络配置和管理问题,数据持久化问题,日志管理问题。
以上问题产生的根本原因是由于docker自身的架构和设计所产生的。
比如,时区问题,是由于我们使用的镜像基本都是由国外的docker官方网站所制作的,当然了,基础镜像也就会使用国外的时区啦,而我们要在本地使用,需要进行适当的本地化改造,将时区统一到东八区啦。docker中如果对时区不加限制,默认会采用格林尼治时间(GMT),这给日常程序部署、日志查看、错误调试等带来了诸多麻烦与困扰。每次都需要将event发生的显示时间+8个时区,手工换算成北京时间,想想都令人抓狂。
CPU亲和度问题和内存限制问题,是由于docker设计的时候就是可以无限抢占宿主机资源,如果容器内的服务疯狂抢占宿主机资源,将会导致宿主机出现一系列问题。
如果生产中使用docker部署项目,或者某个集群,那么,一般是有启动的先后顺序,也就是容器的启动先后顺序是有规定的,比如,WordPress这种项目就必须先启动数据库,在启动WordPress服务,由此,我们势必需要根据各个服务的依赖关系编排docker容器。
并且docker设计之初对于网络的配置和管理是十分弱的,并定义了容器之间默认是相互隔离的,因此,我们需要对原有的默认的网络根据自己的需求进行改造。
服务并不是一成不变的,我们也有升级服务的需求,改变服务的需求,这些需要docker的持久化支持,也就是volume数据外接挂载。
docker默认是不会对日志做任何限制的,因此,我们需要对日志的大小做一定的限制,防止日志过大撑爆宿主机。
实验目的:
贴近实战,使用一个MySQL的docker镜像,通过docker-compose对其进行编排,关于时区问题,数据持久化问题,日志问题详细介绍。
实验环境:
vm虚拟机,虚拟机配置如下:
8G内存,8CPU,硬盘大小为100G。操作系统为centos7.7.1908
实验步骤:
一,docker环境搭建
docker环境搭建没什么好说的,请看我的博客:docker的离线安装以及本地化配置_zsk_john的博客-CSDN博客
docker的版本是:
[root@hdp-1 ~]# docker version
Client: Docker Engine - Community
Version: 20.10.5
API version: 1.41
Go version: go1.13.15
Git commit: 55c4c88
Built: Tue Mar 2 20:14:11 2021
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.5
API version: 1.41 (minimum version 1.12)
Go version: go1.13.15
Git commit: 363e9a8
Built: Tue Mar 2 20:18:31 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: v1.4.3
GitCommit: 269548fa27e0089a8b8278fc4fc781d7f65a939b
runc:
Version: 1.0.0-rc93
GitCommit: 12644e614e25b05da6fd08a38ffa0cfe1903fdec
docker-init:
Version: 0.19.0
GitCommit: de40ad0
docker-compose的版本是:
[root@hdp-1 ~]# docker-compose -verison
docker-compose version 1.25.1, build a82fef07
二,MySQL的镜像文件
链接:https://pan.baidu.com/s/1xWhp4r7Sy4UgLk0ep45k7w
提取码:mysq
MySQL的版本为5.7.22 ,这里需要注意,该镜像的基础镜像是由debian操作系统制作的!!!!!!!!!一定要清楚这一点!!!
三,镜像文件导入docker环境内
将上述镜像文件放入虚拟机内,执行以下命令:
docker load < mysql-Docker.tar
cdb3f9544e4c: Loading layer [==================================================>] 58.44MB/58.44MB
6f8d38b0e2b6: Loading layer [==================================================>] 338.4kB/338.4kB
aae63f31dee9: Loading layer [==================================================>] 10.43MB/10.43MB
4801a487d51a: Loading layer [==================================================>] 4.471MB/4.471MB
c0c26734fb83: Loading layer [==================================================>] 1.536kB/1.536kB
94f8d8f5acbf: Loading layer [==================================================>] 46.11MB/46.11MB
8aeebb3964c1: Loading layer [==================================================>] 28.16kB/28.16kB
22b402e93939: Loading layer [==================================================>] 3.584kB/3.584kB
489bddb9c55e: Loading layer [==================================================>] 257.2MB/257.2MB
f8cb294d5d80: Loading layer [==================================================>] 9.728kB/9.728kB
a968f24d4187: Loading layer [==================================================>] 1.536kB/1.536kB
Loaded image: mysql:5.7.22
执行查看镜像命令,应该有如下输出:
[root@hdp-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7.22 6bb891430fb6 3 years ago 372MB
四,编写docker-compose 的编排文件,文件可放在任意位置,文件名也任意,但后缀必须是yaml或者yml。文件内容如下(本文定义文件名为MySQL.yaml):
version: '3'
services:
mysql:
container_name: mysql-5.7.22
image: mysql:5.7.22
restart: always
environment:
MYSQL_USER: admin
MYSQL_PASSWORD: admins
MYSQL_DATABASE: database
MYSQL_ROOT_PASSWORD: admin
TZ: Asia/Shanghai
volumes:
- /usr/local/mysql/data:/var/lib/mysql
ports:
- 3306:3306
network_mode: host
那么,这个yaml文件里写的都是什么意思呢?
(1)version这里申明docker服务的大体版本,我使用的版本是docker-ce-20.10.5版本,因此,这里version的值至少应该是3,取值范围是3到3.7,如果修改成3.8,那么结果是这样的:
[root@hdp-1 ~]# docker-compose -f mysql.yaml stop mysql
ERROR: Version in "./mysql.yaml" is unsupported. You might be seeing this error because you're using the wrong Compose file version. Either specify a supported version (e.g "2.2" or "3.3") and place your service definitions under the `services` key, or omit the `version` key and place your service definitions at the root of the file to use version 1.
For more on the Compose file format versions, see https://docs.docker.com/compose/compose-file/
(2) container_name
此行定义容器的名称,写在这个文件里的好处显而易见,便于管理。容器的各类操作都和名称是密切相关的。
(3)environment 容器的环境变量
这里就有点意思了,首先,有一个问题 ,这里定义了一个MySQL用户,和该用户的密码,以及该用户的数据库名称,那么,可否定义多个用户,多个数据库名称呢?
经我测试,答案是不可以定义多个用户和密码。那么,如果想要MySQL多个用户怎么办?
volume挂载/docker-entrypoint-initdb.d/这个目录,然后在宿主机放入初始化用户的SQL脚本,例如在/usr/local//mysql/init这个目录下编辑文件 init.sql文件,文件内容如下这样:
CREATE USER 'myuser'@'%' IDENTIFIED BY 'myuser';
GRANT All privileges ON *.* TO 'myuser'@'%';
flush privileges;
这个SQL脚本将会建立一个名字叫myuser的用户,并建立一个数据库,数据库名称为myuser,该用户可远程到此数据库上。
例如:
version: '3'
services:
mysql:
container_name: mysql
image: mysql:5.7.22
restart: always
logging:
driver: "json-file"
options:
max-size: "1g"
environment:
- "MYSQL_USER=huiqing"
- "MYSQL_PASSWORD=Huiqing^*^O3799"
- "MYSQL_ROOT_PASSWORD=R349_&^#@e]"
- "TZ=Asia/Shanghai"
volumes:
- /data/soft/software/mysql/data:/var/lib/mysql
- /data/soft/software/mysql/conf/:/etc/mysql/conf.d
- /data/soft/software/mysql/source:/docker-entrypoint-initdb.d
ports:
- 42706:3306
此时,进入容器内,登录MySQL,两个root密码只有最后一个密码可登录。
[root@hdp-1 ~]# docker exec -it 1e292 /bin/bash
root@hdp-1:/# mysql -uroot -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
root@hdp-1:/# mysql -uroot -padmins123
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
root@hdp-1:/# mysql -uroot -padmins
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
root@hdp-1:/# mysql -uroot -padmins
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
root@hdp-1:/# mysql -uroot -padmins123
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
root@hdp-1:/# mysql -uzsk -pzsk1
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'zsk'@'localhost' (using password: YES)
root@hdp-1:/# mysql -uzsk -p
Enter password:
ERROR 1045 (28000): Access denied for user 'zsk'@'localhost' (using password: YES)
然后执行:
docker-compose -f MySQL.yaml down
docker-compose -f MySQL.yaml up -d
让SQL脚本执行一次,就有新用户myuser了。
(4)数据映射 volume
数据库这样的服务是有数据的流动的,也就是数据流入流出,其实这样的服务并不太适合docker,但自从有了数据挂载映射volume,这些都不是太大的问题了,像本例中使用的yaml文件中的挂载,因为我们是使用的自定义式的覆盖挂载模式,也就是宿主机这边这个目录是空的,而容器端的目录也是空的,因此,不会出现覆盖现象。那么,我们每一次重启容器就会重新映射一次数据,从而保证数据的一致性。
(5)网络模式的管理
一般的情况下,我们使用默认的docker的桥接模式即可满足我们的需求,但,如果对容器间的通信有需求,这个时候就需要我们自定义网络啦。
docker-compose网络配置_chen_jianjian的专栏-CSDN博客这个博客写的还是不错的,由于网络管理是一个比较复杂庞大的内容,再次就不过多讨论了。
(6)日志管理问题
日志管理我在前面的博客内也写了很多,考虑再三,也就不重复前面的话了,可以看本人的博客: docker的日志管理工作和时区本地化设置(docker日志过大,造成磁盘空间被占满的两种处理方法,以及时区的准确设置)_zsk_john的博客-CSDN博客 这里有详细的介绍
五,一个可用的贴近实战的docker启动MySQL正确的示例
version: '3'
services:
mysql:
container_name: mysql
image: mysql:5.7.22
restart: always
logging:
driver: "json-file"
options:
max-size: "1g"
environment:
- "MYSQL_USER=huiqing"
- "MYSQL_PASSWORD=Huiqing^*^O3799"
- "MYSQL_ROOT_PASSWORD=R349_&^#@e]"
- "TZ=Asia/Shanghai"
volumes:
- /data/soft/software/mysql/data:/var/lib/mysql
- /data/soft/software/mysql/conf/:/etc/mysql/conf.d
- /data/soft/software/mysql/source:/docker-entrypoint-initdb.d
ports:
- 42706:3306
这个编排文件表示启动一个MySQL5.7.22版本,配置文件映射到 /usr/local/mysql/conf/目录下,时区为中国上海,容器开放端口为3306,宿主机开放的端口为42706,日志限制在最大2G。日志驱动模式是json-file,也就是说如果使用docker logs mysql-lable 这个命令查看容器的日志,输出格式会为json格式。
那么以上的编排文件又会出现新问题了,这个docker容器所开放的端口是3306,如何更改成自定义的端口呢?
这就简单了,编写my.cnf 文件,文件内容如下:
[client]
port=3306
socket=/var/lib/mysql/mysql.sock
[mysqldump]
quick
max_allowed_packet = 16M
[mysqld]
bind-address = 0.0.0.0
#basedir = /var/lib/mysql
#datadir = /var/lib/mysql
port=3307
server-id = 1
socket=/var/lib/mysql/mysql.sock
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
character_sets_dir=/var/lib/mysql/mysql/charsets
init_connect='SET NAMES utf8mb4'
default-storage-engine=INNODB
default_authentication_plugin=mysql_native_password
skip-character-set-client-handshake = true
lower_case_table_names = 1
key_buffer_size=16M
max_allowed_packet=16M
sql_mode=TRADITIONAL
slow_query_log=on
slow-query-log-file=/var/lib/mysql/slow.log
long_query_time=1
log-bin=my-binlog-name
binlog_format=MIXED
[mysql]
default-character-set=utf8mb4
将此文件cp到/data/soft/software/mysql/conf目录下,重启容器即可自定义端口为3307,并且开启了慢查询日志和binlog日志。此时,上面的那个yaml文件也要做相应修改:
version: '3'
services:
mysql:
container_name: mysql
image: mysql:5.7.22
restart: always
logging:
driver: "json-file"
options:
max-size: "1g"
environment:
- "MYSQL_USER=huiqing"
- "MYSQL_PASSWORD=Huiqing^*^O3799"
- "MYSQL_ROOT_PASSWORD=R349_&^#@e]"
- "TZ=Asia/Shanghai"
volumes:
- /data/soft/software/mysql/data:/var/lib/mysql
- /data/soft/software/mysql/conf/:/etc/mysql/conf.d
- /data/soft/software/mysql/source:/docker-entrypoint-initdb.d
ports:
- 42706:3307
也就是ports 修改为 - 42706:3307 ,然后在别的机器远程连接的时候填写连接端口为42706即可连接啦。
通过编辑my.cnf 文件即可定制自己想要的MySQL啦。
更多推荐
所有评论(0)