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.