Start MariaDB in K8s
This is the first in a series of blogs explaining how to use MariaDB in Kubernetes (K8s), as well as explaining some important concepts of K8s and of MariaDB.
This blog explains how to start MariaDB as a stateless application in K8s using the CLI and explores different commands you can run on your CLI.
The prerequisites are that you have installed kubectl (which will also install Docker runtime) and minikube (local K8s).
Let’s first start the minikube
$ minikube start && kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane,master 104d v1.22.2
The Pod is a K8s resource and the smallest unit in K8s. It is an top abstraction in K8s layer over the container. Pods are ephemeral and can die easily, and when started again the new Pod will get a new IP. That is what stateless application means; there is no consistency of data in case Pods are restarted or removed. Usually a Pod is used to run 1 application container.
A Deployment is a K8s resource and it is an abstraction on top of Pods which have blueprints for Pods and help to interact with Pods, replicate them, etc.
The K8s API consists of other kind of resources that could be listed using kubectl api-resources
. There one can find Deployments, ReplicaSet, Secrets, ConfigMaps, Services, etc.
Start MariaDB from CLI
In order to create any resource from the CLI one needs to run the command kubectl create <resource> <name> --image=<image_name>
. In case of deployment of nginx for example, the last command will be kubectl create deployment nginx --image=nginx
.
To create and run the container, MariaDB needs to have at least one of the expected environment variables (see MariaDB Docker Library). We have to pass the environment variable, but I couldn’t find a way for kubectl create deployment to pass the environment variable to that command from the CLI. Later in this blog we are going to cover how to properly create and start deployment of MariaDB.
It is possible to start the Pod (although it is not recommended) and pass environment variables using the kubectl run command. Let’s use that command to set the root password with the MARIADB_ROOT_PASSWORD
environment variable.
$ kubectl run mariadb-test-pod --image=mariadb --env="MARIADB_ROOT_PASSWORD=secret"
pod/mariadb-test-pod created
To display the Pod (or any other resource) information (status/restarts/age) run
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
mariadb-test-pod 1/1 Running 0 2m37s
In order to log into the container one can use kubectl exec command. Let’s use that command to start mariadb
client within the container and execute a query:
$ kubectl exec -it mariadb-test-pod -- mariadb -uroot -psecret -e "select current_user()"
+----------------+
| current_user() |
+----------------+
| root@localhost |
+----------------+
Another useful command is kubectl logs which prints logs of containers in a Pod.
To see the logs of our created mariadb-test-pod
, run:
$ kubectl logs mariadb-test-pod
...
2022-03-16 7:54:43 0 [Note] mariadbd: ready for connections.
Version: '10.7.3-MariaDB-1:10.7.3+maria~focal' socket: '/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution
To debug Pod and get more information about Pod, run the kubectl describe command:
$ kubectl describe pod mariadb-test-pod
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 27m default-scheduler Successfully assigned default/mariadb-test-pod to minikube
Normal Pulling 27m kubelet Pulling image "mariadb"
Normal Pulled 27m kubelet Successfully pulled image "mariadb" in 19.675118703s
Normal Created 27m kubelet Created container mariadb-test-pod
Normal Started 27m kubelet Started container mariadb-test-pod
At the end, to delete the Pod, run the kubectl delete command:
$ kubectl delete pod mariadb-test-pod
pod "mariadb-test-pod" deleted
Start MariaDB using configuration files
Instead of using the CLI to start some resource in K8s, the recommended way is to create configuration YAML files.
Let’s create the YAML file mariadb-deployment.yaml. The file can be found on GitHub mariadb.org-tools.
apiVersion: apps/v1
kind: Deployment # what to create?
metadata:
name: mariadb-deployment
spec: # specification for deployment resource
replicas: 2 # how many replicas of pods we want to create
selector:
matchLabels:
app: mariadb
template: # blueprint for pods
metadata:
labels:
app: mariadb # service will look for this label
spec: # specification for pods
containers: # we can have one or more containers
- name: mariadb
image: mariadb
ports:
- containerPort: 3306
env:
#- name: MARIADB_RANDOM_ROOT_PASSWORD
- name: MARIADB_ALLOW_EMPTY_ROOT_PASSWORD
value: "0" # if it is 1 and root_password is set, root_password takes precedance
- name: MARIADB_ROOT_PASSWORD
value: secret
Note that we have specified what we want to create (Deployment).
Deployment is a resource that is a superset of Pod that can be scaled by the number of replicas that can be configured in the configuration file.
Each Pod has its labels that is a key-value pair that can be used to filter the Pods using kubectl commands as well as an interface to interact with services in the K8s cluster (we will explain service resources later).
Pod may have an array of containers, but we are creating a single container with the name mariadb (note this name is used by Deployment selector to create the containers), with the mariadb (latest) image, with ports and environment values.
To create and start the Deployment we need to use thekubectl apply command with the YAML file:
$ kubectl apply -f mariadb-deployment.yaml
deployment.apps/mariadb-deployment created
To display Deployment, run:
$ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
mariadb-deployment 2/2 2 2 48s
It displays that all 2 replicas of Deployment are ready and started.
To get information about the replica, display ReplicaSet resource:
$ kubectl get replicasets
NAME DESIRED CURRENT READY AGE
mariadb-deployment-9fd9fbbfd 2 2 2 3m26s
To get information about Pods, display Pod resource:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
mariadb-deployment-9fd9fbbfd-5rkzp 1/1 Running 0 106s
mariadb-deployment-9fd9fbbfd-jtbk2 1/1 Running 0 106s
Note that the ReplicaSet as well as Pods have a hash prefix at the end that K8s creates as an unique identifier. Each Pod in a K8s cluster has its unique IP, so when it gets deleted, a new Pod with a new IP is created leading to loss of data. Pod’s IPs can be found with the following command:
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mariadb-deployment-9fd9fbbfd-5rkzp 1/1 Running 0 5m22s 172.17.0.12 minikube <none> <none>
mariadb-deployment-9fd9fbbfd-jtbk2 1/1 Running 0 5m22s 172.17.0.8 minikube <none> <none>
To get logs of the container, run kubectl logs deploy/mariadb-deployment
.
To start mariadb
client we need to run kubectl exec
on a Pod with a hash name. In this case there are 2 Pods with different hash names, so we will test for both.
$ kubectl exec -it mariadb-deployment-9fd9fbbfd-5rkzp -- mariadb -uroot -psecret -e "select current_user()"
+----------------+
| current_user() |
+----------------+
| root@localhost |
+----------------+
$ kubectl exec -it mariadb-deployment-9fd9fbbfd-jtbk2 -- mariadb -uroot -psecret -e "select current_user()"
+----------------+
| current_user() |
+----------------+
| root@localhost |
+----------------+
In case demands get higher, one would need to scale the application. This is accomplished by changing the number of replicas in Deployment. This will ensure that new Pods are created and scheduled to nodes with available resources. To scale deployment up from 2 replicas to 4, run the following command:
$ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
mariadb-deployment 2/2 2 2 17m
$ kubectl scale deploy/mariadb-deployment --replicas=4
deployment.apps/mariadb-deployment scaled
$ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
mariadb-deployment 4/4 4 4 22m
Try to scale down yourself :).
In order to delete a Deployment (which will delete everything created by Deployment, like Pods and ReplicaSets), run:
$ kubectl delete deploy mariadb-deployment
deployment.apps "mariadb-deployment" deleted
Conclusion and future work
This blog showed how to create the MariaDB Pod in a K8s cluster and demonstrated the usage of basic kubectl commands to work with K8s. Additionally, Deployment was created from YAML file and we have seen how to scale Deployment.
In the next blog we are going to create a frontend Deployment to interact with Deployment in this blog (let’s call it backend) and explore other K8s concepts like Services, Secrets and ConfigMaps, what they are, how to create and how to use them.
You are welcome to chat about it on Zulip.
Read more
- Start MariaDB in K8s
- MariaDB & K8s: Communication between containers/Deployments
- MariaDB & K8s: Create a Secret and use it in MariaDB deployment
- MariaDB & K8s: Deploy MariaDB and WordPress using Persistent Volumes
- Create statefulset MariaDB application in K8s
- MariaDB replication using containers
- MariaDB & K8s: How to replicate MariaDB in K8s