AMP AMP

How to run Multiple Slaves in a Single Machine using Docker Container on Ubuntu 22.04

To Run Multiple Slave In A Single Machine Using A Docker Container On Ubuntu 22.04

Introduction:

Docker is a software platform that allows you to build, test, and deploy applications quickly. MySQL is a relational database management system. Replication enables data from one MySQL database server (known as a source) to be copied to one or more MySQL database servers (known as replicas).

Procedure:

Step 1: Check the OS version by using the below command

root@linuxhelp:~# lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 22.04.3 LTS
Release:	22.04
Codename:	jammy

Step 2: Now check if the docker is installed or not by using the below command

root@linuxhelp:~# systemctl status docker
Unit docker.service could not be found.

Step 3: If the docker is already installed on your Ubuntu machine just skip the docker installation steps or follow from step 4.

Step – 4: Add Docker's official GPG key by using the below command

root@linuxhelp:~# apt install ca-certificates curl -y
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
ca-certificates is already the newest version (20230311ubuntu0.22.04.1).
ca-certificates set to manually installed.
The following packages were automatically installed and are no longer required:
  libflashrom1 libftdi1-2 libllvm13
Use 'apt autoremove' to remove them.
The following packages will be upgraded:
  curl libcurl4
Processing triggers for man-db (2.10.2-1) ...
Processing triggers for libc-bin (2.35-0ubuntu3.1) ...
root@linuxhelp:~# install -m 0755 -d /etc/apt/keyrings
root@linuxhelp:~# curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc

Step 5: Change the permission for the docker GPG key file by using the below command

root@linuxhelp:~# chmod a+r /etc/apt/keyrings/docker.asc

Step 6: Add the repository to Apt sources by using the below command

root@linuxhelp:~# echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Step 7: Now update the repo by using the below command
root@linuxhelp:~# apt-get update
Get:1 https://download.docker.com/linux/ubuntu jammy InRelease [48.8 kB]
Get:2 https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages [26.7 kB]                             
Hit:3 http://in.archive.ubuntu.com/ubuntu jammy InRelease                      
Hit:4 http://security.ubuntu.com/ubuntu jammy-security InRelease
Hit:5 http://in.archive.ubuntu.com/ubuntu jammy-updates InRelease
Hit:6 http://in.archive.ubuntu.com/ubuntu jammy-backports InRelease
Fetched 75.5 kB in 2s (41.8 kB/s)
Reading package lists... Done

Step 7: Then install docker and its dependencies by using the below command

root@linuxhelp:~# apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages were automatically installed and are no longer required:
  libflashrom1 libftdi1-2 libllvm13
Use 'apt autoremove' to remove them.
The following additional packages will be installed:
  docker-ce-rootless-extras git git-man liberror-perl libslirp0 pigz slirp4netns
Suggested packages:
  aufs-tools cgroupfs-mount | cgroup-lite git-daemon-run | git-daemon-sysvinit git-doc git-email git-gui gitk
  gitweb git-cvs git-mediawiki git-svn
The following NEW packages will be installed:
  containerd.io docker-buildx-plugin docker-ce docker-ce-cli docker-ce-rootless-extras docker-compose-plugin git
  git-man liberror-perl libslirp0 pigz slirp4netns
