Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea
3 changes: 2 additions & 1 deletion kubernetes-fabric8/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Spring Boot Admin - Kubernetes Example

Allows to run Spring Boot Admin and one sample app (hello world) in kubernetes. Will guide you through all setup steps for the infrastructure.
Allows to run Spring Boot Admin and two sample apps (hello world, health simulator) in kubernetes. Will guide you through all setup steps for the infrastructure.

## Enable Kubernetes in Docker Desktop

Expand Down Expand Up @@ -36,6 +36,7 @@ Allows to run Spring Boot Admin and one sample app (hello world) in kubernetes.

- [./hello-world/README.md](./hello-world/README.md)
- [./spring-boot-admin/README.md](./spring-boot-admin/README.md)
- [./health-simulator/README.md](./health-simulator/README.md)

## Uninstall Apps

Expand Down
5 changes: 5 additions & 0 deletions kubernetes-fabric8/health-simulator/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
target
.idea
*.iml
*.log
*.gz
8 changes: 8 additions & 0 deletions kubernetes-fabric8/health-simulator/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# https://hub.docker.com/_/eclipse-temurin/
FROM eclipse-temurin:17

VOLUME /tmp

COPY target/app.jar /opt/app/app.jar

CMD ["bash", "-c", "java $JAVA_OPTS -jar /opt/app/app.jar"]
54 changes: 54 additions & 0 deletions kubernetes-fabric8/health-simulator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Health Simulator

App to simulate changes in health status. Spring Boot Admin reports these in the UI and with browser notifications (if you allow browser notifications).

You can change the number of replicas in [deployment/values.yaml](deployment/values.yaml). Note that calls to http://localhost/health-simulator will reach a random pod if the number of replicas is greater than 0. Calls to http://localhost/health-simulator/up ... change the status of a random pod.

## Build App

mvn clean install

## Build Docker Image

docker build --tag health-simulator .

## Install App

helm install health-simulator deployment

### Check deployment

kubectl get pods -o wide
kubectl get services -o wide
kubectl get ingress

### Uninstall

helm uninstall health-simulator

## Build & Install Script

chmod u+x buildAndInstall.sh
./buildAndInstall.sh

## URI

### Simulated health status

- http://localhost/health-simulator

### Change the health status

- http://localhost/health-simulator/up
- http://localhost/health-simulator/down
- http://localhost/health-simulator/unknown
- http://localhost/health-simulator/out_of_service

## Access Actuator

kubectl get pods
kubectl port-forward <pod-name> 8081:8081

### URI

- http://localhost:8081/actuator
10 changes: 10 additions & 0 deletions kubernetes-fabric8/health-simulator/buildAndInstall.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh

# Uninstall App
helm uninstall health-simulator
# Build App
mvn clean install
# Build Docker Image
docker build --tag health-simulator .
# Install App
helm install health-simulator deployment
4 changes: 4 additions & 0 deletions kubernetes-fabric8/health-simulator/deployment/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
apiVersion: v1
description: A Helm chart for Spring Boot services
name: spring-boot-service
version: 0.0.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.name }}
namespace: {{ .Values.namespace }}
labels:
app: {{ .Values.name }}
spec:
replicas: {{ .Values.deployment.replicas }}
strategy:
type: {{ .Values.deployment.updateStrategy }}
rollingUpdate:
maxUnavailable: {{ .Values.deployment.maxUnavailable }}
maxSurge: {{ .Values.deployment.maxSurge }}
selector:
matchLabels:
app: {{ .Values.name }}
template:
metadata:
labels:
app: {{ .Values.name }}
spec:
restartPolicy: {{ .Values.deployment.restartPolicy }}
containers:
- name: {{ .Values.name }}
image: {{ .Values.deployment.image }}
imagePullPolicy: {{ .Values.deployment.pullPolicy }}
{{- with .Values.deployment.env }}
env:
{{- range $env_var, $key := . }}
- name: {{ $env_var }}
value: "{{ $key }}"
{{- end }}
{{- end }}
ports:
- containerPort: 8080
name: http
protocol: TCP
- containerPort: 8081
name: management
protocol: TCP
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8081
initialDelaySeconds: {{ .Values.deployment.livenessProbe.initialDelaySeconds }}
timeoutSeconds: {{ .Values.deployment.livenessProbe.timeoutSeconds }}
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8081
initialDelaySeconds: {{ .Values.deployment.readinessProbe.initialDelaySeconds }}
timeoutSeconds: {{ .Values.deployment.readinessProbe.timeoutSeconds }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Values.name }}
namespace: {{ .Values.namespace }}
spec:
rules:
- http:
paths:
- path: /{{ .Values.name }}
pathType: Prefix
backend:
service:
name: {{ .Values.name }}
port:
name: http
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.name }}
namespace: {{ .Values.namespace }}
labels:
app: {{ .Values.name }}
# Filter discovery to tagged services
annotations:
spring-boot-admin: "true"
spec:
ports:
- port: 8080
targetPort: http
protocol: TCP
# Name must be http or https
# Alternative: configure spring.cloud.kubernetes.discovery.primary-port-name
name: http
- port: 8081
targetPort: management
protocol: TCP
name: management
selector:
app: {{ .Values.name }}
20 changes: 20 additions & 0 deletions kubernetes-fabric8/health-simulator/deployment/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: health-simulator
namespace: default

