Docker 最佳实战:Docker 部署单节点 MySQL 实战
2024 年云原生运维实战文档 99 篇原创计划 第 006 篇 |Docker 最佳实战「2024」系列 第 006 篇
前言
你好,欢迎来到运维有术。
今天分享的内容是 Docker 最佳实战「2024」 系列文档中的 Docker 部署单节点 MySQL 实战。
内容导图
实战服务器配置 (架构 1:1 复刻小规模生产环境,配置略有不同)
主机名 | IP | CPU(核) | 内存(GB) | 系统盘(GB) | 数据盘(GB) | 用途 |
---|---|---|---|---|---|---|
docker-node-1 | 192.168.9.81 | 4 | 16 | 40 | 100 | Docker 节点 1 |
docker-node-2 | 192.168.9.82 | 4 | 16 | 40 | 100 | Docker 节点 2 |
docker-node-3 | 192.168.9.83 | 4 | 16 | 40 | 100 | Docker 节点 3 |
合计 | 3 | 12 | 48 | 120 | 300 |
实战环境涉及软件版本信息
- 操作系统:openEuler 22.03 LTS SP3
- Docker:24.0.7
- Containerd:1.6.27
- MySQL:5.7.44
1. 前提说明
主流的 MySQL 有 5.7.x 和 8.0.x 两个版本,具体选择哪个版本需要根据项目需求确定,如果不确定或是新开发的项目,建议选择 8.0 的最新版。
考虑到后续的实战课程,本文选择了 5.7.x 的最新版 5.7.44。
目前主流的 mysql 5.7.x 容器化部署方案可用的容器有以下几种:
- docker 官方提供:
mysql:5.7.44
- bitnami 提供:
bitnami/mysql:5.7.43
本系列实战文档选择镜像的策略是:优先使用 docker 官方或软件提供商官方镜像。
因此,本文选择 docker 官方提供的 mysql:5.7.44
镜像。
2. 单节点 MySQL 部署实战
2.1 创建 MySQL 数据目录
arduino
mkdir -p /data/containers/mysql/{data,config}
- data 目录:存储容器持久化数据
- config 目录: 配置文件目录
2.2 创建 MySQL 自定义配置文件
默认安装的 MySQL 使用的 my.cnf 配置文件,适配的使用场景有限,所以自定义 MySQL 配置文件是必然要做的一项配置。
这里我随机找了一份配置文件,仅仅是为了实现自定义配置的功能,请根据自己的使用场景自定义配置文件。
创建自定义 MySQL 配置文件,vi /data/containers/mysql/config/mysqld.conf
ini
[mysqld]
# performance setttings
lock_wait_timeout = 3600
open_files_limit = 65535
back_log = 1024
max_connections = 512
max_connect_errors = 1000000
table_open_cache = 1024
table_definition_cache = 1024
thread_stack = 512K
sort_buffer_size = 4M
join_buffer_size = 4M
read_buffer_size = 8M
read_rnd_buffer_size = 4M
bulk_insert_buffer_size = 64M
thread_cache_size = 768
interactive_timeout = 600
wait_timeout = 600
tmp_table_size = 32M
max_heap_table_size = 32M
innodb_open_files = 1024
# TLS 配置
tls_version = TLSv1.2
2.3 创建 docker-compose 文件
yaml
version: '3'
services:
mysql:
container_name: mysql
image: mysql:5.7.44
ulimits:
nofile:
soft: 65536
hard: 65536
environment:
- TZ=Asia/Shanghai
- MYSQL_ROOT_PASSWORD=Db@2024!
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/data:/var/lib/mysql
- ${DOCKER_VOLUME_DIRECTORY:-.}/config:/etc/mysql/conf.d/
ports:
- 3306:3306
restart: always
networks:
default:
name: mysql-tier
driver: bridge
参数说明:
- MYSQL_ROOT_PASSWORDD: 默认管理员 root 用户密码
- volumes 将自定义的 MySQL 配置文件挂载到容器中的 /etc/mysql/conf.d/ 目录下
- ulimits 设置最大的文件打开数,用于提高 MySQL 服务的性能
2.4 创建并启动 MySQL 服务
- 启动服务
bash
cd /data/containers/mysql
docker compose up -d
- 正确启动的结果如下
ini
[root@docker-node-1 mysql]# docker compose up -d
[+] Running 1/2
⠼ Network mysql-tier Created 0.4s
✔ Container mysql Started
2.5 验证容器状态
- 查看 mysql 容器状态
bash
[root@docker-node-1 mysql]# docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
mysql mysql:5.7.44 "docker-entrypoint.s..." mysql 7 seconds ago Up 6 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp
- 查看 mysql 服务日志
bash
# 通过日志查看 mysql 是否有异常,结果略
docker compose logs -f
3. MySQL 服务可用性测试
为了测试 MySQL 服务的可用性,利用 Docker 创建一个 MySQL 客户端容器实例,并执行几个简单的查询命令。
- 创建 MySQL 客户端实例
css
docker run -it --rm --network mysql-tier mysql:5.7.44 mysql -h 192.168.9.81 -uroot -p
- 查看进程列表
sql
mysql> show processlist;
+----+------+------------------+------+---------+------+----------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+------------------+------+---------+------+----------+------------------+
| 4 | root | 172.26.0.1:46442 | NULL | Query | 0 | starting | show processlist |
+----+------+------------------+------+---------+------+----------+------------------+
1 row in set (0.00 sec)
- 查看当前连接情况
sql
mysql> show status like '%conn%';
+-----------------------------------------------+---------------------+
| Variable_name | Value |
+-----------------------------------------------+---------------------+
| Aborted_connects | 2 |
| Connection_errors_accept | 0 |
| Connection_errors_internal | 0 |
| Connection_errors_max_connections | 0 |
| Connection_errors_peer_address | 0 |
| Connection_errors_select | 0 |
| Connection_errors_tcpwrap | 0 |
| Connections | 5 |
| Locked_connects | 0 |
| Max_used_connections | 1 |
| Max_used_connections_time | 2024-04-02 14:12:17 |
| Performance_schema_session_connect_attrs_lost | 0 |
| Ssl_client_connects | 0 |
| Ssl_connect_renegotiates | 0 |
| Ssl_finished_connects | 0 |
| Threads_connected | 1 |
+-----------------------------------------------+---------------------+
16 rows in set (0.01 sec)
4. 自动化 Shell 脚本
全文所有的操作,我都整理成了自动化脚本:
- 配环境变量模式
deploy-mysql.sh
ini
#!/bin/bash
# author:@运维有术
set -e
# 设置 mysql 服务名称,必须修改
services_name=${1:-"mysql"}
# 设置 containers 基础目录,可选修改
docker_container_dir=${2:-"/data/containers"}
# 创建基础目录
mkdir -p ${docker_container_dir}/${services_name}/{data,config}
# 创建 mysql 配置文件
function deploy_services_config(){
cat > ${docker_container_dir}/${services_name}/config/mysqld.cnf <<-EOF
[mysqld]
# performance setttings
lock_wait_timeout = 3600
open_files_limit = 65535
back_log = 1024
max_connections = 512
max_connect_errors = 1000000
table_open_cache = 1024
table_definition_cache = 1024
thread_stack = 512K
sort_buffer_size = 4M
join_buffer_size = 4M
read_buffer_size = 8M
read_rnd_buffer_size = 4M
bulk_insert_buffer_size = 64M
thread_cache_size = 768
interactive_timeout = 600
wait_timeout = 600
tmp_table_size = 32M
max_heap_table_size = 32M
innodb_open_files = 1024
# TLS 配置
tls_version = TLSv1.2
EOF
}
# 创建 docker-compose 文件
function deploy_compose_config(){
cat > ${docker_container_dir}/${services_name}/docker-compose.yml <<-EOF
version: '3'
services:
${services_name}:
container_name: ${services_name}
image: mysql:5.7.44
environment:
- TZ=Asia/Shanghai
- MYSQL_ROOT_PASSWORD=Db@2024!
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/data:/var/lib/mysql
- ${DOCKER_VOLUME_DIRECTORY:-.}/config:/etc/mysql/conf.d/
ports:
- 3306:3306
restart: always
networks:
default:
name: ${services_name}-tier
driver: bridge
EOF
}
# 创建 mysql 服务
function deploy_services(){
cd ${docker_container_dir}/${services_name}
docker compose up -d
}
# 验证 mysql 服务
function check_services(){
cd ${docker_container_dir}/${services_name}
docker compose ps
}
echo -e "\033[1;32m [1].Deploy ${services_name} services config.\n \033[0m"
deploy_services_config
echo -e "\033[1;32m [2].Deploy docker compose config.\n \033[0m"
deploy_compose_config
echo -e "\033[1;32m [3].Deploy ${services_name} service.\n \033[0m"
deploy_services
echo -e "\033[1;32m [4].Check ${services_name} service status. \033[0m"
check_services
说明: 由于调试过程中没有解决 EOF 报错的问题,function 里 cat 部分的内容没有缩进,看着不美观,但是不影响使用。
5. 常见问题
5.1 问题 1
- 问题现象
MySQL 日志里有如下告警信息 :
csharp
[Warning] A deprecated TLS version TLSv1 is enabled. Please use TLSv1.2 or higher.
[Warning] A deprecated TLS version TLSv1.1 is enabled. Please use TLSv1.2 or higher.
- 解决方案
这个只是 TLS 配置的告警信息,不影响实际使用,从 MySQL 5.7.35 开始,TLSv1 和 TLSv1.1 连接协议已弃用,使用 TLS 1.2 几更高版本加密客户端与 MySQL 数据库实例的连接,并且在未来的 MySQL 版本中将删除对它们的支持。
MySQL 进行 SSL/TLS 连接的更多信息,请参阅 MySQL 文档中的使用加密连接。
bash
# 在 my.cnf 配置文件中添加配置项,设置仅允许 tls 1.2, 可通过逗号设置多个 tls 版本
echo "tls_version = TLSv1.2" >> /etc/my.cnf
5.2 问题 2
- 问题现象
MySQL 日志里有如下告警信息 :
css
[Warning] Could not increase number of max_open_files to more than 64 (request: 65535)
- 解决方案
由于容器启动时没有使用 ulimit 设置文件资源限制,因此受默认的文件描述符限制 mysql 配置文件中的 open_files_limit 配置项不生效。需要在启动容器时增加 ulimits 配置项。
java
# 默认的 ulimit 配置,看着很大实际没生效。
bash-4.2# ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 29604
max locked memory (kbytes, -l) 65536
max memory size (kbytes, -m) unlimited
open files (-n) 1073741816
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) unlimited
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
# 在 docker-compose.yml 文件中加入以下内容
ulimits:
nofile:
soft: 65536
hard: 65536
6. 课后练习
根据本文所学,请完成以下实战任务。
- 手工部署单节点 MySQL 服务
- 使用自动化脚本部署单节点 MySQL 服务
- 修改自定义 mysql 配置文件,启动 MySQL 并验证参数是否正确配置
- 使用命令行验证测试 MySQL 服务可用性及状态
7. 总结
本文分享了基于 Docker 官方提供的 MySQL 镜像部署 MySQL 服务的详细流程及注意事项。主要内容概括如下:
- 单节点 MySQL 服务部署
- 单节点 MySQL 服务自动化部署脚本编写
- 自定义 MySQL 配置文件的实现方案
- MySQL 服务可用性验证测试
Get 本文实战视频(请注意,文档视频异步发行,请先关注)
免责声明:
- 笔者水平有限,尽管经过多次验证和检查,尽力确保内容的准确性,但仍可能存在疏漏之处。敬请业界专家大佬不吝指教。
- 本文所述内容仅通过实战环境验证测试,读者可学习、借鉴,但严禁直接用于生产环境 。由此引发的任何问题,作者概不负责!
结束语
如果你喜欢本文,请分享、收藏、点赞、评论! 请持续关注 @ 运维有术,及时收看更多好文!
欢迎加入 「运维有术·云原生实战训练营」 ,获取更多的 KubeSphere、Kubernetes、云原生运维、自动化运维等实战技能。
版权声明
- 所有内容均属于原创,感谢阅读、收藏,转载请联系授权,未经授权不得转载。