
我们就可以到 docker hub 来看:

点击后的页面:

直接执行docker pull mysql,会下载最新版本的 MySQL。
点击 tags,找到并下载经典的 MySQL5.7:

[root@service-monitoring ~]# docker pull mysql:5.7.42-oracle
5.7.42-oracle: Pulling from library/mysql
e83e8f2e82cc: Pull complete
0f23deb01b84: Pull complete
f5bda3b184ea: Pull complete
ed17edbc6604: Pull complete
33a94a6acfa7: Pull complete
f153bd2953e4: Pull complete
ab532edfb813: Pull complete
c76bdfe4f3d0: Pull complete
8a7ffe2f2551: Pull complete
857ada4fbbcc: Pull complete
b7c508404c3c: Pull complete
Digest: sha256:f57eef421000aaf8332a91ab0b6c96b3c83ed2a981c29e6528b21ce10197cd16
Status: Downloaded newer image for mysql:5.7.42-oracle
docker.io/library/mysql:5.7.42-oracle
[root@service-monitoring ~]# 在虚拟机中执行 ipv4 命令的主要目的是配置虚拟机的网络接口,使其能够正常地连接到网络。IPv4 是当前广泛使用的 IP 协议,它是 Internet 协议族中的一员,用于在互联网上标识和定位网络设备。在虚拟化环境中,虚拟机需要一个唯一的 IPv4 地址,以便与其他设备进行通信。
通过执行 ipv4 命令,可以为虚拟机配置 IPv4 地址、子网掩码、网关等网络参数。这些参数将决定虚拟机如何与其他设备进行通信。例如,如果虚拟机的 IP 地址与其他设备的 IP 地址不在同一个子网中,那么它们就无法直接通信,需要通过网关进行转发。
总之,执行 ipv4 命令可以帮助虚拟机正确地配置网络参数,使其能够正常地连接到网络,并与其他设备进行通信。而若使用的云服务器,默认已经开启了,无需再配置了。
[root@service-monitoring ~]# vim /usr/lib/sysctl.d/00-system.conf添加:
net.ipv4_forward=1
由于修改了网络相关, 所以必须重启对应服务:
systemctl restart network;
systemctl restart docker;# 将容器的 3306 端口映射到主机的 3306 端口,这样就可以通过主机的 IP 地址和端口号访问 MySQL 服务。
# 指定容器的名称为 mysql,方便后续管理和操作
[root@service-monitoring home]# docker run -p 3306:3306 --name mysql \
# 将主机的 /home/mysql/log 目录挂载到容器的 /var/log/mysql 目录,用于存储 MySQL 的日志文件。
-v /home/mysql/log:/var/log/mysql \
# 将主机的 /home/mysql/data 目录挂载到容器的 /var/lib/mysql 目录,用于存储 MySQL 的数据文件。
-v /home/mysql/data:/var/lib/mysql \
# 将主机的 /home/mysql/conf 目录挂载到容器的 /etc/mysql 目录,用于存储 MySQL 的配置文件。
-v /home/mysql/conf:/etc/mysql \
# 将主机的 /home/mysql/mysql-files 目录挂载到容器的 /var/lib/mysql-files 目录,用于存储 MySQL 的文件数据。
-v /home/mysql/mysql-files:/var/lib/mysql-files \
# 设置 MySQL 的 root 用户密码为 root。这个参数使用了环境变量来传递密码信息。
-e MYSOL_ROOT_PASSWORD=root \
# 以后台模式运行 MySQL 容器,并使用 mysql:5.7.42-oracle 镜像作为容器镜像。
-d mysql:5.7.42-oracle \
# 设置 MySQL 的字符集为 utf8mb4,并使用 utf8mb4_unicode_ci 排序规则。这个参数可以确保 MySQL 能够正确地处理 Unicode 字符。
--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
# ---命令结束,下面都是输出
# 输出的是容器的 ID,表示容器已成功启动。
ec88509b8b1b8b759747c71b75a9fc6c5c0a8ec63e1e6b7a716a6e98ccce184e
[root@service-monitoring home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@service-monitoring home]# 
MySQL 是exit 态,说明有问题,而且 created 时间和 status 时间基本一致,说明启动就失败了

那就得查看对应容器的日志了:
[root@service-monitoring home]# docker logs mysql
2023-04-26 15:36:12+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.42-1.el7 started.
2023-04-26 15:36:12+00:00 [ERROR] [Entrypoint]: mysqld failed while attempting to check config
command was: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --verbose --help --log-bin-index=/tmp/tmp.lEmtN09BMq
mysqld: Can't read dir of '/etc/mysql/conf.d/' (Errcode: 2 - No such file or directory)
mysqld: [ERROR] Fatal error in defaults handling. Program aborted!
[root@service-monitoring home]# 看来需要调整,去除 etc 启动参数:
# 删除了-v /home/mysql/conf:/etc/mysql \的启动命令:
[root@service-monitoring home]# docker run -p 3306:3306 --name mysql \
-v /home/mysql/log:/var/log/mysql \
-v /home/mysql/data:/var/lib/mysql \
-v /home/mysql/mysql-files:/var/lib/mysql-files \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7.42-oracle \
--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
docker: Error response from daemon: Conflict. The container name "/mysql" is already in use by container "ec88509b8b1b8b759747c71b75a9fc6c5c0a8ec63e1e6b7a716a6e98ccce184e". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.
[root@service-monitoring home]# 当然,意料之中的报错啦,要删除它
[root@service-monitoring home]# docker rm mysql
mysql
[root@service-monitoring home]# 再重新执行启动命令:

