Spring Cloud Kubernetes – How To Make The Best Of Both Worlds

Spring Cloud Kubernetes Demo

In today’s fast-paced digital landscape, harnessing the potential of microservices architecture and container orchestration platforms like Kubernetes is a strategic imperative for modern application development. If you’re navigating the complex terrain of microservices and have chosen Kubernetes as your deployment platform, you’re on the right track. But what if you also want to leverage the rich features of Spring Cloud to supercharge your applications?

In this comprehensive guide, we’ll show you how to bridge the worlds of Spring Cloud and Kubernetes seamlessly. Spring Cloud Kubernetes serves as the conduit between these two powerful technologies, offering an array of benefits that enhance your microservices ecosystem. Whether you’re a seasoned developer or just dipping your toes into these technologies, our step-by-step tutorial will walk you through the process, from setting up a local Kubernetes environment to deploying microservices with ease.

Discover the best practices for service discovery, configuration management, load balancing, and resilience. Dive into Kubernetes-native services, explore configuration management using ConfigMaps and Secrets, and master the art of Ribbon Discovery. Along the way, we’ll provide practical code examples and insights to help you optimize your microservices for peak performance.

Join us on this journey as we demystify the integration of Spring Cloud and Kubernetes, empowering you to create scalable, resilient, and high-performance microservices applications. Whether you’re building the next-generation of web applications or optimizing your existing architecture, Spring Cloud Kubernetes offers the tools and techniques you need to thrive in the world of modern software development.

Let’s embark on this exciting journey to make the best of both worlds – Spring Cloud and Kubernetes.

1. Spring Cloud Kubernetes – Overview

In this guide, we will walk you through the process of consuming Kubernetes native services using the Spring Cloud common interface. Spring Cloud Kubernetes facilitates the integration of Spring Cloud and Spring Boot applications running on Kubernetes.

1.1. Why use Spring Cloud Kubernetes?

If we have already decided to use Kubernetes as our preferred container manager for our microservices but we are still interested in some features offered by Spring Cloud then Spring Cloud Kubernetes might be a good solution.

In fact, this project provides easier integration of these two popular container managers and deployment platforms.

2. Get Started

In this guide, we will build a Spring Cloud Kubernetes demo together to demonstrate how to handle:

  • Service Discovery
  • Configuration Management using ConfigMaps
  • Load Balancing with Ribbon

Specifically, in this demo we’ll first install Minikube to create a local Kubernetes environment.

Then we will develop a simple microservice scenario where we’ll have two individual Spring Boot applications communicating via REST.

  1. recipe-data-service: A service with access to a repository of recipes and related nutritional information.
  2. fitness-client-service: A service that needs updated information from the Recipe Data Service to provide fitness-related information.

Finally, we’ll be deploying the application a one-node cluster on Minikube.

3. Service Discovery with DiscoveryClient Implementation for Kubernetes

Each service will be exposed by Kubernetes into a collection of endpoints called pods. Internally, these pods can be accessed with a unique address that is invisible externally. In fact, the client will access the service as http://recipe-data-service:8080.

Furthermore, Spring Cloud Kubernetes Ribbon can be used to load balance between the different pods.

In order to use this feature we just need to add this in the Spring Boot application that needs to consume this service. In our case, we’ll add this to our fitness-client-service:

<dependency>
     <groupId>org.springframework.cloud</groupId> 
     <artifactId>spring-cloud-starter-kubernetes</artifactId> 
</dependency>Code language: YAML (yaml)

Additionally, the @EnableDisoveryClient annotation should be added on the application class

@SpringBootApplication
@EnableDiscoveryClient
public class Application {
  public static void main(String... args) {
    SpringApplication.run(Application.class, args);
  }
}Code language: Java (java)

Then, you get hold of the DiscoveryClient in your desired class by adding @Autowired to the property as follows:

@Autowired
private DiscoveryClient discoveryClient;Code language: Java (java)

4. Kubernetes Native Service Discovery

Kubernetes offers its own native discovery service on the server-side ensuring compatibility with other tools such as IstioIstio is a service mainly used for load balancing, ribbon, circuit breaking, and failover capabilities.

Additionally, Netflix Hystrix framework library can also be used for circuit breaking and failover functionality. Similar to Istio it also helps to build more resilient applications using fail-fast techniques.

Let’s use Hystrix in our recipe-data-service to specify exactly how to deal quickly with a fallback. Through the @HystrixCommand annotation we can easily specify the fallback method to be used to recover quickly.

