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.
Let’s first start the
$ 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.
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
$ 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
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.
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
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.