Skip to content

jmweir/hello-world-spring-reactive-groovy

Repository files navigation

Spring Reactive Groovy Example

A demo app to show how to setup Reactive Spring on Netty, written in Groovy.

Build Application Jar

$ ./gradlew build

Build Docker Image

$ DOCKER_BUILDKIT=1 docker build -t com.example/hello-world:1.0.0 .

Deploy to Local Kubernetes

Install Kubernetes

  1. Install Docker for Desktop from here: https://www.docker.com/products/docker-desktop
  2. Activate Kubernetes in Docker preferences (takes 5-10 minutes the first time): Enable Kubernetes
  3. Confirm Kubernetes installation:
$ kubectl cluster-info
Kubernetes master is running at https://kubernetes.docker.internal:6443
KubeDNS is running at https://kubernetes.docker.internal:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

Create Kubernetes Deployment

  1. Generate YAML:
$ mkdir .kube
$ kubectl create deployment hello-world --image=com.example/hello-world:1.0.0 --dry-run -o yaml >.kube/deployment.yaml
$ cat .kube/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: hello-world
  name: hello-world
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-world
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: hello-world
    spec:
      containers:
      - image: com.example/hello-world:1.0.0
        name: hello-world
        resources: {}
status: {}
  1. Apply deployment:
$ kubectl apply -f .kube/deployment.yaml
deployment.apps/hello-world created

Forward Deployment Port and Test

$ kubectl port-forward deployment/hello-world 8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080

Test the application by browsing to http://localhost:8080

Scale the Deployment

  1. Update replicas from 1 to 2 in .kube/deployment.yaml
  2. Redeploy with: kubectl apply -f .kube/deployment.yaml

Create Kubernetes Load Balancing Service

  1. Generate YAML:
$ kubectl create service clusterip hello-world --tcp=8080:8080 --dry-run -o yaml >.kube/service.yaml
$ cat .kube/service.yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: hello-world
  name: hello-world
spec:
  ports:
  - name: 8080-8080
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: hello-world
  type: ClusterIP
status:
  loadBalancer: {}
  1. Apply service:
$ kubectl apply -f .kube/service.yaml
service/hello-world created

Forward Service Port and Test

$ kubectl port-forward svc/hello-world 8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080

Test the application by browsing to http://localhost:8080

Visualize POD Identification

  1. Add app.host: ${HOSTNAME} to application.yaml
  2. Add String host to Application.Config
  3. Add ${host} somewhere in the template

Deploy a New Image and Confirm Balancing

  1. Build a new Docker image: DOCKER_BUILDKIT=1 docker build -t com.example/hello-world:1.0.1 .
  2. Update 1.0.0 to 1.0.1 in .kube/deployment.yaml
  3. Redeploy with: kubectl apply -f .kube/deployment.yaml
  4. Reload http://localhost:8080 a few times and confirm round-robin load balancing.

Externalize configuration in a ConfigMap

  1. Generate a ConfigMap:
$ kubectl create configmap hello-world --from-literal=app.name=Jim --dry-run -o yaml >.kube/config.yaml
$ cat .kube/config.yaml
apiVersion: v1
data:
  app.name: Jim
kind: ConfigMap
metadata:
  creationTimestamp: null
  name: hello-world
  1. Apply the ConfigMap:
$ kubectl apply -f .kube/config.yaml
configmap/hello-world configured
  1. Add `org.springframework.cloud:spring-cloud-starter-kubernetes-config:1.1.1.RELEASE' as a Gradle dependency
  2. Remove app.name reference from application.yaml
  3. Build a new Docker image and update the deployment

Create Kubernetes NGINX Ingress

  1. Install NGINX Ingress Controller (see: https://kubernetes.github.io/ingress-nginx/deploy):
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.29.0/deploy/static/mandatory.yaml
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.29.0/deploy/static/provider/cloud-generic.yaml
  1. Create the file .kube/ingress.yaml:
$ cat .kube/ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: hello-world
spec:
  backend:
    serviceName: hello-world
    servicePort: 8080
  1. Apply ingress:
$ kubectl apply -f .kube/ingress.yaml
ingress.networking.k8s.io/hello-world created

Package with Helm

  1. Generate a Helm chart:
$ helm create .kube/hello-world
Creating .kube/hello-world
  1. Replace the contents of templates with the YAML files in .kube
  2. Delete values.yaml because we will supply values at install time.
  3. Externalize our name parameter. In config.yaml change Victor to {{ .Values.Name }}
  4. Add NGINX as a chart dependency by adding the following to Chart.yaml:
dependencies:
  - name: nginx-ingress
    version: 1.31.0
    repository: https://kubernetes-charts.storage.googleapis.com/
  1. Install NGINX chart with:
$ cd .kube/hello-world && helm dependency update
  1. Delete all resources that we've previously installed:
$ kubectl delete ingress/hello-world configmap/hello-world svc/hello-world deploy/hello-world
$ kubectl delete ns/ingress-nginx
  1. Install the new Helm chart:
$ helm install --set Name=Steve hello-world .kube/hello-world

About

Reactive Spring Groovy Example

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published