Syntax highlighter header

Saturday, 12 June 2021

Running local Docker image in Minikube

I was using Minikube to learn Kubernetes. Kubernetes pulls images from public container registries or your private registry hosted on a public server.  I did not want to upload my confidential container images to any public repository or spend money in creating my private repository hosted on a public server.

In this post I am going to describe a method to run container images from my local machine in single node kubernetes cluster hosted in Minikube. I am doing this experiment on n CentOS 7 Laptop.

Creating a Dockerfile

For creating a container image you first need to create a Dockerfile. In Dockerfile you provide a base image and modification you want on top of the content provided by the base image.

You can refer to https://docs.docker.com/develop/develop-images/dockerfile_best-practices/ for more information on Dockerfile.

I am using a tomcat image and creating my image without doing any modification to it. I just want to test if Minikube will be able to pick my image locally.

My Dockerfile content is:

FROM tomcat:latest

Setting docker environment variables

Minikube runs inside a docker container on linux box and hosts a local docker registry there. You can point to that docker registry by setting some environment variables. These environment variables and their value is listed by running following command.


minikube docker-env

The output on my local machine is:


export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.49.2:2376"
export DOCKER_CERT_PATH="/home/deployer/.minikube/certs"
export MINIKUBE_ACTIVE_DOCKERD="minikube"

# To point your shell to minikube's docker-daemon, run:
# eval $(minikube -p minikube docker-env)

Creating Docker image

After setting these environment variables you can run following command to build your image:


docker build -t tomcat-jas .

Now my docker image named tomcat-jas is pushed to Minikube's container registry. Now we can use it in docker deployments. 

Creating Kubernetes deployment

We need to create deployment using yaml file instead of providing image name in kubectl command because there we can't provide imagePullPolicy parameter. My tomcat-jas.yaml file has following content:


apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-jas-deployment
  labels:
    app: tomcat-jas
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tomcat-jas
  template:
    metadata:
      labels:
        app: tomcat-jas
    spec:
      containers:
      - name: tomcat-jas
        image: tomcat-jas:latest
        imagePullPolicy: Never
        ports:
        - containerPort: 8080
      - name: httpd
        image: httpd:latest
        ports:
        - containerPort: 80

I am running two containers inside my pod one is httpd running at port 80 and another is tomcat running at port 8080. You can create deployment using following command:

kubectl create -f tomcat-jas.yaml

You can check status of you deployment using following command:


kubectl get deployment

Output on my machine is:


NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
balanced                1/1     1            1           13d
hello-minikube          1/1     1            1           13d
hello-node              1/1     1            1           13d
kubernetes-bootcamp     2/2     2            2           13d
tomcat-jas-deployment   1/1     1            1           2m21s

You can see that deployment is successfully running.

Exposing the deployment as a service

You can expose your newly created deployment to outside world using the following command:


kubectl expose deployment/tomcat-jas-deployment --type LoadBalancer --port 80,8080

You can check status of your service using following command:

kubectl get service

Output on my machine is:


NAME                    TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                       AGE
balanced                LoadBalancer   10.105.156.60   <pending>     8080:31961/TCP                13d
hello-minikube          NodePort       10.106.246.13   <none>        8080:31293/TCP                13d
hello-node              LoadBalancer   10.104.148.22   <pending>     8080:31192/TCP                13d
kubernetes              ClusterIP      10.96.0.1       <none>        443/TCP                       13d
kubernetes-bootcamp     NodePort       10.99.64.116    <none>        8080:30470/TCP                12d
tomcat-jas-deployment   LoadBalancer   10.103.14.144   <pending>     80:30147/TCP,8080:30692/TCP   19s

Accessing tomcat and httpd from your browser

The port 80 of our deployment is mapped to port number 30147 and port 8080 of our deployment is mapped to port 30690 of Minikube host. The IP address of host can be checked with following command:

minikube ip

Output of above command for me is:


192.168.49.2

You can combine port number and host IP address to make URL of exposed service for me URL will be http://192.168.49.2:30147 and http://192.168.49.2:30692

No comments:

Post a Comment