再验证下:
[root@service-monitoring home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e380fdc23c78 mysql:5.7.42-oracle "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql
[root@service-monitoring home]# 可算是 up 起来咯!

至此,MySQL成功运行了。
发现已经都帮我们按启动命令,都创建好了对应路径:
[root@service-monitoring mysql]# pwd
/home/mysql
[root@service-monitoring mysql]# ll
total 16
drwxr-xr-x 2 root root 4096 Apr 26 23:36 conf
drwxr-xr-x 5 polkitd root 4096 Apr 26 23:58 data
drwxr-xr-x 2 root root 4096 Apr 26 23:36 log
drwxr-xr-x 2 polkitd root 4096 Apr 26 23:36 mysql-files
[root@service-monitoring mysql]# 可见 docker 安装是真的方便呢!

可实时监控每个容器的状态:
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
e380fdc23c78 mysql 0.05% 208.7MiB / 7.795GiB 2.61% 656B / 0B 1.27MB / 289MB 27
Ctrl+C 退出。
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
e380fdc23c78 mysql 0.06% 208.7MiB / 7.795GiB 2.61% 656B / 0B 1.27MB / 289MB 27
^C
[root@service-monitoring data]# 也是完美:

mysql> alter user 'root'@'localhost' identified with mysql_native_password by 'root';
Query OK, 0 rows affected (0.00 sec)
# 设置密码永存
mysql> alter user 'root'@'%' identified by 'root' password expire never;
# 允许 root 用户从任何主机登录 MySQL 数据库。MySQL默认会限制用户只能从本地主机登录,为增强系统安全性。但在某些情况下,例如需要远程管理 MySQL 数据库时,需将用户的登录主机限制更改为任意主机
mysql> update user set host='%' where user='root';
# 若已设置过,则会报该错
ERROR 1062 (23000): Duplicate entry '%-root' for key 'PRIMARY'
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
# Ctrl+D 退出MySQL
mysql> ^DBye
bash-4.2#考虑如下问题:
一般都会提前规划好 MySQL 集群模式,存储大小,一般都不会做什么应急扩容。而像一些 pass,提供一些云数据库这种是方便向用户收费,他们是云平台,使用 docker 扩容完全没问题。但正常公司不会【频繁】修改 MySQL。
若把容器实例删了,镜像也移除了,MySQL库表数据还在吗?
容器实例是由 Docker 镜像创建的运行实例,而容器内的 MySQL 是运行在该容器实例中的 MySQL 数据库服务。在 Docker 中,每个容器实例都是一个相互隔离的运行环境,可以运行不同的应用程序和服务。因此,当您在 Docker 容器中运行 MySQL 时,MySQL 数据库服务是运行在该容器实例的隔离环境中的,与其他容器实例和主机上的其他进程相互隔离。
若你删除 Docker 容器实例,且该容器实例中的数据没有进行持久化存储,则该容器实例中的数据将会被删除。若你删除 Docker 镜像,那么该镜像的文件系统和历史记录也将被删除,但是该镜像所创建的容器实例中的数据不会受到影响。
容器和镜像是不同东西:
因此,删除容器实例不会影响镜像本身,而删除镜像会影响以该镜像为基础创建的所有容器实例。
所以,我们都会通过磁盘进行挂载,将数据转移存储到宿主机的某目录下。所以我们前文中的启动命令也包括挂载操作,这样可以确保即使容器实例被删除,数据仍然可以被保留下来。
但若我们想实现数据共享,即把数据共享给其他数据库,做数据的共享扩容,而我们刚才挂载的目录显然又是无法被多个数据库共享的,其他数据库是无法写入的,所以无法实现数据共享。因为宿主机上的目录只能被一个容器实例访问和写入,无法实现多个容器实例之间的数据共享。
宿主机上的目录只能被一个容器实例访问和写入,是因为同一时间只有一个进程(或容器实例)可以占用该目录。当你将宿主机上的目录挂载到容器中时,该目录在容器中的访问权限与在宿主机上的访问权限是一致的。若多个容器实例同时访问该目录,就会发生冲突,导致数据的不一致性和损坏。 为解决这问题,可使用一些分布式文件系统,如 GlusterFS、Ceph,将宿主机上的目录转换为一个分布式文件系统,并将其挂载到多个容器实例中。这样就可以实现多个容器实例之间的数据共享和访问。
其它中间件如 cache、mq,大家其实都在同一个服务器内,都会使用内存,就会发生内存竞争,当然你也能限制其它中间件的内存使用阈值,MySQL 自然也很可能无法被分配到足够的内存,无法对当前服务器的内存进行独占,导致对性能有一些影响,这也是一大局限。
在这种情况下,可通过以下方式来优化系统的内存使用:
通过以上措施,有效避免内存竞争和独占问题,并提高系统的性能和可靠性。
数据库是系统的底限,必须全力保证其稳定性。所以最好单独部署,一个 docker容器只部署MySQL。所以推荐使用各种云数据库,运维成本低,也满足三高要求,除了贵这一个缺点。
使用 Docker 部署和配置 MySQL 数据库时,可获得很多好处,如更高可移植性、更好的资源隔离和更好的可伸缩性。Docker 为 MySQL 数据库的部署和管理提供了很多便利,可更轻松管理和维护 MySQL 数据库。
本文介绍了如何使用 Docker 部署和配置 MySQL 数据库,并提供了一些优化性能和避免常见问题的建议。希望这篇文章能够帮助您更好地理解 Docker 和 MySQL 数据库,并在实践中获得更好的体验和效果。