@HystrixCommand(fallbackMethod = "getFallbackName", commandProperties = { 
    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1250") })
public String getRecipes() {
    return this.restTemplate.getForObject("http://recipe-data-servie:8080/recipes", String.class);
}
 
private String getFallbackName() {
    return "Fallback";
}Code language: Java (java)

5. Kubernetes PropertySource Implementations

Let’s discuss ways of how to manage configurations using Spring Cloud Kubernetes project.

The two distinct ways are ConfigMap and Secret, where the former is advisable for unencrypted information while Secret as the name implies is meant for more sensitive encrypted information.

5.1. ConfigMap

ConfigMap is a resource provided by Kubernetes for configuration management typically required by microservices. By using an application.yaml (or application.properties) we can externalize the parameters to pass to our application.

Let’s say we need a configurable property for our fitness-client-service, what we do is create a configuration class using Spring annotations @Configuration and @ConfigurationProperties.

@Configuration
@ConfigurationProperties(prefix = "bean")
public class FitnessClientConfig {
 
    private String message = "Message from fitness-client-service: %s <br/> Services : %s";
 
    // getters and setters
}Code language: Java (java)

For example, we can create a ConfigMap for our fitness-client-service using this fitness-client-config.yaml file

apiVersion: v1
kind: ConfigMap
metadata:
  name: fitness-client-service
data:
  application.properties: |-
    bean.message=Message from fitness-client-service: %s <br/> Services : %sCode language: YAML (yaml)

To create the ConfigMap on Kubernetes we need to execute the following command:

kubectl create -f fitness-client-config.yamlCode language: Shell Session (shell)

If you need to edit the ConfigMap, this can be done through the kubectl edit command as follows:

kubectl edit configmap fitness-client-serviceCode language: Shell Session (shell)

The configuration in ConfigMap instances is updated through Spring Cloud Kubernetes during bootstrapping and reloading of the Spring Context. Noteworthy, the name of the ConfigMap should match exactly that of the application name e.g. fitness-client-service.

5.2. Secrets

As already mentioned, these are more suitable for more sensitive information such as passwords or database information.

For example, let’s create a Secret db-credentials-secret.yaml for our recipe-data-service holding database username and password.

apiVersion: v1
kind: Secret
metadata:
  name: db-credentials-secret
data:
  username: dXNlcg==
  password: cDQ1NXcwcmQ=Code language: YAML (yaml)

To create the Secret on the recipe-data-service Kubernetes’ cluster we need to execute the following command:

kubectl apply -f db-credentials-secret.yamlCode language: Shell Session (shell)

6. Ribbon Discovery in Kubernetes

As already hinted, Spring Cloud Kubernetes Ribbon uses a mechanism by which it discovers all the pods/endpoints which expose a specific service. Subsequently, it populates what is called a Ribbon ServerList with endpoint related information and also takes care of load-balancing between the various endpoints.

Adding RibbonClient is very simple. We need to:

  • add the pom dependency in our fitness-client-service,
  • add @RibbonClient annotation from the class where we need to use a reference of the RibbonClient,
  • Enable the ribbon client in the application properties
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId>
</dependency>Code language: YAML (yaml)

In the service layer of fitness-client-service, add the reference for RibbonClient to gather all the info on the recipe-data-service endpoints.

@RibbonClient(name = "recipe-data-service")Code language: Java (java)

Finally, add this in applications.yaml property file, so that you enable the ribbon client.

ribbon.http.client.enabled=trueCode language: YAML (yaml)

7. Environment Setup

As part of our setup for this Spring Cloud Kubernetes Demo we’re using Minikube.

7.1. Minikube Setup

I suggest starting by installing VirtualBox on your machine or your preferred VM driver. Then, it’s the turn of installing Minikube from the Kubernetes site.

7.1.1. Starting a Single Node Kubernetes Cluster

minikube start --vm-driver=virtualbox

kubectl config use-context minikubeCode language: Shell Session (shell)

This command will restart the existing virtualbox VM cluster for Minikube or create a new one if it doesn’t exist. Then we switch to the Minikube cluster using the kubectl config use-context command.

7.1.2. Connecting to Kubernetes Dashboard

minikube dashboardCode language: Shell Session (shell)

By connecting to the Minikube dashboard, we’ll be able to access log files, services, and pods. Additionally, if configured we can also access ConfigMaps and/or Secrets.

7.2. Deployment

In order to build the services on the remote on Minikube’s cluster docker environment execute the following script:

### build the repository
mvn clean install
 
### set docker env
eval $(minikube docker-env)
 
### build the docker images on minikube
cd recipe-data-service
docker build -t recipe-data-service .
cd ../fitness-client-service
docker build -t fitness-client-service .
cd ..
 
### secret
kubectl delete -f recipe-data-service/secret.yaml 
kubectl create -f recipe-data-service/secret.yaml
 
### recipe-data-service
kubectl delete -f recipe-data-service/recipe-data-deployment.yaml
kubectl create -f recipe-data-service/recipe-data-deployment.yaml
 
### fitness-client-service
kubectl delete configmap fitness-client-service
kubectl delete -f fitness-client-service/fitness-client-deployment.yaml
 
kubectl create -f fitness-client-service/fitness-client-config.yaml
kubectl create -f fitness-client-service/fitness-client-deployment.yaml
 
# Check that the pods are running
kubectl get podsCode language: YAML (yaml)

8. Conclusion

This is a simple guide for Spring Cloud Kubernetes demo. By now you will have an idea whether you are interested in trying this out for your microservices architecture. Actually, this is an excellent solution for people who have already chosen to use Kubernetes as their microservices deployment solution but still root for Spring Cloud features.

Let me know if you have any problems or queries at [email protected] or send a message to the Facebook Page

Scroll to Top