Docker 最佳实战:Docker 部署单节点 MySQL 实战

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. 课后练习

根据本文所学,请完成以下实战任务。

  1. 手工部署单节点 MySQL 服务
  2. 使用自动化脚本部署单节点 MySQL 服务
  3. 修改自定义 mysql 配置文件,启动 MySQL 并验证参数是否正确配置
  4. 使用命令行验证测试 MySQL 服务可用性及状态

7. 总结

本文分享了基于 Docker 官方提供的 MySQL 镜像部署 MySQL 服务的详细流程及注意事项。主要内容概括如下:

  • 单节点 MySQL 服务部署
  • 单节点 MySQL 服务自动化部署脚本编写
  • 自定义 MySQL 配置文件的实现方案
  • MySQL 服务可用性验证测试

Get 本文实战视频(请注意,文档视频异步发行,请先关注)

免责声明:

  • 笔者水平有限,尽管经过多次验证和检查,尽力确保内容的准确性,但仍可能存在疏漏之处。敬请业界专家大佬不吝指教。
  • 本文所述内容仅通过实战环境验证测试,读者可学习、借鉴,但严禁直接用于生产环境由此引发的任何问题,作者概不负责

结束语

如果你喜欢本文,请分享、收藏、点赞、评论! 请持续关注 @ 运维有术,及时收看更多好文!

欢迎加入 「运维有术·云原生实战训练营」 ,获取更多的 KubeSphere、Kubernetes、云原生运维、自动化运维等实战技能。

版权声明

  • 所有内容均属于原创,感谢阅读、收藏,转载请联系授权,未经授权不得转载
相关推荐
涔溪2 小时前
Docker简介
spring cloud·docker·eureka
内核程序员kevin3 小时前
在Linux环境下使用Docker打包和发布.NET程序并配合MySQL部署
linux·mysql·docker·.net
CodingBrother4 小时前
MySQL 中的 `IN`、`EXISTS` 区别与性能分析
数据库·mysql
kayotin4 小时前
Wordpress博客配置2024
linux·mysql·docker
甄臻9245 小时前
Windows下mysql数据库备份策略
数据库·mysql
杀神lwz5 小时前
Java 正则表达式
java·mysql·正则表达式
山南2375 小时前
MySql-8.0.40安装详细教程
mysql
运维&陈同学5 小时前
【模块一】kubernetes容器编排进阶实战之k8s基础概念
运维·docker·云原生·容器·kubernetes·云计算
mit6.8246 小时前
[Docker#4] 镜像仓库 | 部分常用命令
linux·运维·docker·容器·架构
十言_6 小时前
MySQL远端访问
数据库·mysql