Container Registery and Minikube

In the previous post, we saw how to create a docker image out of a simple gradle/spring boot app and run it locally. In this post, we will push it to a container registry and use it to deploy it in a kubernetes cluster

Upload to Registry 

I created an account in Docker Hub and did a "docker login" in the command line with my credentials.

docker push neilghosh/gradle-spring-boot-app:latest

Note docker CLI bu default talks to Docker Hub, however one can log in to other container registries e.g. GCP's GCR or Azure's ACR by prefixing the image name with the fully qualified registry login URL.

Install and Setup Minikube
We can run Kubernetes locally using Minikube, this gives us the opportunity to develop/deploy/test quickly before we deploy into remote cluster available in GKE or AKS. Minikube uses a virtualization software like Virtual Box to deploy its containers

Download Virtual Box

Install Minikube

curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64  && chmod +x minikube

Note one can run minikube without using virtualization software as well but usually not recommended because of security and isolation concerns.

minikube start

Switch the context of "kubectl" CLI to "minikube" so that any further kubectl command actually talks to the locally installed kubernetes instead of any remote kubernetes cluster that is running and we may have used kubectl to manage that.

## kubectl config get-contexts
kubectl config use-context minikube
Switched to context "minikube".

Deploy to Kubernetes

We can go back to the gut repo where we have the simple springboot app and we have added some new configuration files (Kubernetes manifest) which will help in deploying the image from docker hub into the kubernetes cluster 


$ git clone https://github.com/neilghosh/simple-gradle-springboot-service.git
$ cd simple-gradle-springboot-service
$ kubectl apply -f deploy/app-httpsdeploy.yaml

deployment.apps/app-deployment created
service/app-backend created


Get the name of the pod its running the container

23:03 $ kubectl get pods

NAME                              READY     STATUS    RESTARTS   AGE

app-deployment-5bb7c7d847-6hlkj   1/1       Running   0          11m<

View/tail the logs from the pod

kubectl logs -t app-deployment-5bb7c7d847-6hlkj

You should be seeing the spring boot logs that was generated at the startup.

You can check the services that were created.

23:05 $ kubectl get services

NAME          TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE

app-backend   LoadBalancer   10.98.90.235          80:30451/TCP     13m

Note, since you are running in minikube it does not have any load balancer available like in cloud providers like GCP and AKS. So it will never get an external IP.

You can expose the service to the host name and launch in the browser with following

$ minikube service app-backend
## Or if you don't want tio launch it automatically
$ minikube service hello-minikube --url
http://192.168.99.103:30451

Note : As per documentation , you can emulate the load balancer and map it to a local IP. (You need to upgrade minikube to the latest version to use this feature). I haven't really tested it.

minikube tunnel

You can also see the kubernetes dashboard.

minikube dashboard
 
Here is the Manifest file that we used to deploy into kubernetes. It has one deployment which uses the simple springboot app image from the docker hub registry and exposes the port 8080.It also has a load balance which directs the traffic at port 80 from the outside of the cluster to the port 8080 of the deployment.

apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 1
template:
metadata:
labels:
app: app
spec:
containers:
- name: app
image: neilghosh/gradle-spring-boot-app:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: app-backend
spec:
type: LoadBalancer
selector:
app: app
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
---
Next time possibly we can deploy it to some remote cluster like GKE and configure HTTPS.