您当前的位置:首页 > 计算机 > 云技术 > Docker

【Docker】CentOS 7.9 Docker 安装 Mysql 5.7

时间:07-16来源:作者:点击数:

引言

docker 搭建Mysql比较蛋疼的点是配置文件映射,本文将会重点围绕这一点进行介绍。

docker部署mysql非常快速。了解docker安装mysql十分有必要,在深入mysql学习过程中可能会遇到不同版本细节对比,或者需要对比子版本号的bug修挂情况差异对比情况,这时候用docker快速运行和卸载不同版本的mysql,或者一个机器上跑多个不同版本的mysql都是十分方便的。

本次实验的个人是用的是 Win11物理机 + VM 16虚拟机软件 + CetnerOs7.9 版本+ docker + mysql5.7 的方案(这个层层套娃有点绷不住)。

docker 安装过程

个人认为最佳答案是查阅官方文档照着一步步做即可,吊打网络上的所有博客:Install Docker Engine on Ubuntu | Docker Documentation

个人在安装过程中碰到了下面的问题。

Job for docker.service failed because start of the service was attempted too often.

一般出现在安装docker之后切换国内镜像重启会报这样的错误:

Job for docker.service failed because start of the service was attempted too often. See "systemctl status docker.service" and "journalctl -xe" for details. To force a start use "systemctl reset-failed docker.service" followed by "systemctl start docker.service" again.

解决办法是把daemon.json配置文件改成daemon.conf(官方真是闲的没事干=-=)。

  1. 切换为root
  2. 进入到/etc/docker这个目录,查看是否有daemon.json的文件
  3. 把daemon.json配置文件改成daemon.conf即可,命令:
mv daemon.json daemon.conf

Error response from daemon: Gethttps://registry-1.docker.io/v2/: net/http: request canceled 报错

拉取镜像的时候发现总是拉取失败,解决方案如下:

vim 打开/etc/resolv.conf

sudo vi /etc/resolv.conf

将 nameserver 改为8.8.8.8

# Generated by NetworkManager
# nameserver 192.168.1.1
# nameserver 192.168.0.1
nameserver 8.8.8.8
~                    

修改之后重启docker:

sudo systemctl restart docker

最后检查重试:

[roothome.php?mod=space&uid=485241 docker]# sudo docker pull mysql:5.7

查找镜像

[zxd@localhost seata]$ docker search mysql
NAME                            DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql                           MySQL is a widely used, open-source relation…   13614     [OK]       
mariadb                         MariaDB Server is a high performing open sou…   5197      [OK]       
phpmyadmin                      phpMyAdmin - A web interface for MySQL and M…   713       [OK]       
percona                         Percona Server is a fork of the MySQL relati…   597       [OK]       
bitnami/mysql                   Bitnami MySQL Docker Image                      80                   [OK]
databack/mysql-backup           Back up mysql databases to... anywhere!         77                   
linuxserver/mysql-workbench                                                     45                   
ubuntu/mysql                    MySQL open source fast, stable, multi-thread…   40                   
linuxserver/mysql               A Mysql container, brought to you by LinuxSe…   38                   
circleci/mysql                  MySQL is a widely used, open-source relation…   28                   
google/mysql                    MySQL server for Google Compute Engine          22                   [OK]
rapidfort/mysql                 RapidFort optimized, hardened image for MySQL   13                   
bitnami/mysqld-exporter                                                         4                    
ibmcom/mysql-s390x              Docker image for mysql-s390x                    2                    
vitess/mysqlctld                vitess/mysqlctld                                1                    [OK]
newrelic/mysql-plugin           New Relic Plugin for monitoring MySQL databa…   1                    [OK]
hashicorp/mysql-portworx-demo                                                   0                    
rapidfort/mysql-official        RapidFort optimized, hardened image for MySQ…   0                    
docksal/mysql                   MySQL service images for Docksal - https://d…   0                    
mirantis/mysql                                                                  0                    
rapidfort/mysql8-ib             RapidFort optimized, hardened image for MySQ…   0                    
cimg/mysql                                                                      0                    
eclipse/mysql                   Mysql 5.7, curl, rsync                          0                    [OK]
drud/mysql                                                                      0                    
silintl/mysql-backup-restore    Simple docker image to perform mysql backups…   0                    [OK]

