MariaDB Kubernetes Setup

Based on the tutorial Laravel in Kubernetes I have been setting up a Databased in Kubernetes, since my preferred choice is MariaDB, and it tends to largely work the same as MySQL, used in this tutorial I decided to switch it out, as I am running locally and not on a cloud provider a couple changes are required.

Providing storage

As my local install of Kubernetes doesn’t use a cloud provider for storage but is self contained on my desktop, I am using local-path-provisioner to provide the backend for the persistent volume claims, installing worked straight out of the box, no issues.

Provisioning MariaDB

MariaDB is providing images to use on hub.docker.com so no issues, here and since MariaDB works mostly like MySQL the configuration options are very similar, except switching the names, which is actually optional. The big issue I ran into is that in the original tutorial a livenessProbe and a readinessProbe are setup to restart the container if required.

livenessProbe:
  exec:
    command:
    - bash
    - -c
    - mysqladmin -u ${MARIADB_USER} -p${MARIADB_PASSWORD} ping
  initialDelaySeconds: 10
  periodSeconds: 5
  timeoutSeconds: 5
readinessProbe:
    exec:
      command:
      - bash
      - -c
      - mysql -u ${MARIADB_USER} -p${MARIADB_PASSWORD} -e "SELECT 1"
    initialDelaySeconds: 5
    periodSeconds: 2
    timeoutSeconds: 1

A readinessProbe does not however delay the livenessProbe also the time given, 10sec, seems to be to short, at least in my setup so my databased continued to be restarted during initialization leaving it not working since the MariaDB startup script will only attempt the database setup if the data directory is empty, which it will only be on the first start. This leaves the database in a state without users, or properly set passwords. The fix, and likely “better” way of handling this for me was replacing the readinessProbe with a startupProbe.

livenessProbe:
  exec:
    command:
    - bash
    - -c
    - mysqladmin -u ${MARIADB_USER} -p${MARIADB_PASSWORD} ping
  periodSeconds: 10
startupProbe:
  exec:
    command:
    - bash
    - -c
    - mysql -u ${MARIADB_USER} -p${MARIADB_PASSWORD} -e "SELECT 1"
  periodSeconds: 10
  failureThreshold: 60 # total 60x10s = 600s = 10min to initialize

The final setup that works for me I uploaded in a Gist seperated into files for each part. With all the files present and local-path-provisioner installed kubectl apply -f . should work, make sure to replace the secrets in secrets.yml with base64encoded proper values.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.