0 upgraded, 12 newly installed, 0 to remove and 240 not upgraded.
Need to get 122 MB of archives.
After this operation, 441 MB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 https://download.docker.com/linux/ubuntu jammy/stable amd64 containerd.io amd64 1.6.28-1 [29.6 MB]
Get:2 http://in.archive.ubuntu.com/ubuntu jammy/universe amd64 pigz amd64 2.6-1 [63.6 kB]   
Get:3 https://download.docker.com/linux/ubuntu jammy/stable amd64 docker-buildx-plugin amd64 0.12.1-1~ubuntu.22.04~jammy [28.2 MB]
Fetched 122 MB in 4s (31.6 MB/s)         
Selecting previously unselected package pigz.
(Reading database ... 202332 files and directories currently installed.)
Preparing to unpack .../00-pigz_2.6-1_amd64.deb ...
Unpacking pigz (2.6-1) ...
Selecting previously unselected package containerd.io.
Preparing to unpack .../01-containerd.io_1.6.28-1_amd64.deb ...
Unpacking containerd.io (1.6.28-1) ...
Selecting previously unselected package docker-buildx-plugin.
Preparing to unpack .../02-docker-buildx-plugin_0.12.1-1~ubuntu.22.04~jammy_amd64.deb ...
Unpacking docker-buildx-plugin (0.12.1-1~ubuntu.22.04~jammy) ...
Selecting previously unselected package docker-ce-cli.
Preparing to unpack .../03-docker-ce-cli_5%3a25.0.3-1~ubuntu.22.04~jammy_amd64.deb ...
Unpacking docker-ce-cli (5:25.0.3-1~ubuntu.22.04~jammy) ...
Processing triggers for man-db (2.10.2-1) ...
Processing triggers for libc-bin (2.35-0ubuntu3.1) ...

Step 8: After the installation completed, check the status of the docker by using the below command

root@linuxhelp:~# systemctl status docker
● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2024-02-24 16:15:12 IST; 33s ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 5082 (dockerd)
      Tasks: 10
     Memory: 30.2M
        CPU: 1.155s
     CGroup: /system.slice/docker.service
             └─5082 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Feb 24 16:15:10 linuxhelp systemd[1]: Starting Docker Application Container Engine...
Feb 24 16:15:11 linuxhelp dockerd[5082]: time="2024-02-24T16:15:11.083786856+05:30" level=info msg="Starting up"
Feb 24 16:15:11 linuxhelp dockerd[5082]: time="2024-02-24T16:15:11.086199193+05:30" level=info msg="detected 127.>
Feb 24 16:15:11 linuxhelp dockerd[5082]: time="2024-02-24T16:15:11.369340493+05:30" level=info msg="Loading conta>

Step 09: By using the below command you can a create a master server with the name mysql-master-42. Its default port 3306 is exposed as 10000 .

root@linuxhelp:~# docker run   --name mysql-master-42   --detach   --env SERVER_ID=42   --env MODE=master   --env MYSQL_ROOT_PASSWORD=Linux@123   --publish 10000:3306  quay.io/alexanderfefelov/mysql-replication
Unable to find image 'quay.io/alexanderfefelov/mysql-replication:latest' locally
latest: Pulling from alexanderfefelov/mysql-replication
69692152171a: Pull complete 
1651b0be3df3: Pull complete 
951da7386bc8: Pull complete 
0f86c95aa242: Pull complete 
37ba2d8bd4fe: Pull complete 
6d278bb05e94: Pull complete 
497efbd93a3e: Pull complete 
f7fddf10c2c2: Pull complete 
16415d159dfb: Pull complete 
0e530ffc6b73: Pull complete 
b0a4a1a77178: Pull complete 
cd90f92aa9ef: Pull complete 
70bbb7e1540a: Pull complete 
Digest: sha256:d1559e6d6e4ea602fe060ccbca7440adc068efa14874630ccb9071197dea3a7e
Status: Downloaded newer image for quay.io/alexanderfefelov/mysql-replication:latest
65e2e65f3e6807f94ab77dca84736b3c4b5060ff5990ebb4414805ec91564662

Step 10: After the container is created, it is linked to martin/wait group to allow communication with the slave servers by using the below command

root@linuxhelp:~# docker run --rm --link mysql-master-42:foobar martin/wait -p 3306 -t 300
Unable to find image 'martin/wait:latest' locally
latest: Pulling from martin/wait
ff3a5c916c92: Pull complete 
197262160aaa: Pull complete 
90b09db3ab0c: Pull complete 
Digest: sha256:183ea5fb43e7e71f3ecad53ad44aae63f0d8d016eaa7671300df76a2870e04c4
Status: Downloaded newer image for martin/wait:latest
Not checking 172.17.0.2:33060 because port is not included.
Waiting for 172.17.0.2:3306  .  up!
Everything is up