获取镜像

使用下面的命令获取镜像,个人用了mysql-5.7的版本:

docker pull mysql:5.7

检查镜像

可以使用下面的命令检查当前下载的所有镜像:

docker images

个人获取到的镜像内容如下:

[zxd@localhost seata]$ docker images
REPOSITORY                          TAG       IMAGE ID       CREATED         SIZE
redis                               latest    0256c63af7db   5 days ago      117MB
mysql                               5.7       d410f4167eea   2 weeks ago     495MB
redis                               <none>    3e12e2ceb68f   2 weeks ago     117MB
apache/rocketmq                     4.9.4     a2a50ca263c3   5 months ago    548MB
apacherocketmq/rocketmq-dashboard   latest    eae6c5db5d11   14 months ago   738MB
hello-world                         latest    feb5d9fea6a5   15 months ago   13.3kB

本地创建mysql的映射目录(重要)

在正式的启动Mysql镜像之前,先建立映射目录的配置。

mkdir -p /opt/mysql/data /opt/mysql/logs /opt/mysql/conf

/root/mysql/conf中创建XXXX.cnf文件(XXX名字叫什么都行,后缀不能改)。这里个人创建的mysql.conf

touch mysql.cnf

创建容器,命令中将数据日志,配置文件映射到宿主机,注意这里的 root 密码为 root :

docker run -p 13306:3306 --name mysql -v /opt/mysql/conf:/etc/mysql/conf.d -v /opt/mysql/logs:/logs -v /opt/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7

运行之后,我们执行docker ps查看当前运行的mysql镜像:

[zxd@localhost conf]$ docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED              STATUS              PORTS                                                                                                               NAMES
e95a0bc7b4a4   mysql:5.7               "docker-entrypoint.s…"   About a minute ago   Up About a minute   33060/tcp, 0.0.0.0:13306->3306/tcp, :::13306->3306/tcp                                                              mysql

相关运行参数解释如下:

-d:后台运行容器

-p将容器的端口映射到本机的端口

-v将主机目录挂载到容器的目录

-e设置参数

如果要访问mysql,需要先进入对应的容器当中,我们先docker ps查看容器ID。

[root@localhost opt]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                                                    NAMES
56f5e5575d35   mysql:5.7   "docker-entrypoint.s…"   20 minutes ago   Up 20 minutes   33060/tcp, 0.0.0.0:13306->3306/tcp, :::13306->3306/tcp   mysql

之后进入到容器。

docker exec -it 56f5e5575d35 /bin/bash

然后执行下面的命令进入到mysql。

bash-4.2# mysql -uroot -proot
[zxd@localhost conf]$ mysql -uroot -proot -P 13306
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.6.51 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

退出容器,最后查看/opt/mysql/data目录是否有数据文件,如果出现下面类似的内容说明映射正确:

[zxd@localhost conf]$ sudo ls /opt/mysql/data
auto.cnf    client-cert.pem  ibdata1      ibtmp1      performance_schema  server-cert.pem
ca-key.pem  client-key.pem   ib_logfile0  mysql       private_key.pem     server-key.pem
ca.pem      ib_buffer_pool   ib_logfile1  mysql.sock  public_key.pem      sys

运行容器

为了方便操作,这里单独运行容器的命令单独抽出来。

mkdir -p /opt/mysql/data /opt/mysql/logs /opt/mysql/conf
docker run -p 13306:3306 --name mysql57 --restart=always -v /opt/mysql/conf:/etc/mysql/conf.d -v /opt/mysql/logs:/logs -v /opt/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7

宿主机备份数据库

