Deploy Spring Boot App on Kubernetes (Minikube) on MacOS

KARAN VERMA
Aug 20, 2020 · 5 min read
Image for post
Image for post

Spring-boot app is all about annotation based development and fast code deployments within embedded servers and all.

To take it further, containerising a spring-boot is an added technical skill, which is in high demand currently.

So lets learn to containerise a spring-boot application. Here are the steps covered in this article:

  1. Install Docker
  2. Install Virtual box
  3. Install Kubernetes on MacOS (Minikube)
  4. Install network gateways (Istio-ingress)
  5. Create docker image
  6. Create kubernetes yaml file
  7. Deploy on kubernetes cluster (minikube)
  8. Enable Port forwarding
  9. Monitor application deployment (Kiali and Lens)

Prerequisite :
a. I assume you should know Spring-boot app creation and project setup before moving further. If you are not familiar with this, go through complete setup process
in this article.

b. Further, i assume you have an initial knowledge on how to create a Dockerfile to create docker image and how to create a kubernetes yaml file for deployments.

Let’s move with the scope of this article now.

Follow the instruction to install docker on your mac from this docker official link.

Before installing Kubernetes (Minikube), let’s install virtualBox first. Minikube by default uses hyperkit as the VM, which has some connectivity issues with Docker images specifically on MacOS. So to get rid of those issues, we need Virtualbox as the VM.

Download the Virtual box dmg file for MacOS from this link.
Follow the installation steps and thats it.

The simplest way to install Kubernetes is by using brew as follow:

brew install minikube

Once the installation is completed, you just need to start it using the Virtualbox VM using the following command:

minikube start — vm-driver=virtualbox

and can check the status using:

minikube status

Now that kubernetes is installed and the cluster is up, we need to install the network related stuff so that our application can talk to outside world and the application is exposed to outside world.

And for all that stuff, we will be using istio as the ingress controller. If you need more details about ingress and istio, please check these links.

To install istio, follow the steps in this link which states following commands:

curl -L https://istio.io/downloadIstio | sh -
cd istio-1.6.8
export PATH=$PWD/bin:$PATH
//where PWD is path of istio install directory
istioctl install --set profile=demo

If you face problems in installations, try increasing the memory assigned to minikube using below command and re-initiate the istio installation:

minikube config set memory 4096

After that, istio will be installed.

Now we need configure the network gateways using the following steps:

a. Create namespaces

kubectl create namespace istio-system

b. Create istio gateway resources

Now create istio gateway resources using the following istio.yml:

kind: Service
apiVersion: v1
metadata:
name: istio-ingressgateway-internal
namespace: istio-system
labels:
app: istio-ingressgateway
istio: ingressgateway
release: istio
spec:
ports:
- name: status-port
protocol: TCP
port: 8080
targetPort: 8080
nodePort: 32200
- name: http2
protocol: TCP
port: 80
targetPort: 80
nodePort: 31390
- name: mongodb
protocol: TCP
port: 27017
targetPort: 27017
nodePort: 33033
selector:
app: istio-ingressgateway
istio: ingressgateway
release: istio
type: LoadBalancer
sessionAffinity: None
externalTrafficPolicy: Cluster

and execute this file using:

kubectl apply -f istio.yml

This will create the resources related to istio ingress and network gateways.

c. Create our app namespace

Create a namespace for your application as follows:

kubectl create namespace myapp

d. Create our app gateway which will use istio gateway

And create a gateway resource(myaap-gateway.yml) for your application which will use the above istio gateway for connectivity as follows:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: myapp-gateway
namespace: myapp
spec:
selector:
istio: istio-ingressgateway-internal
controller
servers:
- port:
number: 80
name: http
protocol: HTTP2
hosts:
- "host.docker.internal"

and execute this using:

kubectl apply -f myapp-gateway.yml

e. Enable istio injection for our app

kubectl label namespace myapp istio-injection=enabled

5. Create docker image

Now we need to create a docker image of our spring-boot application.
As stated previously, this article assumes that you know what is spring-boot, what is docker image and its internal and what is kubernetes yaml file.

To create the docker image of you spring-boot apllication, you need to simply add a Dockerfile in your project root directory and add the commands for docker image creation. For more details on how to create a docker file, see this link.

Our sample Dockerfile is as follows:

FROM adoptopenjdk/openjdk11:alpine-jre

COPY my-app/target/*.jar /myapp/myapp.jar
EXPOSE 8080

ENTRYPOINT ["java", "-jar","/myapp/myapp.jar"]

What is does is simply copies my-app springboot jar to /myapp/myapp.jar, and then executes that jar using java -jar command.

Start docker on you local machine.

Now to create an image from this file, cd to our project root directory in terminal where you just created the Dockerfile and execute the following command:

cd my-app

docker build -t my-app .

This will create an image o f your spring boot application.

Now that our image is ready, we need to create a kubernetes yaml file to tell the cluster on how create the deployment, services and pods (all kubernetes related terms).

To check on how to create the yaml file and what all things it includes, please check this link and this link.

Our sample myapp.yaml file is as follows:

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: myapp
labels:
app: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp
ports:
- containerPort: 8080
imagePullPolicy: Never
---
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: myapp
spec:
ports:
- nodePort: 32000
port: 8080
targetPort: 8080
selector:
app: myapp
type: LoadBalancer
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: myapp
namespace: myapp
spec:
hosts:
- '*'
gateways:
- myapp-gateway
http:
-
match:
- uri:
prefix: /myapp
route:
- destination:
host: myapp.myapp.svc.cluster.local
port:
number: 8080

To deploy the application, execute the following command:

kubectl apply -f myapp.yml

And this will create your deployment, pod, replica set, service and virtual service.

Enable the port forwarding using following command:

kubectl port-forward services/myapp 8080:8080 -n myapp

and now your can access your add on http://localhost:8080

Now to monitor ur application, you can use kiali using the following command:

istioctl d kiali

which will open a web portal in browser and you can check the status of you pods and deployments.

So these are the complete steps to deploy a spring boot application on kubernetes on MacOS local environment.

Hope you enjoyed the article. Keep Learning !!!

The Startup

Medium's largest active publication, followed by +754K people. Follow to join our community.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store