Step 11: By using the below command you can get the Master server IP Address by using the below command

root@linuxhelp:~# docker container inspect -f'{{.NetworkSettings.IPAddress}}'  mysql-master-42
172.17.0.2

Step 12: Create your first slave server with the name mysql-slave-24. Its default port 3306 is exposed as 10000. It is linked to martin/wait group as well by using the below command

root@linuxhelp:~# docker run    --name mysql-slave-24    --detach    --env SERVER_ID=24    --env MODE=slave    --env MASTER_HOST=172.17.0.2    --env MASTER_PORT=3306    --env MYSQL_ROOT_PASSWORD=Linux@123    --publish 12345:3306    quay.io/alexanderfefelov/mysql-replication  && docker run --rm --link mysql-slave-24:foobar martin/wait -p 3306 -t 300  && docker exec mysql-slave-24 cp /read-only.cnf /etc/mysql/conf.d/  && docker restart mysql-slave-24  && docker run --rm --link mysql-slave-24:foobar martin/wait -p 3306 -t 300
259e47d89ed2c89e19b37b6903c75eb0f64b6940e94399048f4decd3430ef910
Not checking 172.17.0.3:33060 because port is not included.
Waiting for 172.17.0.3:3306  .....................  up!
Everything is up
mysql-slave-24
Not checking 172.17.0.3:33060 because port is not included.
Waiting for 172.17.0.3:3306  ..  up!
Everything is up

Step 13: After the first slave server created, check the log and find the line connected to master by using the below command

root@linuxhelp:~# docker logs mysql-slave-24

Step 14: Then, open the container’s bash terminal by using the below command

root@linuxhelp:~# docker exec -it mysql-slave-24 /bin/bash

Step 15: Log in to MySQL by using the below command

root@259e47d89ed2:/# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 14
Server version: 8.0.25 MySQL Community Server - GPL

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

Step 16: After login to the MySQL check the slave status by using the below command

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.17.0.2
                  Master_User: replicator
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: log-bin.000003
          Read_Master_Log_Pos: 196
               Relay_Log_File: relay-bin.000008
                Relay_Log_Pos: 362
        Relay_Master_Log_File: log-bin.000003
             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: 196
              Relay_Log_Space: 605
              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: 42
                  Master_UUID: 2a3cb16d-d302-11ee-989e-0242ac110002
             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: 2a3cb16d-d302-11ee-989e-0242ac110002:1-7
            Executed_Gtid_Set: 2a3cb16d-d302-11ee-989e-0242ac110002:1-7,
fd79bd2b-d302-11ee-a2d6-0242ac110003:1-5
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set, 1 warning (0.00 sec)

ERROR: 
No query specified

Step 17: Now exit from MySQL and container’s bash terminal by using the below command

mysql> \q
Bye
root@259e47d89ed2:/# exit
exit

Step 18: Create your first slave server by copy the above codes for the First Slave. Replace the id 24 with 25. Replace the exposed port 12345 with 12346 by using the below command

root@linuxhelp:~# docker run    --name mysql-slave-25    --detach    --env SERVER_ID=25    --env MODE=slave    --env MASTER_HOST=172.17.0.2    --env MASTER_PORT=3306    --env MYSQL_ROOT_PASSWORD=Linux@123    --publish 12346:3306    quay.io/alexanderfefelov/mysql-replication  && docker run --rm --link mysql-slave-25:foobar martin/wait -p 3306 -t 300  && docker exec mysql-slave-25 cp /read-only.cnf /etc/mysql/conf.d/  && docker restart mysql-slave-25  && docker run --rm --link mysql-slave-25:foobar martin/wait -p 3306 -t 300
a055a33e37d83825913f884041ae3f41f4dfa2b68f24edaa4ec11bb9b503e30f
Not checking 172.17.0.4:33060 because port is not included.
Waiting for 172.17.0.4:3306  ......................  up!
Everything is up
mysql-slave-25
Not checking 172.17.0.4:33060 because port is not included.
Waiting for 172.17.0.4:3306  ..  up!
Everything is up

