Explore Developer Center's New Chatbot! MongoDB AI Chatbot can be accessed at the top of your navigation to answer all your MongoDB questions.

Join us at AWS re:Invent 2024! Learn how to use MongoDB for AI use cases.
MongoDB Developer
Java
plus
Sign in to follow topics
MongoDB Developer Centerchevron-right
Developer Topicschevron-right
Languageschevron-right
Javachevron-right

Using Azure Kubernetes Services for Java Spring Boot Microservices

Tim Kelly9 min read • Published Apr 15, 2024 • Updated Apr 15, 2024
AzureSpringKubernetesJava
FULL APPLICATION
Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty

Introduction

In the early days of software development, application development consisted of monolithic codebases. With challenges in scaling, singular points of failure, and inefficiencies in updating, a solution was proposed. A modular approach. A symphony of applications managing their respective domains in harmony. This is achieved using microservices.
Microservices are an architectural approach that promotes the division of applications into smaller, loosely coupled services. This allows application code to be delivered in manageable pieces, independent of each other. These services operate independently, addressing a lot of the concerns of monolithic applications mentioned above.
While each application has its own needs, microservices have proven themselves as a viable solution time and time again, as you can see in the success of the likes of Netflix.
In this tutorial, we are going to deploy a simple Java Spring Boot microservice application, hosted on the Azure Kubernetes Service (AKS). AKS simplifies deploying a managed Kubernetes cluster in Azure by offloading the operational overhead to Azure. We'll explore containerizing our application and setting up communication between our APIs, a MongoDB database, and the external world. You can access the full code here:
1git clone https://github.com/mongodb-developer/simple-movie-microservice.git
Though we won't dive into the most advanced microservice best practices and design patterns, this application gives a simplistic approach that will allow you to write reviews for the movies in the MongoDB sample data, by first communicating with the review API and that service, verifying that the user and the movie both exist. The architecture will look like this.
The architecture diagram for the microservice application.
Simple, right? Exactly! And AKS makes it even easier to communicate with other APIs managed on the service. In a microservices architecture, services need to discover each other dynamically. Kubernetes itself acts as a service registry, where each service in the cluster has a unique name. So when we communicate with our other services in ReviewController.java, we simply send a request to http://user-management-service/users/. In this demo application, communication is done with RESTful HTTP/S requests, using RestTemplate.

Prerequisites

Before you begin, you'll need a few prerequisites to follow along with this tutorial, including:

Set up an Azure Kubernetes Service cluster

Starting from the very beginning, set up an Azure Kubernetes Service (AKS) cluster.

Install kubectl and create an AKS cluster

Install kubectl, the Kubernetes command-line tool, via the Azure CLI with the following command (you might need to sudo this command), or you can download the binaries from:
1az aks install-cli
Log into your Azure account using the Azure CLI:
1az login
Create an Azure Resource Group:
1az group create --name myResourceGroup --location northeurope
Create an AKS cluster: Replace myAKSCluster with your desired cluster name. (This can take a couple of minutes.)
1az aks create --resource-group myResourceGroup --name myAKSCluster --node-count 2 --enable-addons monitoring --generate-ssh-keys

Configure kubectl to use your AKS cluster

After successfully creating your AKS cluster, you can proceed to configure kubectl to use your new AKS cluster. Retrieve the credentials for your AKS cluster and configure kubectl:
1az aks get-credentials --resource-group myResourceGroup --name myAKSCluster

Create an Azure Container Registry (ACR)

Create an ACR to store and manage container images across all types of Azure deployments:
1az acr create --resource-group <your-resource-group> --name <your-container-registry> --sku Basic
Note: Save the app service id here. We’ll need it later when we are creating a service principal.
Log into ACR:
1az acr login --name <your-container-registry>

Containerize your microservices application

Each of your applications (User Management, Movie Catalogue, Reviews) has a Dockerfile. Create a .jar by running the command mvn package for each application, in the location of the pom.xml file. Depending on your platform, the following steps are slightly different.
For those wielding an M1 Mac, a bit of tweaking is in order due to our image's architecture. As it stands, Azure Container Apps can only jive with linux/amd64 container images. However, the M1 Mac creates images as arm by default. To navigate this hiccup, we'll be leveraging Buildx, a handy Docker plugin. Buildx allows us to build and push images tailored for a variety of platforms and architectures, ensuring our images align with Azure's requirements.

Build the Docker image (not M1 Mac)

To build your image, make sure you run the following command in the same location as the Dockerfile. Repeat for each application.
1docker build -t movie-catalogue-service .
Or you can run the following command from the simple-movie-microservice folder to loop through all three repositories.
1for i in movie-catalogue reviews user-management; do cd $i; ./mvnw clean package; docker build -t $i-service .; cd -; done

Build the Docker image (M1 Mac)