deployment:
env:
SERVER_SERVLET_CONTEXT_PATH: /health-simulator
image: health-simulator
# not recommended for production
pullPolicy: Never
updateStrategy: RollingUpdate
maxSurge: 100%
maxUnavailable: 0%
replicas: 1
restartPolicy: Always
livenessProbe:
initialDelaySeconds: 10
timeoutSeconds: 10
readinessProbe:
initialDelaySeconds: 10
timeoutSeconds: 10
8 changes: 8 additions & 0 deletions kubernetes-fabric8/health-simulator/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: "3.7"

services:
health-simulator:
image: health-simulator:latest
ports:
- 8080:8080
- 8081:8081
73 changes: 73 additions & 0 deletions kubernetes-fabric8/health-simulator/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.6</version>
</parent>

<groupId>de.codecentric</groupId>
<artifactId>health-simulator</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<version>1.0.0-SNAPSHOT</version>
<description>Simulate Health Checks</description>

<properties>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<!-- Supporting -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>

<build>
<finalName>app</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
<!-- Build-Infos for Info-Actuator -->
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- GIT-Infos for Info-Actuator -->
<plugin>
<groupId>io.github.git-commit-id</groupId>
<artifactId>git-commit-id-maven-plugin</artifactId>
<configuration>
<offline>true</offline>
</configuration>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package de.codecentric.healthsimulator;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SimulateHealthApplication {

public static void main(String... args) {
SpringApplication.run(SimulateHealthApplication.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package de.codecentric.healthsimulator.health;

import lombok.RequiredArgsConstructor;
import org.springframework.boot.actuate.health.Status;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class HealthController {

private final HealthIndicatorSimulation healthIndicatorSimulation;

@GetMapping("/")
public Status status() {
return healthIndicatorSimulation.getStatus();
}

@GetMapping("/up")
public Status up() {
healthIndicatorSimulation.setStatus(Status.UP);
return healthIndicatorSimulation.getStatus();
}

@GetMapping("/down")
public Status down() {
healthIndicatorSimulation.setStatus(Status.DOWN);
return healthIndicatorSimulation.getStatus();
}

@GetMapping("/unknown")
public Status unknown() {
healthIndicatorSimulation.setStatus(Status.UNKNOWN);
return healthIndicatorSimulation.getStatus();
}

@GetMapping("/out_of_service")
public Status outOfService() {
healthIndicatorSimulation.setStatus(Status.OUT_OF_SERVICE);
return healthIndicatorSimulation.getStatus();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package de.codecentric.healthsimulator.health;

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.Status;
import org.springframework.stereotype.Component;

@Component
@Getter
@Setter
public class HealthIndicatorSimulation implements HealthIndicator {

private Status status = Status.UP;

@Override
public Health health() {
return Health.status(status).withDetail("Simulated", "health status").build();
}
}
Loading