NashTech Insights

Deploy to GKE: Automating Deployment Workflow with GitHub Actions

Deepak Kumar
Deepak Kumar
Table of Contents

Introduction

In today’s fast-paced development landscape, deploying applications in a scalable and efficient manner is crucial. Google Kubernetes Engine (GKE) offers a robust platform for deploying and managing containerized applications in the Google Cloud environment. In this blog, we will explore the process of deploying a Java application to GKE using GitHub Actions. We’ll walk through the code snippets and configuration files involved in setting up a deployment pipeline, building a Docker image, and deploying the application to a GKE cluster. So, let’s dive in and learn how to deploy your Java application to GKE.

The following technologies are used for this demo: Java 19, Docker, Kubernetes, Spring Boot

Prerequisites for deploying your app to GKE

To follow this we need the following prerequisites:

Once you have installed the necessary CLI tools and set up your Google Cloud account, you can proceed to create a new project in the Google Cloud console. Creating a project allows you to organize and manage your various services and applications within a unified framework.

Google will automatically assign a unique ID for your project, which we’ll need later on for pushing the Docker image to GitHub Artifact Registry.

Next, you’ll need to create your initial Kubernetes cluster. You can use either the web console for this or the gcloud CLI. To create the cluster in your browser, open the left-side menu and navigate to Kubernetes Engine -> Clusters.

For simplicity, you can choose the Standard cluster template from Google to configure your Kubernetes cluster.  In addition, you can rename the cluster, select a specific region and the Kubernetes version. You can leave the other configuration options as they are pre-configured, which are suitable for a first demonstration.

Configure the Spring Boot application for a Kubernetes deployment

The sample Spring Boot application contains one REST endpoint to send a message:

@RestController
public class Controller {
    @GetMapping("/hello")
    public String hello_page() {
        return "hello nashtech!!!";
    }
}

That’s everything required from the code perspective. As we’ll use Docker as the container engine, we need to create a Docker image containing the application. For this, I’ve used a straightforward Java 1Dockerfile:

FROM openjdk:19-jdk
WORKDIR /app
COPY target/demo2-0.0.1-SNAPSHOT.jar app.jar
CMD ["java", "-jar", "app.jar"]

The actual Kubernetes Deployment object is defined in a .yaml file and contains the following configuration:

gcp_cicd_pipeline.yaml

name: Deploy to GKE

on:
  push:
    branches:
      - main

env:
  IMAGE_NAME: ghcr.io/deepak1067/myapp/myimage:latest
  PROJECT_ID: ${{ secrets.PROJECT_ID }}
  GKE_CLUSTER: deployment-cluster-sdk
  GKE_ZONE: asia-southeast1-a

jobs:
  setup-build-deploy:
    name: Setup, Build, and Deploy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Set up JDK 19
        uses: actions/setup-java@v2
        with:
          distribution: 'adopt'
          java-version: 19
      - run: mvn clean install --batch-mode --errors --fail-at-end
      - name: Upload Artifacts
        uses: actions/upload-artifact@v2
        with:
          name: demo2-0.0.1-SNAPSHOT.jar
          path: target/
  build-docker-image:
    name: build-docker
    needs: setup-build-deploy
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v2
      - name: Retrieve saved jar
        uses: actions/download-artifact@v2
        with:
          name: demo2-0.0.1-SNAPSHOT.jar
          path: target/

      - name: Set up Docker Build
        uses: docker/setup-buildx-action@v1

      - name: Build and push Docker image
        env:
          USERNAME: ${{ secrets.GITHUB_USERNAME }}
          PASSWORD: ${{ secrets.GITHUB_PASSWORD }}
        run: |
          echo $GITHUB_PASSWORD | docker login ghcr.io -u $GITHUB_USERNAME --password-stdin
          docker build --tag $IMAGE_NAME .
          docker push $IMAGE_NAME          

  deploy-to-gke:
    needs: build-docker-image
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - name: kubectl - Google Cloud GKE cluster.
        uses: ameydev/gke-kubectl-action@master
        env:
          PROJECT_ID: ${{ secrets.PROJECT_ID }}
          APPLICATION_CREDENTIALS: ${{ secrets.GCLOUD_AUTH }}
          CLUSTER_NAME: ${{ secrets.CLUSTER_NAME }}
          ZONE_NAME: asia-southeast1-a
        with:
          args: apply -f k8s/

Here is the deploy.yaml config in the k8s directory for creating the container.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demoapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demoapp
  template:
    metadata:
      labels:
        app: demoapp
    spec:
      containers:
        - name: demoapp
          image: ghcr.io/deepak1067/myapp/myimage:latest
          ports:
            - containerPort: 8080
      imagePullSecrets:
        - name: dockerconfigjson-github-com

here is the service.yaml config to expose the service to the target port.

apiVersion: v1
kind: Service
metadata:
  name: demoapp-service
spec:
  selector:
    app: demoapp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: LoadBalancer

Deploy the application to GKE

After committing the changes to the main branch the jobs will start to run the deployment in Github Action.

Afterward, you can check if the pods (instances) are up and running:

When querying for all available services, you will receive the public IP address. Please note that assigning the IP address may require a short delay.

For this example, the application is now available at http://34.87.120.208/hello and returns the following output:

Conclusion

Deploying a Java application to Google Kubernetes Engine (GKE) can be made easier and automated using GitHub Actions. By following the steps outlined in this blog, you can set up a deployment pipeline, build Docker images, and deploy your Java application to a GKE cluster with ease. Leveraging the power of containerization and orchestration, you can ensure scalability, reliability, and efficient management of your application in a cloud-native environment. So, get started with GKE and streamline your deployment process today!

You can find the whole codebase on my GitHub.

Deepak Kumar

Deepak Kumar

Leave a Comment

Your email address will not be published. Required fields are marked *

Suggested Article

%d bloggers like this: