This blog entry is part of the series of blogs to productionise a docker image in Kubernetes for enterprises. In our previous article, we saw a quick way of deploying Docker images to Kubernetes using imperative commands. In this entry, we will see a way of managing kubernetes objects in a minikube cluster using YMAL/JSON config files.

Minikube is a tool that runs a single-node Kubernetes cluster in a virtual machine on your personal computer. Deploying it in Minikube normally means you will be able to deploy your Docker images in most other versions of Kubernetes without many modifications.

For the sake of simplicity, we shall pick a couple of docker images from open libraries.

  • Mariadb is a community-developed fork of MySQL DB intended to remain free under the GNU GPL
  • PhpMyAdmin A web interface for MySQL and MariaDB administration. 

This is a quick way of a simulating an application stack with a 2-tier based web architecture and orchestration of multiple docker containers.

Deploying using YAML/JSON

Keeping the configurations for objects in files enables easy CI/CD and easy replication across environments with source control. A detailed explanation of different ways of creating Kubernetes resources and their pros/cons is available here.

Start a quick single-node cluster

minikube start

Login to Docker

docker login

A Kubernetes Pod is a group of one or more Containers, tied together for the purposes of administration and networking.

A Kubernetes Deployment checks on the health of your Pod and restarts the Pod’s Container if it terminates. Deployments are the recommended way to manage the creation and scaling of Pods.

For the benefit of our exercise, we will stick to the model of one container per pod.

Deploy Mariadb

Create a secret for storing the password for MariaDB root user. Kubernetes Secrets let you store and manage sensitive information, such as passwords, OAuth tokens, and ssh keys. Storing confidential information in a Secret is safer and more flexible than putting it verbatim in a Pod definition or in a container image.

kubectl create secret generic mariadb-secret --from-literal=root_pwd=changeit 

Create deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mariadb
spec:
  selector:
    matchLabels:
      app: mariadb
  template:
    metadata:
      labels:
        app: mariadb
spec:
  containers:
  - env:
    - name: MYSQL_ROOT_PASSWORD
      valueFrom:
        secretKeyRef:
          name: mariadb-secret
          key: root_pwd
      name: mariadb
  image: docker.io/mariadb:latest
  ports:
  - containerPort: 3306

Create deployment using the above deployment.yaml

kubectl apply -f deployment.yaml

Get pod name for mariadb from the list of running pods

kubectl get pods

NAME READY STATUS RESTARTS AGE
mariadb-7bb67dd9fc-8kjpm 1/1 Running 0 14h

To make the mariadb Container accessible from outside the Kubernetes virtual network, you have to expose the Pod as a Kubernetes Service. Create mariadb service of type “ClusterIP” on top of deployment so its only accessible within the cluster in port 3306.

Create service.yaml

apiVersion: v1
kind: Service
metadata:
  labels:
    app: mariadb
  name: mariadb
spec:
  ports:
  - name: tcp-3306
    port: 3306
    targetPort: 3306
  selector:
    app: mariadb

Expose mariadb service using above service.yaml

kubectl apply -f service.yaml

Check the list of services running to see if mariadb is exposed on this port

kubectl get svc

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mariadb ClusterIP 10.99.151.240 3306/TCP 13h

Deploy PhpMyAdmin

A ConfigMap is an API object used to store non-confidential data in key-value pairs. Pods can consume ConfigMaps as environment variables, command-line arguments, or as configuration files in a volume. A ConfigMap allows you to decouple environment-specific configuration from your container images, so that your applications are easily portable. We will store the database host name property in a config map.

Create configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: phpmyadmin-config
data:
  # property-like keys; each key maps to a simple value
  root_pwd: "mariadb"

Create the configmap

kubectl apply -f configmap.yaml

Create deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: phpmyadmin
spec:
  selector:
    matchLabels:
      app: phpmyadmin
  template:
    metadata:
      labels:
        app: phpmyadmin 
  spec:
    containers:
    - env:
      - name: MYSQL_ROOT_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mariadb-secret
            key: root_pwd
      - name: PMA_HOST
        valueFrom:
          configMapKeyRef:
            name: phpmyadmin-config
            key: root_pwd
      name: phpmyadmin
      image: docker.io/phpmyadmin/phpmyadmin:latest
      ports:
      - containerPort: 80

Get pod name for phpmyadmin from the list of running pods

kubectl get pods

NAME READY STATUS RESTARTS AGE
mariadb-7bb67dd9fc-8kjpm 1/1 Running 0 14h
phpmyadmin-7559f85f5b-ppjwk 1/1 Running 0 13h

Expose phpmyadmin as a service for the pod port 80 to be accessible from external world in port 80, keep the service type To “LoadBalancer”.

Create service.yaml

apiVersion: v1
kind: Service
metadata:
  labels:
    app: phpmyadmin
  name: phpmyadmin
spec:
  ports:
  - name: http-80
    port: 8080
    targetPort: 80
  selector:
    app: phpmyadmin
  type: LoadBalancer

Expose phpmyadmin service using above service.yaml

kubectl apply -f service.yaml

Check the list of services running to see if phpmyadmin and mariadb are exposed as services

kubectl get svc

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 34d
mariadb ClusterIP 10.99.151.240 3306/TCP 14h
phpmyadmin LoadBalancer 10.105.202.36 80:31779/TCP 13h

View the phpmyadmin service in browser using the below command

minikube service phpmyadmin

Login using ‘root’ as Username and ‘changeit’ as password. Click on the SQL tab and execute a sample query “select 1 from dual”, hit “Go” button to see results(as below). Also, this will prove end to end connectivity.

Delete the resources

kubectl delete deployment phpmyadmin
kubectl delete deployment mariadb
kubectl delete svc mariadb
kubectl delete svc phpmyadmin
kubectl delete secret mariadb-secret
kubectl delete configmap phpmyadmin-config

This is a quick way of getting your docker images deployed into Kubernetes. Many organisations tend to keep resource creation via YAML/JSONs and use for automation. With these YAML files in place, We will see the declarative deployments of these files in our next article.

Leave a Reply

Your email address will not be published. Required fields are marked *