docker compose mysql_使用Docker-compose部署MySQL测试环境

夏新翰
2023-12-01

1.题目部分

使用docker-compose, 创建两个MySQL容器, 满足如下条件:

使用自定义的my.cnf

形成主从复制关系

容器销毁后, 主实例的数据仍保留, 从实例的数据清零销毁

重建两个容器, 主实例沿用之前的数据, 从实例重建数据, 并建立复制

2.解答部分

2.1 docker安装

docker-compose依赖docker环境,需要先安装好docker,本实验环境为在CentOS7虚拟机中安装docker,参考链接:https://docs.docker.com/install/linux/docker-ce/centos/

## 卸载旧版本的docker及相关组件

[root@10-186-61-162 ~]# yum remove docker \

docker-client \

docker-client-latest \

docker-common \

docker-latest \

docker-latest-logrotate \

docker-logrotate \

docker-engine

## 安装yum工具包及docker相关依赖包

[root@10-186-61-162 ~]# yum install -y yum-utils device-mapper-persistent-data lvm2

## 添加docker社区版的软件源(这里将软件源替换为了阿里云提供的软件源,加快镜像下载速度)

[root@10-186-61-162 ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

## 安装并启动docker-ce

[root@10-186-61-162 ~]# yum install docker-ce docker-ce-cli containerd.io

[root@10-186-61-162 ~]# systemctl start docker

[root@10-186-61-162 ~]# systemctl status docker

## 验证docker运行正常

[root@10-186-61-162 ~]# docker --version

Docker version 19.03.6, build 369ce74a3c

[root@10-186-61-162 ~]# docker run hello-world

Unable to find image 'hello-world:latest' locally

latest: Pulling from library/hello-world

1b930d010525: Pull complete

Digest: sha256:9572f7cdcee8591948c2963463447a53466950b3fc15a247fcad1917ca215a2f

Status: Downloaded newer image for hello-world:latest

## 有以下输出表示docker安装且运行正常

Hello from Docker!

This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:

1. The Docker client contacted the Docker daemon.

2. The Docker daemon pulled the "hello-world" image from the Docker Hub.

(amd64)

3. The Docker daemon created a new container from that image which runs the

executable that produces the output you are currently reading.

4. The Docker daemon streamed that output to the Docker client, which sent it

to your terminal.

To try something more ambitious, you can run an Ubuntu container with:

$ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:

https://hub.docker.com/

For more examples and ideas, visit:

https://docs.docker.com/get-started/

2.2 docker-compose 安装

docker-compose是一个用来编排多个容器的工具,我们可以编辑一个YMAL格式的配置文件,将多个容器的配置写入,使用compose工具来统一启停维护。安装参考链接:

## 直接使用官方链接提供的下载命令下载1.23.3版本docker-compose并保存到/usr/local/bin/docker-compose

curl -L "https://github.com/docker/compose/releases/download/1.25.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

## 对docker-compose增加可执行权限

chmod +x /usr/local/bin/docker-compose

## 验证docker版本

[root@10-186-61-162 ~]# docker-compose --version

docker-compose version 1.25.3, build d4d1b42b

2.3 docker-compose 配置

在编排前需规划好相关运行目录及my.cnf配置文件

## 创建docker-compose编排MySQL的系统目录便于维护管理

[root@10-186-61-162 mysql]# mkdir -p /data/docker-compose/mysql

## 在该目录下创建主从需要的文件及目录

[root@10-186-61-162 mysql]# pwd

/data/docker-compose/mysql

[root@10-186-61-162 mysql]# tree -L 2

.

├── docker-compose.yml ## MySQL主从编排的配置文件

├── master

│ ├── data ## master节点保留数据,数据用volumes的方式保留在宿主机本地,需要额外创建data目录

│ ├── init_sql ## 在MySQL初始化完成后需要执行的SQL文件目录,目录下包含创建的初始化用户、数据库、表及测试数据等。

│ └── my.cnf ## 自定义的MySQL配置文件

└── slave

├── init_sql

└── my.cnf

2.3.1 init.sql内容

master节点

创建一个repl用户做复制同步使用

创建一个测试库zhenxing并在其中创建一张t1表插入少量数据

slave节点

reset master清除执行的基础操作产生的GTID信息

change master to指向master节点建立主从复制同步连接

## master节点的初始化sql文件

[root@10-186-61-162 init_sql]# pwd

/data/docker-compose/mysql/master/init_sql

[root@10-186-61-162 init_sql]# cat init.sql

create user 'repl'@'%' identified by 'repl';

grant replication client,replication slave on *.* to 'repl'@'%';

create database zhenxing;

use zhenxing;

create table t1(id int primary key auto_increment,username varchar(20));

insert into t1(username) values('yuzhenxing'),('zhenxingyu');

## slave节点的初始化sql文件

[root@10-186-61-162 init_sql]# pwd

/data/docker-compose/mysql/slave/init_sql

[root@10-186-61-162 init_sql]# cat init.sql

reset master;

CHANGE MASTER TO MASTER_HOST='172.20.0.10',MASTER_USER='repl',MASTER_PASSWORD='repl',MASTER_PORT=3306,MASTER_AUTO_POSITION=1;

start slave;

2.3.2 my.cnf配置文件

其中除server_id与从库不一样以外,其他参数均一致

[mysqld]

# Base Config

server_id = 1623306

user= mysql

port= 3306

default_storage_engine= InnoDB

character_set_server= utf8mb4

# skip_slave_start= 1 ## 该参数需要注释,不然docker调用初始化脚本时不会触发start slave开启主从复制同步

skip-name-resolve= 1

skip-external-locking= 1

lower_case_table_names= 1

query_cache_type = 0

query_cache_size = 0

max_connections= 1000

default-time-zone = '+8:00'

log_timestamps= SYSTEM

# InnoDB config

innodb_strict_mode= 1

innodb_file_per_table= 1

innodb_stats_on_metadata= 0

innodb_flush_method= O_DIRECT

innodb_log_files_in_group= 3

innodb_data_file_path= ibdata1:128M:autoextend

innodb_buffer_pool_size= 128M

innodb_log_file_size= 32M

innodb_log_buffer_size= 8M

innodb_max_dirty_pages_pct= 60

innodb_io_capacity= 200

innodb_buffer_pool_instances= 8

innodb_buffer_pool_load_at_startup= 1

innodb_buffer_pool_dump_at_shutdown= 1

innodb_undo_logs = 128

innodb_undo_tablespaces= 3

innodb_flush_neighbors= 1

# Cache config

key_buffer_size= 8M

tmp_table_size= 8M

max_heap_table_size= 8M

thread_cache_size= 1000

table_open_cache= 2048

open_files_limit= 65535

max_allowed_packet= 64M

# Log config

log_error= mysql-error.log

slow_query_log_file= mysql-slow.log

relay-log= mysql-relay

log-bin= mysql-bin

slow_query_log= 1

long_query_time= 0.2

#log_slow_admin_statements= 1

#log_slow_slave_statements= 1

# Replication config

slave-parallel-type= LOGICAL_CLOCK

slave-parallel-workers= 4

expire_logs_days= 14

binlog_format= row

log_slave_updates= ON

binlog_checksum= NONE

max_binlog_size= 250M

binlog_cache_size= 2M

sync_binlog= 1

innodb_flush_log_at_trx_commit = 1

relay-log-info-repository= TABLE

master_info_repository= TABLE

relay_log_recovery= 1

binlog_rows_query_log_events= 1

log_bin_trust_function_creators = 1

# GTID

gtid-mode= ON

enforce-gtid-consistency= 1

# Performance Schema

performance-schema-instrument = 'wait/lock/metadata/sql/mdl=ON'

2.3.3 docker-compose.yml

采用MySQL5.7.29版本数据库

主从配置文件均采用自定义的配置文件

主库的数据目录采用宿主机上创建的data目录

将init_sql下的文件映射到/docker-entrypoint-initdb.d下(注:/docker-entrypoint-initdb.d下以sql或sh结尾的文件会在数据库初始化完成后自动执行)

[root@10-186-61-162 mysql]# cat docker-compose.yml

version: '3.7'

networks:

mysql_net:

name: mysql_net

driver: bridge

ipam:

driver: default

config:

- subnet: 172.20.0.1/24

services:

master:

networks:

mysql_net:

ipv4_address: 172.20.0.10

image: mysql:5.7.29

restart: always

environment:

MYSQL_ROOT_PASSWORD: oracle

hostname: 172-20-0-10

container_name: 172-20-0-10

volumes:

- "./master/my.cnf:/etc/my.cnf"

- "./master/data:/var/lib/mysql"

- "./master/init_sql:/docker-entrypoint-initdb.d/"

slave:

networks:

mysql_net:

ipv4_address: 172.20.0.11

image: mysql:5.7.29

restart: always

environment:

MYSQL_ROOT_PASSWORD: oracle

hostname: 172-20-0-11

container_name: 172-20-0-11

volumes:

- "./slave/my.cnf:/etc/my.cnf"

- "./slave/init_sql:/docker-entrypoint-initdb.d/"

2.4 docker-compose运行

当相关配置文件编辑完成后,即可启动docker-compose

## 使用docker-compose后台方式创建容器

[root@10-186-61-162 mysql]# cd /data/docker-compose/mysql

[root@10-186-61-162 mysql]# docker-compose up -d

Creating network "mysql_net" with driver "bridge"

Creating 172-20-0-11 ... done

Creating 172-20-0-10 ... done

## 查看mysql_net自定义网络

[root@10-186-61-162 mysql]# docker network ls

NETWORK ID NAME DRIVER SCOPE

d5072726a5c8 bridge bridge local

3443080f11fc host host local

deda6b29ddd0 mysql_net bridge local

25391fba169c none null local

c4aeb18be8c4 root_default bridge local

## 查看当前网络组下各节点对应具体IP

[root@10-186-61-162 mysql]# docker network inspect mysql_net |egrep "IPv4Address|Name"

"Name": "mysql_net",

"Name": "172-20-0-10",

"IPv4Address": "172.20.0.10/16",

"Name": "172-20-0-11",

"IPv4Address": "172.20.0.11/16",

## 使用docker ps命令可以看到当前运行的容器状态

[root@10-186-61-162 mysql]# docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

e1f7ff7f1e2e mysql:5.7.29 "docker-entrypoint.s…" 4 minutes ago Up 4 minutes 3306/tcp, 33060/tcp 172-20-0-11

af1fe13e199d mysql:5.7.29 "docker-entrypoint.s…" 4 minutes ago Up 4 minutes 3306/tcp, 33060/tcp 172-20-0-10

## 也可使用docker-compose的ps命令查看状态

[root@10-186-61-162 mysql]# docker-compose ps

Name Command State Ports

-----------------------------------------------------------------------

172-20-0-10 docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp

172-20-0-11 docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp

## 访问数据库主节点,数据均初始化成功

[root@10-186-61-162 mysql]# mysql -h172.20.0.10 -uroot -P3306 -poracle

mysql> show databases;

+--------------------+

| Database |

+--------------------+

| information_schema |

| mysql |

| performance_schema |

| sys |

| zhenxing |

+--------------------+

5 rows in set (0.01 sec)

mysql> select * from zhenxing.t1;

+----+------------+

| id | username |

+----+------------+

| 1 | yuzhenxing |

| 2 | zhenxingyu |

+----+------------+

2 rows in set (0.01 sec)

## 访问MySQL从库,从库为空实例

[root@10-186-61-162 mysql]# mysql -h172.20.0.11 -uroot -P3306 -poracle

mysql> show databases;

+--------------------+

| Database |

+--------------------+

| information_schema |

| mysql |

| performance_schema |

| sys |

+--------------------+

4 rows in set (0.00 sec)

## 主从同步正常

mysql> show slave status\G

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 172.20.0.10

Master_User: repl

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000004

Read_Master_Log_Pos: 190

Relay_Log_File: mysql-relay.000006

Relay_Log_Pos: 395

Relay_Master_Log_File: mysql-bin.000004

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

Replicate_Do_DB:

Replicate_Ignore_DB:

Replicate_Do_Table:

Replicate_Ignore_Table:

Replicate_Wild_Do_Table:

Replicate_Wild_Ignore_Table:

Last_Errno: 0

Last_Error:

Skip_Counter: 0

Exec_Master_Log_Pos: 190

Relay_Log_Space: 835

Until_Condition: None

Until_Log_File:

Until_Log_Pos: 0

Master_SSL_Allowed: No

Master_SSL_CA_File:

Master_SSL_CA_Path:

Master_SSL_Cert:

Master_SSL_Cipher:

Master_SSL_Key:

Seconds_Behind_Master: 0

Master_SSL_Verify_Server_Cert: No

Last_IO_Errno: 0

Last_IO_Error:

Last_SQL_Errno: 0

Last_SQL_Error:

Replicate_Ignore_Server_Ids:

Master_Server_Id: 1623306

Master_UUID: 72aa5e86-51ff-11ea-8a5a-0242ac14000a

Master_Info_File: mysql.slave_master_info

SQL_Delay: 0

SQL_Remaining_Delay: NULL

Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates

Master_Retry_Count: 86400

Master_Bind:

Last_IO_Error_Timestamp:

Last_SQL_Error_Timestamp:

Master_SSL_Crl:

Master_SSL_Crlpath:

Retrieved_Gtid_Set: 72aa5e86-51ff-11ea-8a5a-0242ac14000a:2-10

Executed_Gtid_Set: 72aa5e86-51ff-11ea-8a5a-0242ac14000a:1-10

Auto_Position: 1

Replicate_Rewrite_DB:

Channel_Name:

Master_TLS_Version:

1 row in set (0.00 sec)

2.5 重置容器并保存master节点数据

因为主节点数据保存在容器外宿主机上,可直接将容器删除,再重新构建时指定容器使用已存在的数据即可完成构建。不会对已存在的数据库做改变,

If you start your mysql container instance with a data directory that already contains a database (specifically, a mysql subdirectory), the $MYSQL_ROOT_PASSWORD variable should be omitted from the run command line; it will in any case be ignored, and the pre-existing database will not be changed in any way

## 在删除容器前在主节点新增一条数据验证是否会在重建后保留

[root@10-186-61-162 mysql]# mysql -h172.20.0.10 -uroot -P3306 -poracle

mysql> insert into zhenxing.t1 select null,'xingzhenyu';

mysql> select * from t1;

+----+------------+

| id | username |

+----+------------+

| 1 | yuzhenxing |

| 2 | zhenxingyu |

| 3 | xingzhenyu |

+----+------------+

3 rows in set (0.00 sec)

## 停止并删除容器

## 使用docker-compose stop && docker-compose rm不会删除创建的网络,如需要一并删除网络可使用docker-compose down

[root@10-186-61-162 mysql]# docker-compose stop && docker-compose rm

Stopping 172-20-0-11 ... done

Stopping 172-20-0-10 ... done

Going to remove 172-20-0-11, 172-20-0-10

Are you sure? [yN] y

Removing 172-20-0-11 ... done

Removing 172-20-0-10 ... done

## 重新构建容器

[root@10-186-61-162 mysql]# docker-compose up -d

Creating 172-20-0-11 ... done

Creating 172-20-0-10 ... done

## 登录主库查看数据

[root@10-186-61-162 mysql]# mysql -h172.20.0.10 -uroot -P3306 -poracle

mysql> show databases;

+--------------------+

| Database |

+--------------------+

| information_schema |

| mysql |

| performance_schema |

| sys |

| zhenxing |

+--------------------+

5 rows in set (0.00 sec)

mysql> show master status;

+------------------+----------+--------------+------------------+-------------------------------------------+

| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+------------------+-------------------------------------------+

| mysql-bin.000004 | 190 | | | 036a86a3-516e-11ea-9394-0242ac130003:1-10 |

+------------------+----------+--------------+------------------+-------------------------------------------+

1 row in set (0.00 sec)

## 验证主库数据仍保留完整

mysql> select * from zhenxing.t1;

+----+------------+

| id | username |

+----+------------+

| 1 | yuzhenxing |

| 2 | zhenxingyu |

| 3 | xingzhenyu |

+----+------------+

3 rows in set (0.01 sec)

## 登录slave查看与主库的同步

[root@10-186-61-162 mysql]# mysql -h172.20.0.11 -uroot -P3306 -poracle

mysql> show slave status\G

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 172.20.0.10

Master_User: repl

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000005

Read_Master_Log_Pos: 190

Relay_Log_File: mysql-relay.000007

Relay_Log_Pos: 395

Relay_Master_Log_File: mysql-bin.000005

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

Replicate_Do_DB:

Replicate_Ignore_DB:

Replicate_Do_Table:

Replicate_Ignore_Table:

Replicate_Wild_Do_Table:

Replicate_Wild_Ignore_Table:

Last_Errno: 0

Last_Error:

Skip_Counter: 0

Exec_Master_Log_Pos: 190

Relay_Log_Space: 1158

Until_Condition: None

Until_Log_File:

Until_Log_Pos: 0

Master_SSL_Allowed: No

Master_SSL_CA_File:

Master_SSL_CA_Path:

Master_SSL_Cert:

Master_SSL_Cipher:

Master_SSL_Key:

Seconds_Behind_Master: 0

Master_SSL_Verify_Server_Cert: No

Last_IO_Errno: 0

Last_IO_Error:

Last_SQL_Errno: 0

Last_SQL_Error:

Replicate_Ignore_Server_Ids:

Master_Server_Id: 1623306

Master_UUID: 72aa5e86-51ff-11ea-8a5a-0242ac14000a

Master_Info_File: mysql.slave_master_info

SQL_Delay: 0

SQL_Remaining_Delay: NULL

Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates

Master_Retry_Count: 86400

Master_Bind:

Last_IO_Error_Timestamp:

Last_SQL_Error_Timestamp:

Master_SSL_Crl:

Master_SSL_Crlpath:

Retrieved_Gtid_Set: 72aa5e86-51ff-11ea-8a5a-0242ac14000a:2-11

Executed_Gtid_Set: 72aa5e86-51ff-11ea-8a5a-0242ac14000a:1-11

Auto_Position: 1

Replicate_Rewrite_DB:

Channel_Name:

Master_TLS_Version:

1 row in set (0.00 sec)

## 数据同步正常

mysql> select * from zhenxing.t1;

+----+------------+

| id | username |

+----+------------+

| 1 | yuzhenxing |

| 2 | zhenxingyu |

| 3 | xingzhenyu |

+----+------------+

3 rows in set (0.00 sec)

## 也可使用dump方式导出导入到slave后再建立主从同步

docker exec -i master sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > all.sql

docker exec -i slave sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD"'

## 或将master的宿主机上的数据拷贝一份供从库使用

2.6 参考链接

 类似资料: