Deploying your docker image to kubernetes in 5 mins

This blog entry is part of the series of blogs to productionise a docker image in kubernetes for enterprises. Considering you have already understood the benefits of containerization, docker, kubernetes and want to take the brave step of migrating your existing docker images to kubernetes, this blog will give you quick steps using minikube version of kubernetes.

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 commands

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 deployment

kubectl create deployment mariadb --image=docker.io/mariadb:latest

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

Check logs for mariadb pod, this will indicate that pods are failing to run because of the absence of required property MYSQL_ROOT_PASSWORD

kubectl logs mariadb-7bb67dd9fc-8kjpm

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=MYSQL_ROOT_PASSWORD=changeit

Pass this as an environment property to the deployment

kubectl set env --from=secret/mariadb-secret deployment/mariadb

Restart the pod, so the docker image can pick up the root password during initialisation. There are 3 ways to restart a pod and my preferred way is as below.

kubectl rollout restart deployment/mariadb

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.

kubectl expose deployment mariadb --port=3306 --type=ClusterIP

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

Create deployment

kubectl create deployment phpmyadmin --image=docker.io/phpmyadmin/phpmyadmin:latest

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

Check logs for phpmyadmin pod, this will indicate that pods are failing to run because of the absence of required properties MYSQL_ROOT_PASSWORD

kubectl logs phpmyadmin-7559f85f5b-ppjwk

Pass the root user password and database hostname as environment properties to the deployment

kubectl set env --from=secret/mariadb-secret deployment/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.

kubectl create configmap phpmyadmin-config --from-literal=PMA_HOST=mariadb

Set env variable on PHPMyAdmin deployment from configmap

kubectl set env --keys=PMA_HOST --from=configmap/phpmyadmin-config deployment/phpmyadmin

Restart the pod, so the docker image can pick up the required properties during initialisation. One of the easiest way to restart is scale down to 0 and scale up the pod.

kubectl scale --replicas=0 deployments/phpmyadmin
kubectl scale --replicas=1 deployments/phpmyadmin

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”.

kubectl expose deployment phpmyadmin  --port=80 --target-port=80 --type=LoadBalancer

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. Normally imperative command creation of Kubernetes resources is not the preferred approach beyond development environment and we will see deploying your docker images in a declarative way in this article. A detailed explanation of different ways of creating Kubernetes resources and their pros/cons is available here.

Leave a Reply

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