Docker containers with MySQL master-slave replication

Posted on Fri 22 April 2016 by Pavlo Khmel

This post shows process of moving MediaWiki to multiple docker containers setup with MySQL master-slave replication.
I'll skip MediaWiki setup. Focus on docker and MySQL replication.

docker

Servers:
- Old MediaWiki server. Create dump of current wiki database.
- docker1 (master physical server)
- docker2 (slave physical server)

Containers:
- dbmaster (docker container for MySQL master)
- dbslave (docker container for MySQL slave)
- webmaster (docker container for main HTTPD + PHP + MediaWiki)
- webslave (docker container for backup HTTPD + PHP + MediaWiki)

1. On both physical servers docker1 and docker2:

Installed CentOS 7.2

Add docker repository:

tee /etc/yum.repos.d/docker.repo <<-'EOF'
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF

Install, enable, and start docker:

yum -y install docker-engine
systemctl enable docker
systemctl start docker

Download docker images:

docker pull mysql
docker pull php:5.6-apache

2. Configure docker1

Add IP addresses. They will be used by containers:

ip addr add 10.0.1.101/24 dev eth0
ip addr add 10.0.1.201/24 dev eth0

Create dbmaster container:

docker run --name dbmaster -e MYSQL_ROOT_PASSWORD=DBpassword -p 10.0.1.101:3306:3306 -d mysql

Dump and upload MediaWiki database from old MediaWiki database server:

mysqldump --database wiki > wiki_dump.db
mysql -h 10.0.1.101 -u root -p < wiki_dump.db

Connect container and modify MySQL configuration for replication:

docker exec -it dbmaster bash
echo 'server-id=1' >> /etc/mysql/my.cnf
echo 'binlog_do_db=wiki' >> /etc/mysql/my.cnf
echo 'log-bin=mysql-bin' >> /etc/mysql/my.cnf
exit
docker restart dbmaster

Create webmaster container and setup additional packages for MediaWiki:

docker run --name webmaster -v /root/html:/var/www/html -p 10.0.1.201:80:80 -d php:5.6-apache
docker exec -it webmaster bash
apt-get update
apt-get install libapache2-mod-php5 php5 php5-common php5-cli php5-mysql php5-mcrypt php5-curl php5-gd php5-curl php5-intl php-pear
exit
docker restart webmaster

3. Configure docker2

Add IP addresses. They will be used by containers:

ip addr add 10.0.1.102/24 dev eth0
ip addr add 10.0.1.202/24 dev eth0

Create dbslave container:

docker run --name dbslave -e MYSQL_ROOT_PASSWORD=DBpassword -p 10.0.1.102:3306:3306 -d mysql

Connect container and modify MySQL configuration for replication:

docker exec -it dbslave bash
echo 'server-id=2' >> /etc/mysql/my.cnf
echo 'binlog_do_db=wiki' >> /etc/mysql/my.cnf
echo 'read_only=on' >> /etc/mysql/my.cnf
exit
docker restart dbslave

4. Replication

Create user for replication on dbmaster and lock table for mysqldump:

docker exec -it dbslave bash
mysql -h 10.0.1.101 -u root -p
    CREATE USER 'repl'@'%' IDENTIFIED BY 'slavepass';
    GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
    FLUSH TABLES WITH READ LOCK;
    SHOW MASTER STATUS;
    # I got file: mysql-bin.000001
    # I got position: 10229
    exit

Connect dbslave, dump database from dbmaster,

docker exec -it dbslave bash
mysqldump -h 10.0.1.101 -u root -p wiki > wiki_dump.db

Create database, import dump, configure slave for replication:

mysql -u root -p
    CREATE DATABASE wiki;
    exit
mysql -u root -p wiki < wiki_dump.db
mysql -u root -p
    CHANGE MASTER TO MASTER_HOST='10.0.1.101',MASTER_USER='repl', MASTER_PASSWORD='slavepass', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=10229;
    exit

Unlock tables on dbmaster:

mysql -h 10.0.1.101 -u root -p
    UNLOCK TABLES;
    exit

Start replication on dbslave:

mysql -u root -p
    START SLAVE;
    SHOW SLAVE STATUS\G
    exit
exit

Create webslave container and setup additional packages for MediaWiki:

docker run --name webslave -v /root/html:/var/www/html -p 10.0.1.202:80:80 -d php:5.6-apache
docker exec -it webslave bash
apt-get update
apt-get install libapache2-mod-php5 php5 php5-common php5-cli php5-mysql php5-mcrypt php5-curl php5-gd php5-curl php5-intl php-pear
exit
docker restart webslave

5. How to start after docker1 and docker2 reboot:

On docker1:

ip addr add 10.0.1.101/24 dev enp0s3
ip addr add 10.0.1.201/24 dev enp0s3
docker start dbmaster
docker start webmaster
docker ps -a

On docker2:

ip addr add 10.0.1.102/24 dev enp0s3
ip addr add 10.0.1.202/24 dev enp0s3
docker start dbslave
docker start webslave
docker ps -a