If you are using an M1 Mac, use the following commands to use Buildx to create your images:
1docker buildx install
Next, enable Buildx to use the Docker CLI:
1docker buildx create --use
Open a terminal and navigate to the root directory of the microservice where the Dockerfile is located. Run the following command to build the Docker image, replacing movie-catalogue-service with the appropriate name for each service.
1docker buildx build --platform linux/amd64 -t movie-catalogue-service:latest --output type=docker .

Tag and push

Now, we're ready to tag and push your images. Replace <your-acr-name> with your actual ACR name. Repeat these two commands for each microservice.
1docker tag movie-catalogue-service <your-acr-name>.azurecr.io/movie-catalogue-service:latest
2docker push <your-acr-name>.azurecr.io/movie-catalogue-service:latest
Or run this script in the terminal, like before:
1ACR_NAME="<your-acr-name>.azurecr.io"
2
3for i in movie-catalogue reviews user-management; do
4 # Tag the Docker image for Azure Container Registry
5 docker tag $i-service $ACR_NAME/$i-service:latest
6 # Push the Docker image to Azure Container Registry
7 docker push $ACR_NAME/$i-service:latest
8done

Deploy your microservices to AKS

Now that we have our images ready, we need to create Kubernetes deployment and service YAML files for each microservice. We are going to create one mono-file to create the Kubernetes objects for our deployment and services. We also need one to store our MongoDB details. It is good practice to use secrets for sensitive data like the MongoDB URI.

Create a Kubernetes secret for MongoDB URI

First, you'll need to create a secret to securely pass the MongoDB connection string to your microservices. In Kubernetes, the data within a secret object is stored as base64-encoded strings. This encoding is used because it allows you to store binary data in a format that can be safely represented and transmitted as plain text. It's not a form of encryption or meant to secure the data, but it ensures compatibility with systems that may not handle raw binary data well.
Create a Kubernetes secret that contains the MongoDB URI and database name. You will encode these values in Base64 format, but Kubernetes will handle them as plain text when injecting them into your pods. You can encode them with the bash command, and copy them into the YAML file, next to the appropriate data keys:
1echo -n 'your-mongodb-uri' | base64
2echo -n 'your-database-name' | base64
This is the mongodb-secret.yaml.
1apiVersion: v1
2kind: Secret
3metadata:
4 name: mongodb-secret
5type: Opaque
6data:
7 MONGODB_URI: <Base64 encoded MongoDB URI>
8 MONGODB_DATABASE: <Base64 encoded MongoDB database name>
Run the following command to apply your secrets:
1kubectl apply -f mongodb-secret.yaml
So, while base64 encoding doesn't secure the data, it formats it in a way that's safe to store in the Kubernetes API and easy to consume from your applications running in pods.

Authorize access to the ACR

If your ACR is private, you'll need to ensure that your Kubernetes cluster has the necessary credentials to access it. You can achieve this by creating a Kubernetes secret with your registry credentials and then using that secret in your deployments.
The next step is to create a service principal or use an existing one that has access to your ACR. This service principal needs the AcrPull role assigned to be able to pull images from the ACR. Replace <your-service-principal-name>, <your-subscription-id>, <your-resource-group-name>, and <your-acr-name> with your own values.
: This can be any unique identifier you want to give this service principal.
: You can get the id for the subscription you’re using with az account show --query id --output tsv.
: Use the same resource group you have your AKS set up in.
: This is the Azure Container Registry you have your images stored in.
1az ad sp create-for-rbac --name <your-service-principal-name> --role acrPull --scopes /subscriptions/<your-subscription-id>/resourceGroups/<your-resource-group-name>/providers/Microsoft.ContainerRegistry/registries/<your-acr-name>
This command will output JSON that looks something like this:
1{
2 "appId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
3 "displayName": "<your-service-principal-name>",
4 "password": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
5 "tenant": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
6}
  • appId is your <your-service-principal-app-id>.
  • password is your <your-service-principal-password>.
Note: It's important to note that the password is only displayed once at the creation time. Make sure to copy and secure it.
Create a Kubernetes secret with the service principal's credentials. You can do this with the following command:
1kubectl create secret docker-registry acr-auth \
2 --namespace default \
3 --docker-server=<your-acr-name>.azurecr.io \
4 --docker-username=<your-service-principal-app-id> \
5 --docker-password=<your-service-principal-password> \
6 --docker-email=<your-email>

Create Kubernetes deployment and service YAML files

There are a couple of points to note in the YAML file for this tutorial, but these points are not exhaustive of everything happening in this file. If you want to learn more about configuring your YAML for Kubernetes, check out the documentation for configuring Kubernetes objects.
  • We will have our APIs exposed externally. This means you will be able to access the endpoints from the addresses we'll receive when we have everything running. Setting the type: LoadBalancer triggers the cloud provider's load balancer to be provisioned automatically. The external load balancer will be configured to route traffic to the Kubernetes service, which in turn routes traffic to the appropriate pods based on the service's selector.
  • The containers: section defines a single container named movie-catalogue-service, using an image specified by <your-container-registry>/movie-catalogue-service:latest.
  • containerPort: 8080 exposes port 8080 inside the container for network communication.
  • Environment variables MONGODB_URI and MONGODB_DATABASE are set using values from secrets (mongodb-secret), enhancing security by not hardcoding sensitive information.
  • imagePullSecrets: - name: acr-auth allows Kubernetes to authenticate to a private container registry to pull the specified image, using the secret we just created.