可以用下面的命令进行备份

docker exec 容器ID sh -c ' exec mysqldump --all-databases -uroot -p"root" ' > /mydocker/mysql/all-databases.sql
docker exec 58fa52f21404 sh -c ' exec mysqldump --all-databases -uroot -p"root" ' > /mydocker/mysql/all-databases.sql

不出意外是下面的报错:

bash: /mydocker/mysql/all-databases.sql: No such file or directory

新建一个备份SQL的存储位置:

[root@localhost xander]# mkdir -p /opt/mysql/backup

再重新执行一遍

docker exec 58fa52f21404 sh -c ' exec mysqldump --all-databases -uroot -p"root" ' > /opt/mysql/backup/all-databases.sql

再次执行之后检查相关文件夹发现成功导出。

[root@localhost xander]# ls -alF /opt/mysql/backup/all-databases.sql
-rw-r--r-- 1 root root 3450718 Apr 16 05:13 /opt/mysql/backup/all-databases.sql

容器其他操作

停止容器

docker stop 容器id

强制停止容器

docker kill 容器ID

删除容器

docker rm  [-f] 容器ID

删除所有容器(谨慎使用)

docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm

mysql5.7容器内部情况

配置文件

个人的运行情况,容器内的配置文件在/etc目录。my.cnf文件内容如下(引入了conf.d 、mysql.conf.d路径下的文件):

bash-4.2# cat my.cnf
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html

