Deploy Spring Boot App on Kubernetes (Minikube) on MacOS

KARAN VERMA
The Startup
Published in
5 min readAug 20, 2020

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.

1. Install Docker

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

2. Install Virtual box

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.

3. Install Kubernetes on MacOS (Minikube)

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

Update: For M1 Chip Macs, use the following commands to install minikube

curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-arm64
sudo install minikube-darwin-arm64 /usr/local/bin/minikube

To run the minikube on m1 chip, use below command

minikube start — driver=docker — alsologtostderr

4. Install network gateways (Istio-ingress)

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.

6. Create kubernetes yaml file

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

7. Deploy on kubernetes cluster (minikube)

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.

8. Port forwarding for myapp 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

9. Monitor application deployment (Kiali and Lens)

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 !!!

--

--