Spring Boot Admin on Kubernetes
The main goal of this article is to show how to monitor Spring Boot applications running on Kubernetes with Spring Boot Admin. I have already written about Spring Boot Admin more than two years ago in the article Monitoring Microservices With Spring Boot Admin. You can find there a detailed description of its main features. During this time some new features have been added. They have also changed the look of the application to more modern. But the principles of working have not been changes anymore, so you can still refer to my previous article to understand the main concept around Spring Boot Admin.
I was pretty surprised that there is no comprehensive article about running Spring Boot Admin on Kubernetes online. That’s why I decided to build this tutorial. Today I’m going to show you how to use Spring Cloud Kubernetes with Spring Boot Admin to enable monitoring for all Spring Boot applications running across the whole cluster. That’s a challenging task, but fortunately it is not very hard with Spring Cloud Kubernetes.
Example
As usual the source code with sample applications is available on GitHub in the repository https://github.com/piomin/sample-spring-microservices-kubernetes.git. It was used as the example for some other articles on my blog, which may be helpful to better understand the idea behind Spring Cloud Kubernetes. One of them is Microservices with Spring Cloud Kubernetes.
Anyway, I’m using three sample Spring Boot applications from this repository for a demo purpose. Each application would be run in a different namespace inside Minikube. Spring Boot Admin should monitor only Spring Boot applications, with the assumptions that there are different types of applications and solutions running on Kubernetes. All the three applications are optimized to be built with Skaffold and Jib. So the only thing you have to do is to run command skaffold dev
in the directory of each application.
The picture illustrating an architecture of applications for the current article is visible below. The application employee-service is deployed inside namespace a
, department-service is deployed inside namespace b
, while organization-service is deployed inside namespace c
. Spring Boot Admin is also started using Spring Boot and is deployed in the namespace default
.
Dependencies
Let’s begin from dependencies. Spring Boot Admin Server is available as a starter library. The current stable version is 2.2.2
. We also need to include Spring Boot Web starter. Because our Spring Boot Admin application is integrating with Kubernetes discovery we should include Spring Cloud Kubernetes Discovery. If you also use Spring Cloud Kubernetes for direct integration with ConfigMap
and Secret
you may just include spring-cloud-starter-kubernetes-all
starter instead of starter dedicated only for discovery. Here’s the list of dependencies inside our sample module admin-server with embedded Spring Boot Admin.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-all</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Spring Boot Admin Server and Kubernetes discovery
We need to add some annotations to the Spring Boot main class to enable Spring Boot Admin with Kubernetes Discovery. First of them is of course @EnableAdminServer
(1). With Spring Cloud Kubernetes we still need to add annotation @EnableDiscoveryClient
to enable DiscoveryClient
based on Kubernetes API (2). The last annotation @EnableScheduling
is not so obvious, but also required (3). Without it a discovery client won’t periodically call Kubernetes API to refresh the list of running services, and do it only once on startup. Since, we always want to have the current list of pods (for example after scaling up the number of application instances), we need to enable a scheduler responsible for watching service catalog for changes and updating the DiscoveryClient
implementation accordingly.
@SpringBootApplication
@EnableAdminServer // (1)
@EnableDiscoveryClient // (2)
@EnableScheduling // (3)
public class AdminApplication {
public static void main(String[] args) {
SpringApplication.run(AdminApplication.class, args);
}
}
Now, a crucial issue throughout the game – configuration. Those two properties visible below do the whole “magic”. First of them spring.cloud.kubernetes.discovery.all-namespace
enables DiscoveryClient
from all namespaces (1). After enabling it Spring Boot Admin would be able to monitor all the applications across the whole cluster! Great, but since we would like to force it to monitor just the Spring Boot application, we need to be able to filter them. Here comes Spring Cloud Kubernetes with another smart solution. The property spring.cloud.kubernetes.discovery.serviceLabels
allows us to define the set of labels used for filtering list of services fetched from Kubernetes API. In simple words, we fetch only those Kubernetes Service
, that has labels defined on the Spring Boot Admin server side with such values. Here’s application.yml
for admin-service defined inside ConfigMap
.
kind: ConfigMap
apiVersion: v1
metadata:
name: admin
data:
application.yml: |-
spring:
cloud:
kubernetes:
discovery:
all-namespaces: true # (1)
service-labels:
spring-boot: true # (2)
Implementation on the client side
Thanks to using DiscoveryClient
on Spring Boot Admin Server we don’t have to include any additional Spring Boot Admin Client library to our sample applications. Of course, they also don’t have to include Spring Cloud Kubernetes, since Kubernetes manages pods registration by itself. In fact, the only thing we have to do is to add label to the Kubernetes Service
, which has been set as a filtering condition on the server side. Here’s the example of Service
definition for department-service.
apiVersion: v1
kind: Service
metadata:
name: department
labels:
app: department
spring-boot: "true"
spec:
ports:
- port: 8080
protocol: TCP
selector:
app: department
Spring Boot Admin is based on Spring Boot Actuator endpoints, so each application should at least include that project to Maven dependencies.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
By default, not all the endpoints are exposed outside application. Therefore we need to expose them by setting property management.endpoints.web.exposure.include
to *
. It is also worth showing details about application in health
endpoint. That step is optional. Here’s our application.yml
for department-service.
spring:
application:
name: department
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: ALWAYS
It’s also worth generating a build-info.properties
file during build to provide more details for Actuator /info
endpoint.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
Running Spring Boot Admin on Kubernetes
First, we should start Minikube. Because we are running applications and MongoDB I suggest changing the default memory limit 4 GB.
$ minikube start --vm-driver=virtualbox --memory='4000mb'
Let’s start from creating all the required namespaces on Minikube. Except default
namespace, we also need namespaces a
, b
, and c
, as it has been described in the section Example.
$ kubectl create namespace a
namespace/a created
$ kubectl create namespace b
namespace/b created
$ kubectl create namespace c
namespace/c created
Spring Boot Admin uses Spring Cloud Kubernetes, which requires extra privileges in order to access Kubernetes API. Let’s set cluster-admin
as a default role for ServiceAccount
just for a development purpose.
$ kubectl create clusterrolebinding admin-default --clusterrole=cluster-admin --serviceaccount=default:default
Assuming we have already succesfully deploy all the sample microservices and Spring Boot Admin Server application on Minikube you will get the following list of Services
for all the namespaces. Option -L=spring-boot
prints value of label spring-boot
for all services.
We may also take a look into the list of pods. I have set two instances for employee
deployment.
As you can see on the picture below Spring Boot Admin manages only Kubernetes Services
labeled with spring-boot=true
. For example mongodb
, kubernetes
or admin
inside default
namespace were omitted.
Spring Boot Admin provides some useful features for managing Spring Boot applications. It is worth considering using it on Kubernetes to monitor the whole set of your microservices distributed across many namespaces. The following picture illustrates the details page for a single application (pod) running on Minikube.
13 COMMENTS