1---
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5 name: movie-catalogue-service-deployment
6spec:
7 replicas: 1
8 selector:
9 matchLabels:
10 app: movie-catalogue-service
11 template:
12 metadata:
13 labels:
14 app: movie-catalogue-service
15 spec:
16 containers:
17 - name: movie-catalogue-service
18 image: <your-container-registry>/movie-catalogue-service:latest
19 ports:
20 - containerPort: 8080
21 env:
22 - name: MONGODB_URI
23 valueFrom:
24 secretKeyRef:
25 name: mongodb-secret
26 key: MONGODB_URI
27 - name: MONGODB_DATABASE
28 valueFrom:
29 secretKeyRef:
30 name: mongodb-secret
31 key: MONGODB_DATABASE
32 imagePullSecrets:
33 - name: acr-auth
34---
35apiVersion: v1
36kind: Service
37metadata:
38 name: movie-catalogue-service
39spec:
40 selector:
41 app: movie-catalogue-service
42 ports:
43 - protocol: TCP
44 port: 80
45 targetPort: 8080
46 type: LoadBalancer
47---
Remember, before applying your Kubernetes YAML files, make sure your Kubernetes cluster has access to your ACR. You can configure this by granting AKS the ACRPull role on your ACR:
1az aks update -n <your-AKS-Cluster> -g <your-resource-group> --attach-acr <your-ACR>
Replace <your-AKS-Cluster>, <your-resource-group>, and <your-ACR> with your AKS cluster name, Azure resource group name, and ACR name, respectively.

Apply the YAML file

Apply the YAML file with kubectl:
1kubectl apply -f all-microservices.yaml

Access your services

Once deployed, it may take a few minutes for the LoadBalancer to be provisioned and for the external IP addresses to be assigned. You can check the status of your services with:
1kubectl get services
Look for the external IP addresses for your services and use them to access your microservices.
After deploying, ensure your services are running:
1kubectl get pods
Access your services based on the type of Kubernetes service you've defined (e.g., LoadBalancer in our case) and perform your tests.
You can test if the endpoint is running with the CURL command:
1curl -X POST http://<ReviewAPI-External-IP>/reviews \
2 -H "Content-Type: application/json" \
3 -d '{"movieId": "573a1391f29313caabcd68d0", "userId": "59b99db5cfa9a34dcd7885b8", "rating": 4}'
And this review should now appear in your database. You can check with a simple:
1curl -X GET http://<ReviewAPI-External-IP>/reviews
Hooray!

Conclusion

As we wrap up this tutorial, it's clear that embracing microservices architecture, especially when paired with the power of Kubernetes and Azure Kubernetes Service (AKS), can significantly enhance the scalability, maintainability, and deployment flexibility of applications. Through the practical deployment of a simple microservice application using Java Spring Boot on AKS, we've demonstrated the steps and considerations involved in bringing a microservice architecture to life in the cloud.
Key takeaways:
  • Modular approach: The transition from monolithic to microservices architecture facilitates a modular approach to application development, enabling independent development, deployment, and scaling of services.
  • Simplified Kubernetes deployment: AKS abstracts away much of the complexity involved in managing a Kubernetes cluster, offering a streamlined path to deploying microservices at scale.
  • Inter-service communication: Utilizing Kubernetes' internal DNS for service discovery simplifies the communication between services within a cluster, making microservice interactions more efficient and reliable.
  • Security and configuration best practices: The tutorial underscored the importance of using Kubernetes secrets for sensitive configurations and the Azure Container Registry for securely managing and deploying container images.
  • Exposing services externally: By setting services to type: LoadBalancer, we've seen how to expose microservices externally, allowing for easy access and integration with other applications and services.
The simplicity and robustness of Kubernetes, combined with the scalability of AKS and the modularity of microservices, equip developers with the tools necessary to build complex applications that are both resilient and adaptable. If you found this tutorial useful, find out more about what you can do with MongoDB and Azure on our Developer Center.
Are you ready to start building with Atlas on Azure? Get started for free today with MongoDB Atlas on Azure Marketplace.
Top Comments in Forums
There are no comments on this article yet.
Start the Conversation

Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Related
Article

Java Driver: Migrating From 4.11 to 5.0


Mar 01, 2024 | 3 min read
Tutorial

Getting Started With Azure Spring Apps and MongoDB Atlas: A Step-by-Step Guide


Jan 27, 2024 | 5 min read
Article

Using MongoDB Change Streams in Java


Aug 28, 2024 | 6 min read
Tutorial

Integrating MongoDB With Amazon Managed Streaming for Apache Kafka (MSK)


Sep 17, 2024 | 7 min read
Table of Contents