How to launch Spring, Quarkus, and microservices on top of Kubernetes?

How to launch Spring, Quarkus, and microservices on top of Kubernetes?

To launch a microservices architecture with Spring Boot, Quarkus, and other microservices on top of Kubernetes, you'll need to prepare containerized versions of your microservices and orchestrate them using Kubernetes. The following steps outline how to achieve this, focusing on deploying Spring Boot, Quarkus, and any other microservices, with each having its own service, deployment, and possibly database dependencies.

1. Containerizing Applications

a. Spring Boot Microservice Dockerfile

FROM openjdk:17-jdk-alpine
VOLUME /tmp
COPY target/spring-boot-app.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

b. Quarkus Microservice Dockerfile

FROM registry.access.redhat.com/ubi8/openjdk-17:1.14
COPY target/quarkus-app/lib/ /deployments/lib/
COPY target/quarkus-app/*.jar /deployments/
COPY target/quarkus-app/app/ /deployments/app/
COPY target/quarkus-app/quarkus/ /deployments/quarkus/
ENTRYPOINT [ "java", "-jar", "/deployments/quarkus-run.jar" ]

2. Build the Docker Images

To containerize the microservices, build Docker images for both Spring Boot and Quarkus apps.

For Spring Boot:

mvn clean package
docker build -t your-repo/spring-boot-app .

For Quarkus:

./mvnw package -Dquarkus.container-image.build=true
docker build -t your-repo/quarkus-app .

Push these images to your Docker registry (DockerHub, ECR, or GCR).

docker push your-repo/spring-boot-app
docker push your-repo/quarkus-app

3. Kubernetes YAML Files

To deploy these microservices on Kubernetes, you need YAML files for Deployments and Services.

a. Spring Boot Kubernetes Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-boot-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: spring-boot-app
  template:
    metadata:
      labels:
        app: spring-boot-app
    spec:
      containers:
      - name: spring-boot-app
        image: your-repo/spring-boot-app
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: spring-boot-service
spec:
  selector:
    app: spring-boot-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: LoadBalancer

b. Quarkus Kubernetes Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: quarkus-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: quarkus-app
  template:
    metadata:
      labels:
        app: quarkus-app
    spec:
      containers:
      - name: quarkus-app
        image: your-repo/quarkus-app
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: quarkus-service
spec:
  selector:
    app: quarkus-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: LoadBalancer

c. Database Deployment (if needed)

If any microservice requires a database, for instance, MySQL or PostgreSQL, create a database deployment as well.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: db-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: db-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: db
  template:
    metadata:
      labels:
        app: db
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: password
        - name: MYSQL_DATABASE
          value: microservice_db
        ports:
        - containerPort: 3306
        volumeMounts:
        - name: db-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: db-storage
        persistentVolumeClaim:
          claimName: db-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: db-service
spec:
  ports:
    - port: 3306
  selector:
    app: db

4. Configuring Kubernetes Ingress (Optional)

You can set up Ingress to expose your services externally under different URLs, making it easier to route traffic to specific microservices.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: microservices-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: your-app-domain.com
    http:
      paths:
      - path: /spring
        pathType: Prefix
        backend:
          service:
            name: spring-boot-service
            port:
              number: 80
      - path: /quarkus
        pathType: Prefix
        backend:
          service:
            name: quarkus-service
            port:
              number: 80

5. Apply the Kubernetes YAML Files

Now that you have all your YAML files ready, apply them to your Kubernetes cluster.

kubectl apply -f spring-boot.yaml
kubectl apply -f quarkus.yaml
kubectl apply -f database.yaml  # If needed
kubectl apply -f ingress.yaml   # If using Ingress

6. Verifying the Setup

Check if all deployments are running properly by running:

kubectl get pods
kubectl get svc
  • The LoadBalancer or Ingress service will give you an external IP to access the services.

  • You can scale up or down your microservices using Kubernetes' kubectl scale command.

7. Inter-service Communication

For communication between services, Kubernetes allows services to be accessible by their DNS names (service-name.namespace.svc.cluster.local). You can configure Spring Boot, Quarkus, or any other microservice to communicate using the service name defined in Kubernetes YAML.

For example:

  • Spring Boot microservice calls Quarkus:

      http://quarkus-service:8080/api/endpoint
    
  • Quarkus microservice calls Spring Boot:

      http://spring-boot-service:8080/api/endpoint
    

8. Monitoring & Logging

Once deployed, you can monitor and debug the services using tools like Prometheus, Grafana, or logging solutions like ELK Stack (Elasticsearch, Logstash, Kibana) or Loki.

For simple logs:

kubectl logs <pod-name>

Summary

By following these steps, you can deploy and run Spring Boot, Quarkus, and other microservices on top of Kubernetes. Kubernetes allows you to scale, update, and manage the lifecycle of these microservices in a highly available and resilient manner.