How to deploy to google kubernetes engine using Github actions

Google Kubernetes Engine(GKE) is a managed Kubernetes cluster service from Google Cloud that can host your containerized workloads in the cloud or in your own datacenter. 

In this guide, we will learn how to use GitHub Actions to build a containerized application, push it to Google Container Registry (GCR), and deploy it to Google Kubernetes Engine (GKE) when there is a push to the main branch.

Checkout related Content:

Step 1 – Prerequisites

To follow along this guide, you need to have a google account then create a gke cluster. The assumption is that you already have a project with a Dockerfile at the base and kubernetes deployment configuration in the deploy directory.

Creating a Google account and a Kubernetes cluster

First ensure that you have a google cloud account. Head over to the google cloud page and create an account. Once you have an active account, we can create a gke cluster.

Next create a google kubernetes cluster. There are many ways of going about it. You can either go to the google cloud console UI and click on the Create cluster button.

You can also use automation tools like terraform. Checkout How to use Terraform to create a vpc network and a GKE in GCP.

To create a GKE cluster in the command line using gcloud, you will first need to authenticate using the gcloud  then use this command:

export GKE_CLUSTER=citizix-main
export GKE_PROJECT=citizix-prj
export GKE_ZONE=europe-west6

gcloud container clusters create $GKE_CLUSTER \
	--project=$GKE_PROJECT \
	--zone=$GKE_ZONE

Enabling the APIs

Enable the Kubernetes Engine and Container Registry APIs. You can use the cloud console to achieve this but if you have gcloud access use this command:

gcloud services enable \
	containerregistry.googleapis.com \
	container.googleapis.com

Configure a Service Account

For GKE integration and access, we will need a service account. In this section, we will create an account,

add roles to it, retrieve its keys, and store them as a base64-encoded encrypted repository secret named GKE_SA_KEY.

Create a new service account:

export SA_NAME=gkeaccess

gcloud iam service-accounts create ${SA_NAME}

Retrieve the email address of the service account you just created:

gcloud iam service-accounts list

Add roles to the service account. Note: Apply more restrictive roles to suit your requirements.

export GKE_PROJECT=citizix-prj
export SA_EMAIL=gkeaccess@citizix-prj.iam.gserviceaccount.com

gcloud projects add-iam-policy-binding $GKE_PROJECT \
	--member=serviceAccount:$SA_EMAIL \
	--role=roles/container.admin
gcloud projects add-iam-policy-binding $GKE_PROJECT \
	--member=serviceAccount:$SA_EMAIL \
	--role=roles/storage.admin
gcloud projects add-iam-policy-binding $GKE_PROJECT \
	--member=serviceAccount:$SA_EMAIL \
	--role=roles/container.clusterViewer

Download the JSON keyfile for the service account:

gcloud iam service-accounts keys create key.json --iam-account=$SA_EMAIL

Store the service account key as a secret named GKE_SA_KEY:

export GKE_SA_KEY=$(cat key.json | base64)

Step 2 – Creating the workflow

Once you’ve completed the prerequisites, you can proceed with creating the workflow.

The following example workflow demonstrates how to build a container image and push it to GCR. It then uses the Kubernetes tools (such as kubectl and kustomize) to pull the image into the cluster deployment.

Under the env key, change the value of GKE_CLUSTER to the name of your cluster, GKE_ZONE to your cluster zone, DEPLOYMENT_NAME to the name of your deployment, and IMAGE to the name of your image.

Be sure to set the variables defined with ${{ secrets.XXXX }} in github actions secrets in the project settings.

name: Build and deploy citizixapp in GKE

on:
  push:
    branches:
      - main

env:
  PROJECT_ID: ${{ secrets.GKE_PROJECT }}
  GKE_CLUSTER: citizix-main    # Add your cluster name here.
  GKE_ZONE: europe-west6       # Add your cluster zone here.
  DEPLOYMENT_NAME: citizixapp  # Add your deployment name here.
  IMAGE: citizixapp

jobs:
  build-push:
    name: Build, Push and deploy app to gke
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: 'Set up Cloud SDK'
        uses: 'google-github-actions/setup-gcloud@v0'
        with:
          service_account_key: ${{ secrets.GKE_SA_KEY }}
          project_id: ${{ secrets.GKE_PROJECT }}

      # Configure Docker to use the gcloud command-line tool as a credential
      # helper for authentication
      - run: |-
          gcloud --quiet auth configure-docker

      # Get the GKE credentials so we can deploy to the cluster
      - uses: 'google-github-actions/get-gke-credentials@v0'
        with:
          cluster_name: ${{ env.GKE_CLUSTER }}
          location: ${{ env.GKE_ZONE }}
          credentials: ${{ secrets.GKE_SA_KEY }}

      - name: Declare docker tag variables
        id: vars
        shell: bash
        run: |
          GIT_HASH=$(git rev-parse --short "${GITHUB_SHA}")
          echo "##[set-output name=docker_tag;]$(echo ${GITHUB_REF##*/}-${GIT_HASH})"

      # Build the Docker image
      - name: Build
        run: |-
          docker build \
            --tag "gcr.io/${PROJECT_ID}/$IMAGE:${{ steps.vars.outputs.docker_tag }}" .

      # Push the Docker image to Google Container Registry
      - name: Publish
        run: |-
          docker push "gcr.io/$PROJECT_ID/${IMAGE}:${{ steps.vars.outputs.docker_tag }}"

      - name: Setup Kustomize
        uses: imranismail/setup-kustomize@v1
        with:
          kustomize-version: 4.5.4

      - name: Update deploy image
        working-directory: deploy
        run: |-
          kustomize edit set image "gcr.io/$PROJECT_ID/${IMAGE}:${{ steps.vars.outputs.docker_tag }}"
          cat kustomization.yaml
          kustomize build . | kubectl apply -f -
          kubectl rollout status deployment/${DEPLOYMENT_NAME}
          kubectl get services -o wide

Conclusion

In the above guide, we learnt how to set up GKE and use github actions to deploy on push to a specific branch to it.

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy