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:
- How to use Terraform to create a vpc network and a Cloud SQL in GCP
- How to use Terraform to create a vpc network and a GKE in GCP
- How to use Terraform to create a vpc network and a Compute instance in GCP
- How to use Terraform to create a Redis instance in GCP
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.