Managing Spring Boot Microservices with Spring Boot Admin on Kubernetes

by Christophe BouhierDecember 6, 2018

In this blog:

  • Prerequisites
  • Introduction
  • The top cool features we like and use most
    • The service journal
    • Overall View, what is deployed
    • Change LOG levels
    • DB migrations
  • Creating an SBA Application
    • Dependency configuration
    • Spring Boot Admin
    • Spring Boot Application
    • Configuration of the Admin Application
    • Summing up
  • Running SBA on K8s
  • Conclusion
  • References

Prerequisites

Knowledge of:

  • Spring Boot and Spring Boot actuator is required. To get started easily with Spring Boot consider, the Spring Boot initializer. [1]
  • Kubernetes knowledge is required to actually deploy Spring Boot Admin and a sample microservice to Kubernetes.

Note that, this blog will not lead the reader step by step on how it’s done exactly, but provides background information and important settings to make it happen.

Introduction

Here at Trifork we love Spring Boot. We use the framework for microservices, and deploy the services on i.e. Kubernetes (K8s). For a client, in a recent project, we have been building a system which is fully deployed on K8s with various Spring Boot services.

The spring boot services, are easily managed with Spring Boot Admin (SBA) [2], from the good folks at codecentric.

SBA is convenient to manage a Spring Boot Application, it reads the actuator endpoints to visualize de state of a Spring Boot Application as well as managing the state or configuration.

The top cool features we like and use most

1. The service journal

In K8s, pods come and go. The SBA journal tells you when a pod is registered, when they are online,  when they are offline including many notification possibilities like browser, email and chat.  

2. Overall View, what is deployed

Microservices are deployed on an as-needed basis. However, the release of a specific microservice, should refer to a Git commit hash. In our case, we use a reference to the CI/CD build, which in its turn points to the Git commit hash.

* On top the K8s instance ID, below at info the CI/CD build reference.

3. Change LOG levels

Imagine you are in a situation where additional log details are required for a certain package. Simply enter the package name, and your logs will spit the corresponding log entries.

4. DB migrations

This feature is super cool, we want to see which flyway DB migrations have been running, just check the ‘Flyway’ tab.

Other useful features:

  • View the Environment vars
  • Manage your JMX resources
  • View the metrics.

Further on, in this blog we will show how SBA can be configured to discover the Spring Boot microservices deployed on Kubernetes.

Creating an SBA Application

In our case SBA is just another Spring Boot microservice, which gets deployed alongside the ‘regular’ application services. It requires a Spring Boot Application class, some dependencies and configuration.

Dependency configuration

Let’s start with the dependencies in gradle format.

dependencies {
    compile libraries.springBoot
    compile libraries.springBootAdmin
    compile libraries.springCloudK8s
}

We will elaborate on each of these, minding these dependency versions:

ext {
    jolokiaVersion = '1.6.0'
    springBootAdminVersion = '2.0.1'
    springCloudK8s = '0.3.0.RELEASE'
}

Spring Boot Admin:

The actual dependency on SBA Starter

springBootAdmin : [
       'de.codecentric:spring-boot-admin-starter-server'
],

Spring Boot:

We need the spring boot starter obviously and as Spring Boot Admin, is working with Spring Boot Actuator, we will need that as well. The Jolokia dependency is required to interact with JMX through a Rest API.

springBoot : [
    'org.springframework.boot:spring-boot-starter-web',
    'org.springframework.boot:spring-boot-starter-actuator',
    "org.jolokia:jolokia-core:$jolokiaVersion"
],

Spring Cloud K8s:

This is the Spring Cloud integration with K8s [3], Note that this library can do more than discovery like reading K8s config maps and secrets.

springCloudK8s : [
    'org.springframework.cloud:spring-cloud-starter',
    "org.springframework.cloud:spring-cloud-starter-kubernetes:$springCloudK8s"
],

Spring Boot Application

@SpringBootApplication
@EnableAdminServer
@EnableDiscoveryClient
@EnableScheduling
@Configuration
public class AdminApplication {
    public static void main(String[] args) {
        SpringApplication.run(AdminApplication.class, args);
    }
}

That’s it, with a lot of magic, we get this application to do what we want, let’s go through the ‘Enable’ annotations.

@EnableAdminServer

This is an annotation from SBA itself to tell spring to configure this

@EnableDiscoveryClient

This is required, so SBA can discover services from a Spring Cloud Discovery implementation. As we have a dependency on Spring Cloud Kubernetes, we expect the microservices deployed as ‘service’ in K8s to be discovered.

@EnableScheduling

Now this one is interesting, and unfortunately not documented. In order for Spring Cloud k8s, to check the status of a service on regular basis, the implementation schedules a task to do so. Failing to provide this annotation, will cause the service status not to be updated in SBA. (Although the services running will be discovered, when SBA is launched. This requirement was only he found out, after going through the code, and noticing a @Scheduled annotation in the Spring Cloud K8s code.

Configuration of the Admin Application

Some configuration is required, as Spring Boot Autoconfiguration doesn’t do exactly what is needed we feel.

application.yml

spring:
 application:
   name: admin
 boot:
   admin:
     context-path: /admin (1)
     discovery:
       converter:
         management-context-path: manage (2)
       ignored-services: a, b, c (3)
   kubernetes:
     discovery:
       enabled: true (4)
       catalog-services-watch:
         enabled: true (5)
         catalogServicesWatchDelay: 10000 (6)
  1. Expose SBA UI on /admin path
  2. Manage actuator endpoints from context path /manage. (This is the context path configured on the managed Spring Boot Microservices.
  3. Ignore these services (Because they are not Spring Boot).
  4. Enable on Spring Cloud K8s discovery.
  5. Now this is important, make sure we ask K8s about the state of our instances every…
  6. … 10 seconds.

Summing up

By now the Spring Boot Application, running SBA, should have the basic Spring Boot structure, with an AdminApplication class, an application.yml in the resources folder and a build.gradle with required dependencies. Next, let’s take this baby for a spin.

Running SBA on K8s

Now that we have a Spring Boot Admin Application, we are ready to run it. One of the requirements is that it needs to run in K8s or have permission to interact with a Kubernetes Cluster.

The Spring Cloud K8s implementation will use the Fabric8 Kubernetes Client, this client by default, will request the current K8s context and try to connect to it.

An easy way to test the application on a local machine is to run Docker with K8s locally, set that as the current K8s context and run the Spring Admin Application. In this way, deployed Spring Boot services* on the K8s cluster will be discovered and visible on Spring Boot Admin.

* Deploying Spring Boot Services on the local K8s cluster, is beyond the goal of this blog. Please refer to some good resources [4,5] to deploy your Spring Boot Microservices to K8s.

Conclusion

With Spring Boot Admin, we have a useful way to manage, deployed Spring Boot Applications. When these run on Kubernetes, we can leverage the Spring Cloud K8s project to discover deployed instances.

References

[1] Spring Boot Initializr https://start.spring.io/

[2] Spring Boot Admin: https://github.com/codecentric/spring-boot-admin

[3] Spring Cloud Kubernetes: https://github.com/spring-cloud/spring-cloud-kubernetes

[4] Get started with Kubernetes on Docker https://medium.com/coryodaniel/newbernetes-getting-started-b1991e42900c

[5] Spring Boot on Kubernetes https://itnext.io/migrating-a-spring-boot-service-to-kubernetes-in-5-steps-7c1702da81b6

More information from Trifork: