Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ansible/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
ansible==12.0.0
ansible-lint==25.9.1
pip==25.2
pip==25.3
41 changes: 13 additions & 28 deletions images/mariadb-galera/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
FROM python:3.8.10-slim-buster
MAINTAINER Rich Braun "docker@instantlinux.net"
FROM mariadb:12.0.2
ARG BUILD_DATE
ARG VCS_REF
LABEL org.label-schema.build-date=$BUILD_DATE \
LABEL org.opencontainers.image.authors="Rich Braun docker@instantlinux.net" \
org.label-schema.build-date=$BUILD_DATE \
org.label-schema.license=GPL-2.0 \
org.label-schema.name=mariadb-galera \
org.label-schema.vcs-ref=$VCS_REF \
Expand All @@ -12,41 +12,26 @@ ENV DEBIAN_FRONTEND=noninteractive \
CLUSTER_NAME=cluster01 \
CLUSTER_SIZE=3 \
DISCOVERY_SERVICE=etcd:2379 \
ROOT_PASSWORD_SECRET=mysql-root-password \
ROOT_SECNAME=mysql-root-password \
TTL=10 \
TZ=UTC \
SST_AUTH_SECRET=sst-auth-password

ARG MARIADB_MAJOR=10.4
ARG MARIADB_VERSION=10.4.20
ARG APT_KEY=F1656F24C74CD1D8
ARG DEB_REL=buster
TZ=UTC
ARG UID=212
ARG GID=212

COPY requirements/ /root/

