Deploy Jakarta EE application to Google Cloud Platform (GCP) with Kubernetes

In the last tutorial, we learned how to deploy our Jakarta EE application locally and created our own Docker registry where we deployed our Docker images and today we will learn how to deploy our Jakarta EE application to Google Cloud Platform (GCP) with Kubernetes.

Go to https://cloud.google.com/ and create an account, you will get $300 credit and it's valid for one year.

To follow this tutorial, you will need Docker, Kubernetes, Maven and Google Cloud SDK.

Create Google Kubernetes Engine Cluster.

Click in the top menu bar where it says My first project and create a new project, I will call my project jakartaee-cloud-project and when it's created select it.

1. In the menu, click on Kubernetes Engines and then on Clusters.

2. Click on Create Cluster, choose the default values for now, this will take few minutes.

Google Cloud SDK

Install the Google Cloud SDK and run the following command in the terminal.

$> gcloud init

Next install the kubectl command by using the following command:

$> gcloud components install kubectl

To see a list of components that are available, run the following command:

$> gcloud components list

Now we need to connect our local gcloud CLI with the cluster, you will find the correct command for your project when you click on the Connect button.

$> gcloud container clusters get-credentials standard-cluster-1 --zone us-central1-a --project
  zippy-starlight-256807

Output:

Fetching cluster endpoint and auth data.
kubeconfig entry generated for standard-cluster-1.

I will use my custom maven archetype to generate the Jakarta EE application.

Type the following command in your terminal:

$> mvn archetype:generate -DarchetypeGroupId=com.kodnito \
-DarchetypeArtifactId=kodnito-jakartaee-archetype \
-DarchetypeVersion=1.0.5 -DgroupId=com.kodnito \
-DartifactId=jakartaee-google-cloud -Dversion=1.0-SNAPSHOT

Now open the project in your IDE or editor of your choice.

Open deployment and make it look like this:


kind: Service
apiVersion: v1
metadata:
  name: jakartaee-google-cloud
  labels:
    app: jakartaee-google-cloud
spec:
  type: NodePort
  selector:
    app: jakartaee-google-cloud
  ports:
  - port: 8080
    targetPort: 8080
    name: http
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: jakartaee-google-cloud
spec:
  replicas: 2
  selector:
    matchLabels:
      app: jakartaee-google-cloud
  template:
    metadata:
      labels:
        app: jakartaee-google-cloud
        version: v1
    spec:
      containers:
        - name: jakartaee-google-cloud
          image:
  gcr.io/zippy-starlight-256807/jakartaee-google-cloud:1.0
          imagePullPolicy: Always
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 45
          livenessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 45
      restartPolicy: Always

This image: gcr.io/zippy-starlight-256807/jakartaee-google-cloud:1.0 part is the important one.

Run the following command to build the war file:

$> mvn clean package

The following command will build the image from the Dockerfile.

$> docker build -t jakartaee-google-cloud:1.0 .

Next command is used to tag the image so it points to our registry.

$> docker tag jakartaee-google-cloud:1.0
  gcr.io/zippy-starlight-256807/jakartaee-google-cloud:1.0

Run the following command to authenticate to Container registry.

$> gcloud auth configure-docker

Now we can push the image.

$> docker push gcr.io/zippy-starlight-256807t/jakartaee-google-cloud:1.0

Now it's time to deploy, use the following command to create the deployment.

$> kubectl apply -f deployment.yml

Now run the following command to see if the deployment was created.

$> kubectl get deployments
NAME                     READY UP-TO-DATE  AVAILABLE   AGE
jakartaee-google-cloud   2/2   2           2           70s

The following command will list all the services.

$> kubectl get services

NAME                     TYPE CLUSTER-IP  EXTERNAL-IP   PORT(S)           AGE
jakartaee-google-cloud   NodePort         10.12.4.69    8080:31719/TCP    109s
kubernetes               ClusterIP        10.12.0.1     443/TCP           15m

Your cluster is not ready yet because it is not publicly accessible, so in the root of the project create a file called jakartaee-ingress-deployment.yml and add the following:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: jakartaee-google-cloud-ingress
spec:
  backend:
    serviceName: jakartaee-google-cloud
    servicePort: 8080

This file defines an Ingress resource that directs traffic to our service.

Ingress is a Kubernetes resources that defines rules and configurations for HTTP(S) routes outside the cluster to services within the cluster.

Now create the deployment:

$> kubectl apply -f jakartaee-ingress-deployment.yml

With the following command we will se the IP

$> kubectl get ingress jakartaee-google-cloud-ingress

NAME                             HOSTS ADDRESS           PORTS AGE
jakartaee-google-cloud-ingress   *     107.178.255.164   80    3m35s

Now open your browser and point it to http://IP/jakartaee-google-cloud/api/hello

You can find the source code on GitHub.

About the Author

Hayri Cicek

Hayri Cicek