Cloud Native 14 min read

Deploying Spring Boot Applications with Spring Boot Operator on Kubernetes

This guide explains how to package a Spring Boot project into a Docker image using Jib, install the Spring Boot Operator on a Kubernetes cluster, and manage applications through custom resources, including deployment, scaling, graceful shutdown, node affinity, and custom operator configuration.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
Deploying Spring Boot Applications with Spring Boot Operator on Kubernetes

Deploying a Spring Boot application on Kubernetes can be complex, but the Spring Boot Operator simplifies the process by extending the Kubernetes API with custom resource definitions (CRDs).

Package Docker Image – Use the Google Jib Maven plugin to build and push a Docker image directly from the project without a Dockerfile:

mvn com.google.cloud.tools:jib-maven-plugin:build \
  -Djib.to.auth.username=${{ secrets.MY_USERNAME }} \
  -Djib.to.auth.password=${{ secrets.MY_PASSWORD }} \
  -Djib.container.jvmFlags=--add-opens=java.base/sun.nio.ch=ALL-UNNAMED \
  -Djib.from.image=freemanliu/oprenjre:11.0.5 \
  -Dimage=registry.cn-shanghai.aliyuncs.com/qingmuio/operator-demo/operator-demo:v1.0.0

After the command finishes, the image is pushed to the remote registry.

Install the Operator – Apply the operator manifests to the cluster (a ready Kubernetes cluster is required):

kubectl apply -f https://raw.githubusercontent.com/goudai/spring-boot-operator/master/manifests/deployment.yaml

The console shows the creation of the namespace, CRD, roles, and the operator deployment.

Deploy the Demo Application – Create a CRD yaml (Demo.yaml) that describes the Spring Boot application and apply it:

# Demo.yaml
apiVersion: springboot.qingmu.io/v1alpha1
kind: SpringBootApplication
metadata:
  name: operator-demo
spec:
  springBoot:
    version: v1.0.0
    # image: registry.cn-shanghai.aliyuncs.com/qingmuio/operator-demo/operator-demo:v1.0.0
kubectl apply -f Demo.yaml

Verify the pod is running and the service is exposed:

kubectl get po -n spring-boot-operator-system
kubectl get svc | grep operator-demo

Test the endpoint:

curl -i http://10.101.128.6:8080

Scale the Application – Edit Demo.yaml to add a replicas: 1 field and re‑apply:

spec:
  springBoot:
    version: v1.0.0
    replicas: 1
kubectl apply -f Demo.yaml

Check that only one pod remains.

Cleanup – Delete the demo resources:

kubectl delete -f Demo.yaml

Deploy Your Own Application – Create a Docker‑registry secret if needed, then write a full CRD yaml that includes image, replicas, resource limits, health paths, and optional imagePullSecrets:

apiVersion: springboot.qingmu.io/v1alpha1
kind: SpringBootApplication
metadata:
  name: my-app
spec:
  springBoot:
    version: v1.0.0
    image: registry.cn-shanghai.aliyuncs.com/qingmuio/my-app:v1.0.0
    replicas: 2
    resource:
      cpu:
        request: 50m
      memory:
        request: 1Gi
    liveness: /actuator/health
    readiness: /actuator/health
    shutdown: /spring/shutdown
    imagePullSecrets:
      - aliyun-registry-secret
kubectl apply -f MyApp.yaml

Graceful Shutdown – Enable the shutdown endpoint in application.yml and expose it via a controller:

management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    shutdown:
      enabled: true
@RestController
public class ShutdownController {
    @Autowired
    private ShutdownEndpoint shutdownEndpoint;

    @GetMapping("/spring/shutdown")
    public Map
shutdown(HttpServletRequest request) {
        return shutdownEndpoint.shutdown();
    }
}

Node Affinity – Label nodes with zones (e.g., cn‑i, cn‑h, cn‑g) and set affinity in the CRD to distribute pods across zones:

kubectl label node node-i1 failure-domain.beta.kubernetes.io/zone=cn-i
kubectl label node node-i2 failure-domain.beta.kubernetes.io/zone=cn-i
# repeat for other zones
spec:
  springBoot:
    nodeAffinity:
      key: "failure-domain.beta.kubernetes.io/zone"
      operator: "In"
      values:
        - "cn-i"
        - "cn-h"
        - "cn-g"

Custom Operator Installation – Modify the operator deployment yaml to inject environment variables that control image repository, CPU/memory requests, health check paths, replica count, log paths, and global Spring Boot environment variables. Example fragment:

- name: IMAGE_REPOSITORY
  value: registry.cn-shanghai.aliyuncs.com/qingmuio
- name: REQUEST_CPU
  value: 50m
- name: REQUEST_MEMORY
  value: 500Mi
- name: READINESS_PATH
  value: /actuator/health
- name: SHUTDOWN_PATH
  value: /spring/shutdown
- name: REPLICAS
  value: "3"
- name: SPRING_BOOT_ENV
  value: "EUREKA_SERVERS=http://eureka1:8761/eureka/,http://eureka2:8761/eureka/"

After editing, apply the deployment to update the operator.

For more details, refer to the GitHub repository SpringBootOperator .

DockerdeploymentkubernetesOperatorSpring BootYAMLJib
Java Architect Essentials
Written by

Java Architect Essentials

Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.