Create Galera cluster

Containers

Create a network

docker network create --driver=bridge --subnet 172.16.0.0/16 galera-net

Create the volumes

for n in 1 2 3; do docker volume create galera-node$n-data; done

# output
galera-node1-data
galera-node2-data
galera-node3-data

Configuration

Create the config directories

mkdir -p ~/containers/galera_cluster/galera-node{1,2,3}-conf

Initial config for the galera-node1 cluster initialization

cat <<EOF > galera-node1-conf/60-galera.cnf
[galera]

wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_name="galera_cluster"
wsrep_cluster_address="gcomm://"
wsrep_sst_method=rsync
wsrep_node_name="galera-node1"
binlog_format=row
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
EOF

galera-node2 & galera-node3 config

galera-node2

cat <<EOF > galera-node2-conf/60-galera.cnf
[galera]

wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_name="galera_cluster"
wsrep_cluster_address="gcomm://172.16.0.101,172.16.0.102,172.16.0.103"
wsrep_sst_method=rsync
wsrep_node_name="galera-node2"
binlog_format=row
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
EOF

galera-node3

cat <<EOF > galera-node3-conf/60-galera.cnf
[galera]

wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_name="galera_cluster"
wsrep_cluster_address="gcomm://172.16.0.101,172.16.0.102,172.16.0.103"
wsrep_sst_method=rsync
wsrep_node_name="galera-node3"
binlog_format=row
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
EOF

Start the first node that will initialize the cluster

docker run -it -d --net galera-net --name galera-node1 -h galera-node1 --ip 172.16.0.101 \
-e MYSQL_ROOT_PASSWORD=rootpass -e GALERA_NEW_CLUSTER=1 -v galera-node1-data:/var/lib/mysql \
-v ~/containers/databases/galera_cluster/galera-node1-conf/60-galera.cnf:/etc/mysql/mariadb.conf.d/60-galera.cnf:Z \
docker.io/library/mariadb:11.4
docker exec -it galera-node1 mariadb -h 172.16.0.101 -uroot -prootpass -e "SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';"
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| wsrep_cluster_size | 1     |
+--------------------+-------+

stop and delete the intialized cluster node aka galera-node1

docker stop galera-node1 
docker rm galera-node1

Reconfigure galera-node1

[galera]

wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_name="galera_cluster"
# wsrep_cluster_address="gcomm://" # <= comment this line out
wsrep_cluster_address="gcomm://172.16.0.101,172.16.0.102,172.16.0.103" # <= add all the galera node ip addresses
wsrep_sst_method=rsync
wsrep_node_name="galera-node1"
binlog_format=row
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2

Start galera-node1, galera-node2 & galera-node3

Start the containers

galera-node1

docker run -it -d --net galera-net --name galera-node1 -h galera-node1 --ip 172.16.0.101 \
-e MYSQL_ROOT_PASSWORD=rootpass -e GALERA_NEW_CLUSTER=1 -v galera-node1-data:/var/lib/mysql \
-v ~/containers/databases/galera_cluster/galera-node1-conf/60-galera.cnf:/etc/mysql/mariadb.conf.d/60-galera.cnf:Z \
docker.io/library/mariadb:11.4

galera-node2

docker run -it -d --net galera-net --name galera-node2 -h galera-node2 --ip 172.16.0.102 \
-e MYSQL_ROOT_PASSWORD=rootpass -v galera-node2-data:/var/lib/mysql \
-v ~/containers/databases/galera_cluster/galera-node2-conf/60-galera.cnf:/etc/mysql/mariadb.conf.d/60-galera.cnf:Z \
docker.io/library/mariadb:11.4

galera-node3

docker run -it -d --net galera-net --name galera-node3 -h galera-node3 --ip 172.16.0.103 \
-e MYSQL_ROOT_PASSWORD=rootpass -v galera-node3-data:/var/lib/mysql \
-v ~/containers/databases/galera_cluster/galera-node3-conf/60-galera.cnf:/etc/mysql/mariadb.conf.d/60-galera.cnf:Z \
docker.io/library/mariadb:11.4

Check status of the cluster

  • https://galeracluster.com/documentation/html_docs_20241007-1720-master/training/tutorials/galera-monitoring.html
docker exec -it galera_node1 mariadb -h 172.16.0.101 -uroot -prootpass -e "SHOW GLOBAL STATUS LIKE 'wsrep_%';"
docker exec -it galera_node1 mariadb -h 172.16.0.101 -uroot -prootpass -e "SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';"

Use a personal python script

This has a lot of the important cluster information builtin already.

docker pull registry.gitlab.com/myteam/galera_status:latest
docker run -it --rm registry.gitlab.com/andrewmercer/galera_status:latest python galera_status.py -c all
docker run -it --rm registry.gitlab.com/andrewmercer/galera_status:latest python galera_status.py --check [ option ]

Troubleshooting

WSREP: It may not be safe to bootstrap the cluster from this node.

WSREP: It may not be safe to bootstrap the cluster from this node. It was not the last one to leave the cluster and may not contain all the updates. To force cluster bootstrap with this node, edit the grastate.dat file manually and set safe_to_bootstrap to 1
docker inspect galera-node1 | grep Mounts -A 5
sudo vi /var/lib/docker/volumes/galera-node1-data/_data/grastate.dat

Next time you stop the containers, make sure the node that initialized the cluster is the last to leave.

todo

Find out which node is the node that needs to bootstrap the cluster (it’s not always the one used initially to bootstrap the cluster).

Cleanup

for container in galera-node1 galera-node2 galera-node3; do docker stop $container && docker rm $container; done
docker network rm galera-net
for volume in galera-node1-data galera-node2-data galera-node3-data; do docker volume rm $volume; done