使用Docker-compose部署MySQL測試環境

1.題目部分

  • 參考文檔: https://hub.docker.com/_/mysql
  • 使用docker-compose, 建立兩個MySQL容器, 知足以下條件:
    • 使用自定義的my.cnf
    • 造成主從複製關係
    • 容器銷燬後, 主實例的數據仍保留, 從實例的數據清零銷燬
    • 重建兩個容器, 主實例沿用以前的數據, 從實例重建數據, 並創建複製

2.解答部分

2.1 docker安裝

docker-compose依賴docker環境,須要先安裝好docker,本實驗環境爲在CentOS7虛擬機中安裝docker,參考連接:https://docs.docker.com/install/linux/docker-ce/centos/mysql

## 卸載舊版本的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工具來統一啓停維護。安裝參考連接:linux

## 直接使用官方連接提供的下載命令下載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配置文件git

## 建立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與從庫不同之外,其餘參數均一致github

[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

  1. 採用MySQL5.7.29版本數據庫
  2. 主從配置文件均採用自定義的配置文件
  3. 主庫的數據目錄採用宿主機上建立的data目錄
  4. 將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-composesql

## 使用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"' <all.sql
 
## 或將master的宿主機上的數據拷貝一份供從庫使用

2.6 參考連接

相關文章
相關標籤/搜索