[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
#
# 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
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
secure-file-priv=/var/lib/mysql-files
user=mysql

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

#log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
[client]
socket=/var/run/mysqld/mysqld.sock

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

最后一部分包含的配置可以将对应目录下的所有配置文件配置引入:

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

!includedir /etc/mysql/conf.d/

表示包含/etc/mysql/conf.d/这个路径下面的配置文件,前提是必须以为.cnf为后缀

!includedir /etc/mysql/mysql.conf.d/

表示包含/etc/mysql/mysql.conf.d/这个路径下面的配置文件,前提是必须以为.cnf为后缀

相对应容器内的/etc/mysql/conf.d/下有之前自定义的mysql.cnf配置文件,我们可以通过修改此宿主机的配置文件影响/etc/mysql/mysql.conf.d/mysql.cnf目录的内容,而my.cnf中又引入了此文件,也就达到了映射配置文件的目的:

bash-4.2# ls /etc/mysql/conf.d/
mysql.conf

下面就进入到关键的验证宿主配置影响容器运行的mysql配置环节。

容器安装vim

我们首先会想到直接修改/etc/mysql/mysql.conf.d/XXX.cnf文件,但是docker的镜像是没有vim的,执行通常都会报错。

在容器当中执行下面的命令可以让其具备修改文件的能力。

yum install -y vim

或者

yum install -y vi

之后就可以使用vi或者vim的命令了。注意不同的Mysql的镜像版本配置文件的存储位置和内容可能存在差别,以上的配置仅为个人机器的实际部署情况。

另外还需要注意vim命令会在重新部署mysql的容器失效,这是docker本身设计导致,个人未找到快捷方案,只能说尽量避免容器内操作和修改文件,在部署容器的时候做好宿主机的配置映射。

docker mysql允许外部远程访问

由于下文的实验中需要用到主机远程访问虚拟机docker的mysql数据库,为了确保验证结果不会受到外部原因的干扰,需要在docker的mysql当中支持root用户远程连接mysql数据库。

生产中禁止root身份远程访问mysql数据库。

grant all privileges on *.* to 'root'@'%' identified by '修改为对应系统的密码' with grant option;  

操作完成之后刷新:

flush privileges;

设置之后就可以远程访问,如果无法访问则检查Linux防火墙设置,或者直接把防火墙关了。

systemctl stop firewalld

上面方式重启Linux服务器之后会重新启动防火墙,永久关闭方式如下。

systemctl disable firewalld

最后我们用navicat连接测试,注意这里的端口号是13306。

为什么这里笔者不使用默认端口?源自过去玩了十多年Linux的大佬同事建议,10000以内的端口经常被各种开源中间件使用,确保防止端口不冲突给开源中间件的启动端口号前面加个1是个好习惯

image.png

验证映射文件 cnf 配置是否生效

修改宿主机映射文件 cnf 配置

如果在容器内部进行配置修改/etc/my.cnf,那么重新部署mysql容器之后所有的改动都会还原,docker环境中要永久生效建议使用映射配置文件到宿主机器的方式。

那么要如何配置?这里回到开头介绍的docker启动脚本的映射配置/opt/mysql/conf:/etc/mysql/conf.d,我们可以在/opt/mysql/conf新建*.cnf文件的方式,在宿主机当中修改容器的mysql配置。

重新部署容器之后,安装过的vim等命令也会一同消失.....

vim /opt/mysql/conf/mysql.cnf

在容器当中对应的配置文件路径如下:

bash-4.2# ls /etc/mysql/conf.d/
mysql.cnf

修改mysql.cnf,我们在里面进行一些极端设置,比如整个服务器的最大连接数设置为0

[mysqld]
# sort 缓冲
sort_buffer_size = 16M
# read缓冲
read_rnd_buffer_size = 2M
# 最大连接数,为了测试是否生效,这里暂时改为0,但是测试完成之后需要修改回来
max_connections = 0

需要注意的是,MySQL允许的最大连接数实际为:max_connections+1,因为这超出的一个用户其实是作为超级管理员来使用的。

也就是说如果我们设置为 0,max_connections 实际上为 1(下面的实验也可以验证),因为要预留给 root操作权限。

验证是否生效

上面我们尝试修改服务器最大连接数为0,这个配置意味着只允许一个(基本是给root)客户端访问,我们可以通过show varibales like "max_connections";或者在两个客户端连接进行测试,验证宿主机的修改是否可以影响到docker内的Mysql。

  1. 最简单的方式是直接重启mysql容器:
[root@localhost xander]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED       STATUS          PORTS                                                    NAMES
38114e273e5a   mysql:5.7   "docker-entrypoint.s…"   2 hours ago   Up 27 minutes   33060/tcp, 0.0.0.0:13306->3306/tcp, :::13306->3306/tcp   mysql57
[root@localhost xander]# docker restart 38114e273e5a

之后我们使用docker exec -it xxx /bin/bash,然后mysql -uroot -p的方式连接到服务端,使用show variables like 'max_connections';检查连接数是否被修改,如果是默认值151说明配置存在问题。

mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 1     |
+-----------------+-------+
1 row in set (0.06 sec)
  1. 如果想要验证部署mysql之后配置是否依然生效,可以把容器删除重新部署。
[root@localhost conf]# docker rm 761f4d17ddf4
761f4d17ddf4
  1. 镜像被删除,重新跑一遍运行容器的参数。
docker run -p 13306:3306 --name mysql57 --restart=always -v /opt/mysql/conf:/etc/mysql/conf.d -v /opt/mysql/logs:/logs -v /opt/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7
[root@localhost xander]# docker run -p 13306:3306 --name mysql57 --restart=always -v /opt/mysql/conf:/etc/mysql/conf.d -v /opt/mysql/logs:/logs -v /opt/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7
58fa52f21404dc8e070bade7cc8f38dbc4a585c1fb1157443f03652bb640c076
  1. 我们查看新部署的mysql容器ID,之后进入到容器内。
[root@localhost conf]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                                                    NAMES
38114e273e5a   mysql:5.7   "docker-entrypoint.s…"   3 seconds ago   Up 2 seconds   33060/tcp, 0.0.0.0:13306->3306/tcp, :::13306->3306/tcp   mysql57

进入到容器内:

docker exec -it 38114e273e5a /bin/bash
  1. 进入到容器之后我们直接连接mysq,使用show variables like 'max_connections';检查连接数是否被修改。
bash-4.2# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.41 MySQL Community Server (GPL)

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

查看系统参数发现配置依然是生效的:

mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 1     |
+-----------------+-------+
1 row in set (0.01 sec)
  1. 看起来不管是重新部署还是重启容器都是成功生效的。
  2. 这里再补充如何用两个客户端连接测试,注意因为个人的Mysql在Linux的虚拟的docker中安装,可以尝试主机用神器软件navicat访问。端口是13306。
    需要注意在连接之前,我们要用Linux的容器连接客户端占用一个connection客户端。之后主机用navicat连接会频繁报错:
image.png
  1. 上面的实验结果可以确定我们修改宿主机文件成功影响到docker容器内部的配置。当然测试完成之后记得改回来,否则mysql容器就没法正常用了。

从这个实验也可以说明,max_connections 永远会预留一个连接入口(给root使用)。

问题

自定义映射不生效?

个人查找到某一篇stackflow的文章看到如下对话,基本上属于文件命名的问题:

It turns out that on top of requiring a.cnfending for files in!include(and!includedir), you also can't have extra dots. The solution was to change the filename frommy.cnf.localtomy-local.cnf.

事实证明,除了要求 !include(和 !includir)中的文件以 .cnf 结尾之外,也不能有额外的点。最稳妥解决办法是将文件名从my.cnf.local改为my-local.cnf。

为什么映射的配置修改不生效。

哪怕是做了文件映射,依然有可能碰到max_connections参数修改无效的情况,下面是一些解决思路:

  1. 确保*.cnf*文件配置正确,这一点可以通过搜集网络资料和官方文档解决,比如mysql的官方文档介绍如下:

引自:MySQL :: MySQL 8.0 Reference Manual :: 5.1.8 Server System Variables

  • max_connections Command-Line Format --max-connections=#
    System Variable max_connections  
    Scope Global  
    Dynamic Yes  
    SET_VARHint Applies No  
    Type Integer  
    Default Value 151  
    Minimum Value 1  
    Maximum Value 100000  

The maximum permitted number of simultaneous client connections. The maximum effective value is the lesser of the effective value ofopen_files_limit- 810, and the value actually set formax_connections.

注意:max_connections 实际生效值是open_files_limitmax_connections当中较小者。

For more information, seeSection5.1.12.1, “Connection Interfaces”.

  1. 确保配置文件的后缀是.cnf。为什么是.cnf?我只能说是官方规定和要求没有为什么,文件名称可以随便起,但是后缀必须固定为.cnf
  2. 确保是否重启容器。

[Warning] skipping '!includedir /etc/mysql/conf.d/' directive as maximum.....

个人在实验过程中连接docker的mysql出现如下的报错。

bash-4.2# mysql -uroot -p
mysql: [Warning] skipping '!includedir /etc/mysql/conf.d/' directive as maximum includerecursion level was reached in file /etc/mysql/conf.d/mysql.cnf at line 41!
mysql: [Warning] skipping '!includedir /etc/mysql/mysql.conf.d/' directive as maximum includerecursion level was reached in file /etc/mysql/conf.d/mysql.cnf at line 42!

经过谷歌搜索并没有找到这个报错的原因,但是想到之前的mysql.cnf配置是从容器的my.cnf原样拷贝的,怀疑是拷贝的配置文件格式某一处有错误,所以把其他所有的干扰项删除只保留了自定义的部分,再次尝试之后发现这个报错就再也没有出现过了。

too many connections....

如果照着本文操作,那么最后的配置肯定是max_connections=0,实验完成之后记得把这个参数配置修改回去。比如本地学习可以大胆点开放个10024,当然生产根据情况设置

mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 10024 |
+-----------------+-------+
1 row in set (0.07 sec)

写到最后

以上内容可能在不同的用户机器会有不同的表现,一切请以个人的运行情况为准,如果遇到问题查阅Mysql的官方文档是非常必要的。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门