Create Galera cluster

Containers

Create a network

docker network create --driver=bridge --subnet 172.16.0.0/16 galera_net

Create the volumes

docker volume create galera-node1-data
docker volume create galera-node2-data
docker volume create galera-node3-data

configuration

Create the config directories

mkdir galera-node{1,2,3}

Initial config for the galera-node1 cluster initialization

cat <<EOF > galera-node1/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/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-node2/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 ./galera-node1-conf/60-galera.cnf:/etc/mysql/mariadb.conf.d/60-galera.cnf mariadb:10.11

stop and delete the intialized cluster node aka galera-node1

Note: because data is kept in a volume and persisted, deleting a container and starting it again with a different config works because the cluster has already been created.

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://172.16.0.101,172.16.0.102,172.16.0.103"
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 ./galera-node1-conf/60-galera.cnf:/etc/mysql/mariadb.conf.d/60-galera.cnf mariadb:10.11 --wsrep-new-cluster; 
# 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 ./galera-node2-conf/60-galera.cnf:/etc/mysql/mariadb.conf.d/60-galera.cnf mariadb:10.11; \
# 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 ./galera-node3-conf/60-galera.cnf:/etc/mysql/mariadb.conf.d/60-galera.cnf mariadb:10.11

Check status of the cluster

  • https://galeracluster.com/documentation/html_docs_20241007-1720-master/training/tutorials/galera-monitoring.html
mysql -h 172.16.0.101 -uroot -p -e "SHOW GLOBAL STATUS LIKE 'wsrep_%';"
mysql -h 172.16.0.101 -uroot -p -e "SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';"

Use a personal python script

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

podman pull registry.gitlab.com/myteam/galera_status:latest
podman run -it --rm galera_status -c # by default checks all
podman run -it --rm galera_status python galera_status.py --check [ option ] # or select an 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
```