RUN apt-get -yq update && apt-get install -yq gnupg && \
apt-key adv --recv-keys --keyserver keyserver.ubuntu.com $APT_KEY && \
echo "deb [arch=amd64] \
http://nyc2.mirrors.digitalocean.com/mariadb/repo/$MARIADB_MAJOR/debian $DEB_REL main" \
> /etc/apt/sources.list.d/mariadb.list && \
groupadd -g $GID mysql && \
useradd -u $UID -g $GID -s /bin/false -c "MariaDB" -d /none mysql && \
apt-get -yq update && apt-get -yq install --no-install-recommends \
curl iputils-ping jq mariadb-server=1:$MARIADB_VERSION+maria~$DEB_REL \
mariadb-backup=1:$MARIADB_MAJOR_$MARIADB_VERSION+maria~$DEB_REL \
mariadb-client=1:$MARIADB_MAJOR_$MARIADB_VERSION+maria~$DEB_REL \
net-tools netcat procps && \
apt-get clean && rm -fr /var/log/* /var/lib/mysql/* && \
rm -fr /root/.cache /usr/share/zoneinfo/leap-seconds.list
RUN pip install -r /root/common.txt && \
RUN groupmod -g $GID mysql && \
usermod -u $UID -s /bin/false -c "MariaDB" -d /none mysql && \
apt -yq update && apt -yq install --no-install-recommends \
curl iputils-ping jq net-tools netcat-openbsd procps \
python3 python3-pip python3-etcd3 && \
apt-get clean && rm -fr /var/log/* /var/lib/mysql/* \
/var/lib/apt/lists /var/cache/debconf/*old /root/.cache
RUN pip install -r /root/common.txt --break-system-packages && \
echo "dash dash/sh boolean false" | debconf-set-selections && \
dpkg-reconfigure dash || true

EXPOSE 3306 4444 4567/udp 4567 4568
VOLUME /var/lib/mysql

HEALTHCHECK --interval=10s --timeout=3s --retries=30 \
CMD /bin/sh /usr/local/bin/healthcheck.sh || exit 1

Expand Down
31 changes: 17 additions & 14 deletions images/mariadb-galera/Dockerfile.alpine
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
FROM python:3.7.0-alpine3.8
MAINTAINER Rich Braun "docker@instantlinux.net"
# Experimental - this "almost" works but SST transfers fail, apparently
# due to issues with the mariadb-backup script distributed with alpine;
# abandoned this in favor of the image distributed by MariaDB maintainers

FROM python:3.14.0-alpine3.22
ARG BUILD_DATE
ARG VCS_REF
LABEL org.label-schema.build-date=$BUILD_DATE \
LABEL org.opencontainers.image.authors="Rich Braun docker@instantlinux.net" \
org.label-schema.build-date=$BUILD_DATE \
org.label-schema.license=GPL-2.0 \
org.label-schema.name=mariadb-galera \
org.label-schema.vcs-ref=$VCS_REF \
Expand All @@ -11,27 +15,25 @@ LABEL org.label-schema.build-date=$BUILD_DATE \
ENV CLUSTER_NAME=cluster01 \
CLUSTER_SIZE=3 \
DISCOVERY_SERVICE=etcd:2379 \
ROOT_PASSWORD_SECRET=mysql-root-password \
PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python \
ROOT_SECNAME=mysql-root-password \
TTL=10 \
TZ=UTC \
SST_PASSWORD= \
SST_SECRET=sst-auth-password
SST_SECNAME=sst-auth-password

ARG MARIADB_MAJOR=10.3
ARG MARIADB_VERSION=10.3.9-r2
ARG MARIADB_MAJOR=11.4
ARG MARIADB_VERSION=11.4.8-r0
ARG UID=212
ARG GID=212

COPY requirements/ /root/

RUN echo '@edge http://dl-cdn.alpinelinux.org/alpine/edge/main' \
>>/etc/apk/repositories && \
addgroup -g $GID mysql && \
RUN addgroup -g $GID mysql && \
adduser -u $UID -G mysql -s /bin/false -g "MariaDB" -h /none -D mysql && \
apk add --update --no-cache \
curl jq mariadb@edge=$MARIADB_VERSION \
mariadb-backup@edge=$MARIADB_VERSION \
mariadb-client@edge=$MARIADB_VERSION net-tools socat && \
bash curl galera jq mariadb=$MARIADB_VERSION \
mariadb-backup=$MARIADB_VERSION \
mariadb-client=$MARIADB_VERSION net-tools pv socat && \
pip install -r /root/common.txt && \
ln -s /usr/bin/mysqld /usr/sbin && \
rm -fr /var/log/* /var/lib/mysql/*
Expand All @@ -44,6 +46,7 @@ HEALTHCHECK --interval=10s --timeout=3s --retries=30 \

COPY wsrep.cnf my.cnf /etc/
COPY src/entrypoint.py src/healthcheck.sh /usr/local/bin/
COPY wsrep_sst_mariabackup /usr/bin/
ENTRYPOINT ["/usr/local/bin/entrypoint.py"]

# TODO: fix healthcheck.sh to handle long-duration bootstrap
2 changes: 1 addition & 1 deletion images/mariadb-galera/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ test_requirements: python_env

$(VDIR)/bin/python:
@echo "Creating virtual environment"
virtualenv --system-site-packages $(VDIR)
python3 -m venv --system-site-packages $(VDIR)

pytest: test_requirements
@echo "Running pytest unit tests"
Expand Down
24 changes: 18 additions & 6 deletions images/mariadb-galera/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
## mariadb-galera
[![](https://img.shields.io/docker/v/instantlinux/mariadb-galera?sort=date)](https://hub.docker.com/r/instantlinux/mariadb-galera/tags "Version badge") [![](https://img.shields.io/docker/image-size/instantlinux/mariadb-galera?sort=date)](https://github.com/instantlinux/docker-tools/tree/main/images/mariadb-galera "Image badge") [![](https://img.shields.io/badge/dockerfile-latest-blue)](https://gitlab.com/instantlinux/docker-tools/-/blob/main/images/mariadb-galera/Dockerfile "dockerfile")

MariaDB 10.4 with automatic cluster generation under kubernetes / swarm using named volumes for data persistence. This has robust bootstrap logic based on MariaDB / Galera documentation for automated cluster create / join operations.
MariaDB 12.x with automatic cluster generation under kubernetes / swarm using named volumes for data persistence. This has robust bootstrap logic based on MariaDB / Galera documentation for automated cluster create / join operations. Requires an etcd instance for sharing instance-health data across the cluster.

### Usage - kubernetes

Define the following dependencies before launching the cluster: passwords for root and SST, network load balancer, and a dedicated etcd key-value store. Here's how:
Define the following dependencies before launching the cluster: password for root, network load balancer, and a dedicated etcd key-value store. Here's how:

Create a random root password:
```
Expand All @@ -25,7 +25,7 @@ EOT
sekret enc /dev/shm/new.yaml >secrets/$SECRET
rm /dev/shm/new.yaml
```
You can use a tool like [sops](https://github.com/mozilla/sops) or [sekret](https://github.com/nownabe/sekret) to generate the secrets file. Do the same for an sst-auth-password.
You can use a tool like [sops](https://github.com/mozilla/sops) or [sekret](https://github.com/nownabe/sekret) to generate the secrets file.

Set any local my.cnf values in files under a volume mount for
/etc/mysql/my.cnf.d (mapped as $ADMIN_PATH/mariadb/etc/). Use
Expand Down Expand Up @@ -90,9 +90,19 @@ cd docker-tools/k8s
make db00
~~~

### Restarting

When taking the database down, wait for all pods to stop, and then clear etcd entries for the cluster:
```
CLUSTER=db00
ETCD_HOST=10.101.1.19
etcdctl --endpoints=$ETCD_HOST:2379 del --prefix /galera/$CLUSTER
```
Then launch with the helm chart or docker-compose.

### Usage - swarm

This was originally developed under docker Swarm. A [docker-compose](https://github.com/instantlinux/docker-tools/blob/main/images/mariadb-galera/docker.compose) file is a legacy of that original work. Before stack-deploying it, invoke _docker secret create_ to generate the two secrets _mysql-root-password_ and _sst-auth-password-, and define an ADMIN_PATH environment variable pointing to your my.cnf (it has to be in the same location on each docker node).
This was originally developed under docker Swarm. A [docker-compose](https://github.com/instantlinux/docker-tools/blob/main/images/mariadb-galera/docker.compose) file is a legacy of that original work. Before stack-deploying it, invoke _docker secret create_ to generate the secret _mysql-root-password_, and define an ADMIN_PATH environment variable pointing to your my.cnf (it has to be in the same location on each docker node).

### Variables

Expand All @@ -102,11 +112,11 @@ This was originally developed under docker Swarm. A [docker-compose](https://git
| CLUSTER_NAME | cluster01 | cluster name |
| CLUSTER_SIZE | 3 | expected number of nodes |
| DISCOVERY_SERVICE | etcd:2379 | etcd host list, e.g. etcd1:2379,etcd2:2379 |
| LOG_LEVEL | info | set to debug for additional logging |
| REINSTALL_OK | | set to any value to enable reinstall over old volume |
| ROOT_PASSWORD_SECRET | mysql-root-password | name of secret for password |
| ROOT_SECNAME | mysql-root-password | name of secret for password |
| TTL | 10 | longevity (in seconds) of keys posted to etcd |
| TZ | UTC | timezone |
| SST_AUTH_SECRET | sst-auth-password | name of secret for password |

### Notes

Expand All @@ -129,6 +139,8 @@ configuration. It requires a stable etcd configuration for node
discovery and master election at restart. A single instance can
be invoked without HA resources using kubernetes-single.yaml.

There is no supported etcd3 library for python3 (as of Oct 2025). For now, this is using python-etcd3 0.12.0, last updated in 2020, with PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION set for compatibility.

### Credits

Thanks to ashraf-s9s of severalnines for the healthcheck script.
Expand Down
4 changes: 2 additions & 2 deletions images/mariadb-galera/helm/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ sources:
- https://github.com/MariaDB/server
- https://github.com/MariaDB/galera
type: application
version: 0.1.0
appVersion: "10.4.20"
version: 0.1.1
appVersion: "12.0.2"
dependencies:
- name: chartlib
version: 0.1.8
Expand Down
1 change: 0 additions & 1 deletion images/mariadb-galera/helm/templates/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ data:
# * InnoDB
#
innodb_data_file_path = ibdata1:10M:autoextend
innodb_buffer_pool_instances = {{ .Values.innodb_buffer_pool_instances }}
innodb_buffer_pool_size = {{ .Values.innodb_buffer_pool_size }}
innodb_log_file_size = {{ .Values.innodb_log_file_size }}
Expand Down
10 changes: 2 additions & 8 deletions images/mariadb-galera/helm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ ipReadOnly: 10.101.1.101
nodePort: 30306
character_set_server: utf8
ft_min_word_len: 3
innodb_buffer_pool_instances: 1
innodb_buffer_pool_size: 1024M
innodb_log_file_size: 32M
interactive_timeout: 28800
Expand All @@ -26,8 +25,9 @@ statefulset:
containerPorts: [ containerPort: 3306 ]
env:
cluster_name: mariadb
discovery_service: "10.101.1.19:2379"
cluster_size: 3
discovery_service: "10.101.1.19:2379"
log_level: info
replicas: 3
resources:
limits:
Expand All @@ -48,19 +48,13 @@ volumeMounts:
- name: mysql-root-password
mountPath: /run/secrets/mysql-root-password
subPath: mysql-root-password
- name: sst-auth-password
mountPath: /run/secrets/sst-auth-password
subPath: sst-auth-password
volumes:
- name: etc
configMap:
name: mariadb-galera
- name: mysql-root-password
secret:
secretName: mysql-root-password
- name: sst-auth-password
secret:
secretName: sst-auth-password
volumeClaimTemplates:
- metadata:
name: data
Expand Down
2 changes: 1 addition & 1 deletion images/mariadb-galera/hooks/add_tags
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/sh
TAG=$(grep "ARG .*_VERSION" Dockerfile | cut -d= -f 2)
TAG=$(grep "FROM mariadb:" Dockerfile | cut -d: -f 2)
echo "--tag $DOCKER_REPO:$TAG"
1 change: 1 addition & 0 deletions images/mariadb-galera/my.cnf
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ socket = /dev/shm/mysqld.sock
default_storage_engine = InnoDB
query_cache_size = 0
query_cache_type = 0
slave_connections_needed_for_purge = 0

innodb_flush_log_at_trx_commit = 0
innodb_flush_method = O_DIRECT
Expand Down
2 changes: 1 addition & 1 deletion images/mariadb-galera/requirements/common.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
python-etcd==0.4.5
etcd3==0.12.0
10 changes: 5 additions & 5 deletions images/mariadb-galera/requirements/test.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
coverage==5.4
flake8==3.9.0
mock==4.0.3
pytest==6.2.2
pytest-cov==2.11.1
coverage==7.11.0
flake8==7.3.0
mock==5.2.0
pytest==8.4.2
pytest-cov==7.0.0
Loading
Loading