Deploying and scalling your Springboot application in a Kubernetes Cluster — Part1
I’ve recently wrote a tutorial about how to encapsulate a single Springboot application in a Docker container. If you haven't read that, I suggest you go there before continue this reading.
This tutorial will be divided in 2 parts. In the first part we are going to deploy our containerized Springboot application in a local cluster (a kubernets cluster running in our local computer). In the second one, we will deploy the same application in a kubernetes cluster hosted in a cloud provider (I haven't decided each one yet).
In order to run kubernetes on my local computer, I'm going to use the docker for mac (that has a single-node kubernetes cluster embedded). The following tutorial explains in a very good way how to get start with kubernets with docker for mac:
There are another ways to run kubernets on your local machine. One good option is to use minikube. The documentation about getting start with minikube is at the kubernetes oficial website:
https://kubernetes.io/docs/tutorials/hello-minikube
Whatever way you choose, you are gonna need two things:
- Kubernets (1.8+) up and running in your local computer (dã)
- kubectl (kubernets CLI) installed
I assume that you already know the basics about kubernetes. Just to be sure, let's recap some important concepts about kubernetes objects:
- Pod: It's the atomic unit of deployment. A pod encapsulates one or more containers (in our case, docker containers).
- ReplicaSet: Encapsulates a set of Pods, and manages the scalling.
- Deployments: Encapsulates a ReplicaSet, and manages the updates, rollbacks, and another things.
- Service: Expose a set of Pods to be consumed for another applications (inside or outside the kubernetes cluster), and manages things like load balancing.
In our case, as we already have a functional container image with our Springboot application in it, all we need to do is:
- Create a Pod manifest with our container image
- Create a ReplicaSet manifest to scale our application (deploy more than one container instance in order to have scalability and contingency)
- Create a Deployment manifest and deploy it to our kubernetes cluster
- Create a Service manifest to expose our Pods to be consumed as a service by other applications outside the cluster
The first three steps can be done with a single yaml file. You can give whatever name you want to the file. I'm gonna call it k8s-deploy.yml. The yaml should have the following content:
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: k8s-spring-sample-deploy
spec:
replicas: 3
selector:
matchLabels:
app: k8s-spring-sample
minReadySeconds: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
app: k8s-spring-sample
spec:
containers:
- name: k8s-spring-sample
image: caiopereirasousa/spring-boot-sample
ports:
- containerPort: 8080
In the manifest file above we are defining basically two thing:
- The Pods that are going to be deployed in our kubernetes cluster encapsulate a docker container based on the caiopereirasousa/spring-boot-sample image (if you had published your image on docker hub, you can replace the "image" property with the name of your own).
- We want kubernetes to create 3 Pod instances, in order to scale our application.
Once you have created and saved the yaml file, open the terminal and execute the following command. It will send the deploy instructions to your kubernetes cluster:
$ kubectl apply -f k8s-deploy.yml
You should see the message "deployment.apps/k8s-spring-sample-deploy created" in your terminal. Execute the get pods command to see if kubernetes is creating and starting the Pods correctly:
$ kubectl get pods
If everything goes well, you should see something like this in your terminal:
NAME READY STATUS RESTARTS AGEk8s-spring-sample-deploy-757764fd97-jxxtm 0/1 ContainerCreating 0 4sk8s-spring-sample-deploy-757764fd97-r8b5t 0/1 ContainerCreating 0 4sk8s-spring-sample-deploy-757764fd97-s2rwf 0/1 ContainerCreating 0 4s
Execute the same command after a while to see if the Pods are already in a "running" state (it can take a few seconds, or minutes depending of your internet connection):
NAME READY STATUS RESTARTS AGEk8s-spring-sample-deploy-757764fd97-jxxtm 1/1 Running 0 15sk8s-spring-sample-deploy-757764fd97-r8b5t 1/1 Running 0 15sk8s-spring-sample-deploy-757764fd97-s2rwf 1/1 Running 0 15s
Ok, at this point we already have our Springboot application up and running in the kubernetes cluster. Repare that kubernetes has created 3 Pods. It is because we fill the "replicas" property with the value "3" in the manifest file. You can change this number and re-send the manifest to kubernetes and see how the cluster creates and terminates the Pods according to the number of replicas in the manifest.
The next step is to expose the Pods as a service. To do that, we should create a service manifest and send it to the cluster. Create another yaml file called "k8s-svc.yml", with the following content:
apiVersion: v1
kind: Service
metadata:
name: k8s-spring-sample-service
labels:
app: k8s-spring-sample
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30001
protocol: TCP
selector:
app: k8s-spring-sample
This manifest tells kubernetes to create a service object and link it to all the Pods that are tagged with "app: k8s-spring-sample". The service will listen in the port 30001.
Send the manifest to kubernetes with the following command:
$ kubectl apply -f k8s-svc.yml
The message "service/k8s-spring-sample-service created" should be displayed in your teminal.
Finally, it is time to prove if everything is working fine. Type the following URL in your browser: http://localhost:30001
If you see the message "Greetings from Spring Boot!" it means that everything is fine! We have deployed and scaled our application in the kubernetes cluster!
If something goes wrong or you have any doubts about this tutorial, please leave your comment. The code used is published in my github:
See you in part 2.
Good coding for everyone!