Step 19: After the first slave server created, check the log and find the line connected to master by using the below command

root@linuxhelp:~# docker logs mysql-slave-25

Step 20: Then, open the container’s bash terminal by using the below command

root@linuxhelp:~# docker exec -it mysql-slave-25 /bin/bash

Step 21: Log in to MySQL by using the below command

root@a055a33e37d8:/# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 8.0.25 MySQL Community Server - GPL

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

Step 22: After login to the MySQL check the slave status by using the below command

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.17.0.2
                  Master_User: replicator
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: log-bin.000003
          Read_Master_Log_Pos: 196
               Relay_Log_File: relay-bin.000008
                Relay_Log_Pos: 362
        Relay_Master_Log_File: log-bin.000003
             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: 196
              Relay_Log_Space: 605
              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: 42
                  Master_UUID: 2a3cb16d-d302-11ee-989e-0242ac110002
             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: 2a3cb16d-d302-11ee-989e-0242ac110002:1-7
            Executed_Gtid_Set: 2a3cb16d-d302-11ee-989e-0242ac110002:1-7,
95b6000c-d304-11ee-90ea-0242ac110004:1-5
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set, 1 warning (0.01 sec)

ERROR: 
No query specified

Step 23: Now exit from MySQL and container’s bash terminal by using the below command

mysql> \q
Bye
root@a055a33e37d8:/# exit
exit

Step 24: Then, open the Master container’s bash terminal and Login to the MySQL by using the below command

root@linuxhelp:~# docker exec -it mysql-master-42 /bin/bash
root@65e2e65f3e68:/# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 17
Server version: 8.0.25 MySQL Community Server - GPL

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

Step – 25 : List the databases by using the following commands.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.01 sec)

Step 26: Create a database in the master server and confirm the database is created by using the below command

mysql> create database test;
Query OK, 1 row affected (0.01 sec)
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.01 sec)

Step 27: Exit from MySQL and Master container bash terminal by using the below command

mysql> \q
Bye
root@65e2e65f3e68:/# exit
exit

Step 28: Open the First slave server container bash terminal and login to the MySQL by using the below command

root@linuxhelp:~# docker exec -it mysql-slave-24 /bin/bash;
root@259e47d89ed2:/# mysql -u root -p;
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 15
Server version: 8.0.25 MySQL Community Server - GPL

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

Step 29: Now list the databases and verify that the database created in the Master is replicated here or not by using the below command

;mysql> show databases;;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.01 sec)

Step 30: Exit from MySQL and First slave server bash terminal by using the below command

mysql> \q;
Bye
;root@259e47d89ed2:/# exit;
exit

Step 31: Open the Second Slave server bash terminal and login to the MySQL by using the below command

root@linuxhelp:~# docker exec -it mysql-slave-25 /bin/bash;
root@a055a33e37d8:/# mysql -u root -p;
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 8.0.25 MySQL Community Server - GPL

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

Step 32: Here also list the databases and verify that the database created in the Master is replicated here or not by using the below command

;mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.00 sec)

Conclusion:

We have reached the end of this article. In this guide, we have walked you through the steps required to run multiple Slave in Single Machine using Docker Container on Ubuntu 22.04. Your feedback is much welcome.

FAQ
Q
How to check the status of the slave server?
A
Use the below command on MySQL console to check the slave status
# show slave status\G;
Q
How do I tell a replica to use row-based replication?
A
Replicas automatically know which format to use.
Q
How to start and stop docker containers on Linux?
A
Use the below commands to start and stop the docker containers
#docker start
#docker stop
Q
How to install MySQL server on a Linux machine?
A
By using the following command you can install MySQL
#apt install mysql-server
Q
How to list all docker containers on Linux?
A
By using the following command you can list all the commands
#docker container list -a