运维有话说 | Mysql容器化主主从架构搭建
1 前言
1.1 介绍
MySQL可以适用于容器吗?在这一篇里,简单地为大家介绍一下MySQL在容器上的使用并且实现主主从的架构实施。
容器是软件的标准单元,它将代码及其所有依赖项打包,以便应用程序在不同的计算环境之间快速可靠地运行。Docker容器映像是一个轻量级的、独立的、可执行的软件包,它包括运行应用程序所需的一切:代码、运行时、系统工具、系统库和设置。Docker是实现容器技术的一个开源项目,它将程序以及程序所有的依赖都打包到Docker容器里面。
使用Docker时,需要用到Docker镜像。镜像可以从正式的镜像库下载,也可以人工制作和更新。本次Mysql镜像从https://hub.docker.com/下载,也可以从https://container-registry.oracle.com下载企业版和社区版本两个版本。
1.2 环境
系统 |
版本 |
IP |
CentOS Linux |
7.7.1908 |
192.168.100.75 |
Docker |
19.03.12 |
|
Mysql |
5.7.31 |
2 实施过程
2.1 docker环境
2.1.1 Docker服务安装
yum install -y docker-ce
2.1.2 下载Mysql镜像
docker pull mysql:5.7.31
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
v1.1.2 eb4bb8b766f5 2 weeks ago 340MB
v1.1.1 f9c14ba8b254 2 weeks ago 328MB
centos latest 0d120b6ccaa8 2 weeks ago 215MB
nginx latest 08393e824c32 3 weeks ago 132MB
mysql 5.7.31 718a6da099d8 3 weeks ago 448MB
2.1.3 修改镜像
修改dockerfile中的配置,包括镜像的时区和默认系统字符集
cd /root/dockert/dockerfile
vi Dockerfile
FROM mysql:5.7.31
MAINTAINER Liu
RUN echo "alias ls='ls --color=auto'" >> /root/.bashrc \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
ENV LANG=C.UTF-8
编译镜像
docker build -t mysqlt:5.7.31 .
查看到新的创建镜像
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysqlt 5.7.31 7a2a0aadd202 25 seconds ago 448MB
v1.1.2 eb4bb8b766f5 2 weeks ago 340MB
v1.1.1 f9c14ba8b254 2 weeks ago 328MB
centos latest 0d120b6ccaa8 2 weeks ago 215MB
nginx latest 08393e824c32 3 weeks ago 132MB
mysql 5.7.31 718a6da099d8 3 weeks ago 448MB
2.2 启动Mysql
MySQL容器化其实也需要映射端口,数据持久化,加载配置文件等操作。本地启动三个mysql实例容器,容器端口3306分别映射到宿主机的33061、33062、33063端口。
2.2.1 创建目录
Data目录存放各mysql实例的数据文件,etc存放mysql的配置启动文件。
mkdir -p /data/5.7.31/33061/data
mkdir -p /data/5.7.31/33061/etc
mkdir -p /data/5.7.31/33062/data
mkdir -p /data/5.7.31/33062/etc
mkdir -p /data/5.7.31/33063/data
mkdir -p /data/5.7.31/33063/etc
2.2.2 添加配置文件
因需配置主主从复制架构在master1和master2上打开bin-log和log_slave_updates参数。
cd /data/5.7.31/33061/etc
vim my.cnf
[mysqld]
# basic settings #
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
server_id = 561101
user = mysql
port = 3306
log_error = /var/lib/mysql/error.log
sql_mode = "STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER"
autocommit = 1
character_set_server=utf8
transaction_isolation = READ-COMMITTED
explicit_defaults_for_timestamp = 1
max_allowed_packet = 16777216
event_scheduler = 1
log_timestamps = system
lower_case_table_names=1
# connection #
interactive_timeout = 1800
wait_timeout = 1800
lock_wait_timeout = 1800
skip_name_resolve = 1
max_connections = 512
max_connect_errors = 100000
# table cache performance settings #
table_open_cache = 4096
table_definition_cache = 4096
table_open_cache_instances = 16
# session memory settings #
read_buffer_size = 16M
read_rnd_buffer_size = 32M
sort_buffer_size = 32M
tmp_table_size = 64M
join_buffer_size = 128M
thread_cache_size = 64
# log settings #
slow_query_log = 1
slow_query_log_file = /var/lib/mysql/slow.log
log_queries_not_using_indexes = 1
log_slow_admin_statements = 1
log_slow_slave_statements = 1
log_throttle_queries_not_using_indexes = 10
expire_logs_days = 7
long_query_time = 2
min_examined_row_limit = 100
binlog-rows-query-log-events = 1
log-bin-trust-function-creators = 1
max_binlog_size = 512M
# InnoDB settings #
innodb_page_size = 16384
innodb_data_file_path = ibdata1:256M:autoextend
innodb_buffer_pool_size = 512M
innodb_buffer_pool_instances = 16
innodb_buffer_pool_load_at_startup = 1
innodb_buffer_pool_dump_at_shutdown = 1
innodb_lru_scan_depth = 4096
innodb_lock_wait_timeout = 50
innodb_io_capacity = 10000
innodb_io_capacity_max = 20000
innodb_flush_method = O_DIRECT
innodb_file_format = Barracuda
innodb_file_format_max = Barracuda
innodb_undo_logs = 128
innodb_undo_tablespaces = 3
innodb_flush_neighbors = 0
innodb_log_buffer_size = 16777216
innodb_log_file_size = 131072000
innodb_log_files_in_group = 3
innodb_purge_threads = 4
innodb_large_prefix = 1
innodb_thread_concurrency = 64
innodb_print_all_deadlocks = 1
innodb_strict_mode = 1
innodb_sort_buffer_size = 67108864
innodb_write_io_threads = 16
innodb_read_io_threads = 16
innodb_file_per_table = 1
innodb_stats_persistent_sample_pages = 64
innodb_autoinc_lock_mode = 2
innodb_online_alter_log_max_size = 1G
innodb_open_files = 4096
innodb_flush_log_at_trx_commit = 1
# replication settings #
#slave_parallel_workers = 4
#slave_parallel_type = 'LOGICAL_CLOCK'
#master_info_repository = table
#relay_log_info_repository = table
sync_binlog = 1
gtid_mode = on
enforce_gtid_consistency = 1
log_slave_updates = 1
log_bin = /var/lib/mysql/mysql-bin
log_bin_index = /var/lib/mysql/binlog.index
binlog_format = row
binlog_row_image = minimal
binlog_rows_query_log_events = 1
2.2.3 运行Mysql实例
Mysql容器端口3306映射主机33061,
/var/lib/mysql绑定本地/data/5.7.31/33061/data,
/etc/mysql绑定本地/data/5.7.31/33061/etc,
mysql实例root密码指定123456
$ docker run -itd -p 33061:3306 --name mysqlmaster1 --hostname=master1 -v /data/5.7.31/33061/etc:/etc/mysql -v /data/5.7.31/33061/data:/var/lib/mysql --privileged=true -e MYSQL_ROOT_PASSWORD=123456 mysqlt:5.7.31
df94f5a97a57084ec1cdaab49e64f1e4bb4c44f0e8e01de5a736977abdb316c4
# 解释下各个参数的含义
-d: 后台运行容器,并返回容器ID
-i: 以交互模式运行容器,通常与 -t 同时使用
-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用
-p: 指定端口映射,格式为:主机(宿主)端口:容器端口
--name="mysql57": 为容器指定一个名称
--hostname=mysql57: 指定容器的hostname
-v: 绑定一个卷
--privileged=true: 以特权方式启动容器
查看容器运行情况
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
df94f5a97a57 mysqlt:5.7.31 "docker-entrypoint.s?? 5 seconds ago Up 2 seconds 33060/tcp, 0.0.0.0:33061->3306/tcp mysqlmaster1
启动过程中可查看日志
docker logs df94f5a97a57084ec1cdaab49e64f1e4bb4c44f0e8e01de5a736977abdb316c4
查看mysql日志
tail -100f error.log
删除容器
docker rm df94f5a97a57
相同方法启动另两条mysql实例
docker run -itd -p 33062:3306 --name mysqlmaster2 --hostname=master2 -v /data/5.7.31/33062/etc:/etc/mysql -v /data/5.7.31/33062/data:/var/lib/mysql --privileged=true -e MYSQL_ROOT_PASSWORD=123456 mysqlt:5.7.31
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b16630629a70 mysqlt:5.7.31 "docker-entrypoint.s?? 8 seconds ago Up 5 seconds 33060/tcp, 0.0.0.0:33063->3306/tcp mysqlslave1
3020b33142a8 mysqlt:5.7.31 "docker-entrypoint.s?? 30 seconds ago Up 28 seconds 33060/tcp, 0.0.0.0:33062->3306/tcp mysqlmaster2
b179db93d92f mysqlt:5.7.31 "docker-entrypoint.s?? 4 minutes ago Up 4 minutes 33060/tcp, 0.0.0.0:33061->3306/tcp mysqlmaster1
补充:# 更改mysql实例配置只需要修改宿主机 /data/5.7.31/33061/etc/my.cnf 文件,然后重启容器即可
docker restart mysqlmaster1
2.3 建立主主从关系
2.3.1 创建测试数据
在主库master1上创建测试数据
登录数据库两种方式
1)本地登录数据库
mysql -uroot -p -P33061 -h192.168.100.75
2)进去容器里后登录数据库
docker exec -it mysqlmaster1 /bin/bash
或
docker exec -it [CONTAINER ID] /bin/bash
进入容器后,登录数据库进行操作
root@master1:/
mysql> create database test1;
mysql> use test1;
mysql> create table tbl_test (
id bigint(20) NOT NULL AUTO_INCREMENT,
name varchar(20) NOT NULL,
PRIMARY KEY (id),
KEY idx_name (name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
mysql> insert into tbl_test(name) values('aaa');
mysql> insert into tbl_test(name) values('bbb');
mysql> insert into tbl_test(name) values('ccc');
mysql> select * from tbl_test;
+----+------+
| id | name |
+----+------+
| 1 | aaa |
| 2 | bbb |
| 3 | ccc |
+----+------+
3 rows in set (0.00 sec)
2.3.2 配置同步
1)在master1上创建同步账号
'rep'@'%' identified by 'rep'; grant replication slave on *.* to
flush privileges;
2)将master1上的数据同步至 master2和slave1上
#导出
docker exec mysqlmaster1 sh -c 'exec mysqldump --all-databases --set-gtid-purged=off--master-data=2 --flush-logs -uroot -p"$MYSQL_ROOT_PASSWORD" ' > /tmp/all-databases.sql
#导入
docker exec -i mysqlmaster2 sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD"' < /tmp/all-databases.sql
docker exec -i mysqlslave1 sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD"' < /tmp/all-databases.sql
3)确认三个容器内部网络IP
'{{.NetworkSettings.IPAddress}}' mysqlmaster1 docker inspect --format=
172.17.0.2
'{{.NetworkSettings.IPAddress}}' mysqlmaster2 docker inspect --format=
172.17.0.3
'{{.NetworkSettings.IPAddress}}' mysqlslave1; docker inspect --format=
172.17.0.4
4)确认日志位置,进行同步
查询主库master1的日志位置
mysql> Show master status ;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000007 | 194 | | |
+------------------+----------+--------------+------------------+
在master2和slave1上执行
CHANGE MASTER TO
MASTER_HOST='172.17.0.2',
MASTER_PORT=3306,
MASTER_USER='rep',
MASTER_PASSWORD='rep',
MASTER_LOG_FILE='mysql-bin.000007',
MASTER_LOG_POS=194;
Start slave ;
show slave status\G;
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
这两个状态为Yes,证明主从关系创建成功。
5)现在是mster2和slave1分别同步与master1同步,本次需要设置为双主一从模式,现配置master1与master2进行同步。
Master2Mysql实例中操作
mysql> set sql_log_bin=off; ---关闭binlog写入
mysql> grant replication slave on *.* to 'rep2'@'%' identified by 'rep2';
mysql> show master status;
mysql> set sql_log_bin=on;
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000005 | 234 | | |
+------------------+----------+--------------+------------------+
mater1Mysql实例中操作
mysql> show slave status;
mysql> set sql_log_bin=off;
mysql> stop slave;
mysql> CHANGE MASTER TO
MASTER_HOST='172.17.0.3',
MASTER_PORT=3306,
MASTER_USER='rep2',
MASTER_PASSWORD='rep2',
MASTER_LOG_FILE='mysql-bin.000005',
MASTER_LOG_POS=234;
mysql> Start slave;
mysql> set sql_log_bin=on;
2.4 数据验证
通过主机ip和映射端口访问数据库
master1--
$ mysql -uroot -p123456 -h192.168.100.75 -P33061
mysql> insert into test1.tbl_test(name) values('ddd');
mysql> insert into test1.tbl_test(name) values('eee');
master2--
$ mysql -uroot -p123456 -h192.168.100.75 -P33062
mysql> insert into test1.tbl_test(name) values('fff');
mysql> insert into test1.tbl_test(name) values('ggg');
slave1--
$ mysql -uroot -p123456 -h192.168.100.75 -P33063
mysql> select * from test1.tbl_test;
+----+------+
| id | name |
+----+------+
| 1 | aaa |
| 2 | bbb |
| 3 | ccc |
| 4 | ddd |
| 5 | eee |
| 6 | fff |
| 7 | ggg |
+----+------+
7 rows in set (0.00 sec)
编辑:路程