Enterprise Java

Spring Boot Microservices , Docker and Kubernetes workshop – part3

In the previous posts we build few micro services (Order Service, Product Service, Customer Service) for an order management system using Docker and Spring Boot. We used Netflix libraries to manage, discover and load balance the micro services.

Managing these micro services and their multiple containers could get a bit tricky; especially in terms of Scalability, Observability, Security, Monitoring and managing resources. Hence we would use Kubernetes for our container orchestration. Click here to read more about Kubernetes.

In order to get started, we could either use a local Kube cluster in the laptop or use a cloud provider like AWS/Azure/GCP.

Local Kube Cluster :
We can use Minikube or Docker for Desktop for setting up local kube cluster. Follow their respective documentations to install them on your laptop/computer. In this tutorial we will be using Docker for Desktop on Mac, so if you are using the same follow this documentation for setting it up.

Use Amazon Elastic Kubernetes Service (EKS):
You can also set up a cluster on EKS to deploy the applications, for that you will need an account on AWS (https://aws.amazon.com/).
Once logged into AWS, go to EKS and create a Cluster. Read this documentation for setting up the cluster.

Kubectl :
KubeCtl is a command line interface for running commands against Kubernetes clusters. If you are using Docker for Desktop, it is already included and configured to connect to the local Kubernetes server, otherwise set up KubeCtl on your laptop using this documentation.

In order for kubectl to find and access a Kubernetes cluster, it needs a kubeconfig file. By default, kubectl configuration is located at:

1
~/.kube/config.

Check that kubectl is properly configured by getting the cluster state:

1
kubectl cluster-info

for managing cluster in EKS, use this documentation to set up kubeconfig.

Deploying Applications in Kube cluster :

Now that we have successfully created a kube cluster and have configured kubectl to manage and deploy into that cluster, we are ready to deploy our applications to it.

In the previous blogs we have created 3 microservices running in Docker containers. We can use the image of any of these microservices to deploy into kube cluster. If we are using local kube cluster (Docker for desktop or MiniKube) we can use the local docker image to deploy to the cluster.
(For local images to work, we need to set a property called “imagePullPolicy” to “Never” in our deployment definition.)

For EKS we will need the image to be in a registry, we can use docker hub public repo for now so we dont have to worry about authentication with with the registry. If we have to use ECR (Amazon Elastic Container Registry) we would need to give ECR pull permissions to the instances running the nodes in cluster, for simplicity, we will bypass this part for now.

Build local image

In order to deploy the application in local kube cluster, we will create its docker image in our laptop.

So, if you have the source code for any of the services we used in the previous blogs, we will use them.
– Go to the root folder of productService and run the docker build command :

1
docker build -t productservice .

This will create a local image with tag “productservice”. Test if this image works fine by running it.

1
docker run -p 8001:8001 productservice:latest

This service requires access to a local Postgres Database server, hence it fails to start. For simplicity, lets make a quick change to the application and use an in-memory DB (H2).
Make the following changes to build.gradle : (replace postgres depenendcy with H2)

1
2
3
4
5
6
7
8
dependencies {
    implementation('org.springframework.boot:spring-boot-starter-data-jpa')
    implementation('org.springframework.boot:spring-boot-starter-web')
    implementation('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')
    runtime("com.h2database:h2:1.3.176")
    compileOnly 'org.projectlombok:lombok:1.18.4'
    testImplementation('org.springframework.boot:spring-boot-starter-test')
}

And Replace the spring datasource to use H2 in application.properties :

1
2
3
4
5
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.h2.console.enabled=false

Once these 2 changes are done, the application would be good to start and work. This time rebuild the image (make sure you clean the old tag) and run it. Use the previous blog to test the endpoints. (create and get products @ /products)

Creating deployment.yaml
For deploying the images to kube, we need a deployment definition (or a pod definition if we just want to install a pod).

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
apiVersion: apps/v1
kind: Deployment
metadata:
  name: product-service-deployment
spec:
  selector:
    matchLabels:
      app: product-service
  replicas: 1
  template:
    metadata:
      labels:
        app: product-service
    spec:
      containers:
      - name: product-app
        image: productservice:latest
        imagePullPolicy: Never
        ports:
        - containerPort: 8001

Make sure to use the tag of the local image created in “name”.

Save the above file as product-service-deployment.yaml and run the following command from where the file is saved.

1
kubectl apply -f product-service-deployment.yaml

This will create a Pod in the cluster running the application inside the container. Now this application is running inside a pod in the kube cluster and has been assigned an IP address, which is accessible only from inside the cluster. We can access this pod from inside the cluster using this IP address, but as the pods are volatile (can be scaled up and scaled down, recreated and destroyed) we would need an interface or a service to access them by a “service name” which would not change when the pods are recreated. This “service” will also act as a load balancer for distributing requests to the pods.

Create a Kubernetes Service:
Now, we will create a service in Kubernetes which can be used to access the pod. Read more about Kubernetes services here. For this blog we will create a service of type “ClusterIP” which will be accessbile from withtin the cluster.
Create a file in the same root folder with the name product-service.yaml with the following contents:

01
02
03
04
05
06
07
08
09
10
apiVersion: v1
kind: Service
metadata:
  name: product-service
spec:
  selector:
    app: product-service
  ports:
  - port: 8001
    targetPort: 8001

To create this service, run the following command :

1
kubectl apply -f product-service.yaml

Run the kubectl get services command to see if the service is successfully created :

1
kubectl get svc

You should see the service “product-service” there with an assigned ClusterIP.

Access the service from your laptop.
To access this service from our laptop we will use something called as “kube port-forwarding” run the following command :

1
kubectl port-forward svc/product-service 8001:8001

Now we can access the service using http://localhost:8001/products.

You can test the product service by creating some products and retrieving them as mentioned in the previous blog.

So, we have now our application running in the local kube cluster.
In the next series of blogs we will deploy couple of more applications into the cluster with the external Database and have a fully functional microservices application. We will also learn how the internal services communicate with each other and how can we expose them to the outside world using Ingress Controller.

Published on Java Code Geeks with permission by Anirudh Bhatnagar, partner at our JCG program. See the original article here: Spring Boot Microservices , Docker and Kubernetes workshop – part3

 

Opinions expressed by Java Code Geeks contributors are their own.

Anirudh Bhatnagar

Anirudh is a Java programmer with extensive experience in building Java/J2EE applications. He has always been fascinated by the new technologies and emerging trends in software development. He has been involved in propagating these changes and new technologies in his projects. He is an avid blogger and agile enthusiast who believes in writing clean and well tested code.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button