CI/CD Pipeline on GKE using GitHub Actions

CI/CD Pipeline on GKE using GitHub Actions

The purpose of this post is to demonstrate how to deploy a containerized application in Kubernetes using GitHub Actions and a very simple CI/CD pipeline.

GitHub Actions makes it simple to automate all your development activities. GitHub action makes it easy all the activities right from writing, testing and deploying code.

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.

GitHub Actions allows you to establish software development workflows, such as continuous integration and delivery (CI/CD) processes, from the same code repository where you save code and collaborate on pull requests and issues.


GKE is a Google Cloud managed Kubernetes cluster solution that can host your containerized workloads in the cloud or on-premises.


The GitHub Container Registry allows you to host and manage Docker container images in your company or personal GitHub account. Fine-grained permissions can also be used to control who can manage and access packages.


GitHub Actions core components -

Github Actions is an extension of Github. It mostly consists of workflows saved in a git repository (.github/workflows/)

Workflows are often triggered by events in the repository like commits, or external events tirggered via repository webhooks.?

When a workflow is activated, the runner takes over and executes each job one at a time.?

The job is made up of steps with actions that complete a task in the process.

CI/CD Workflow -

When we commit the code –

CI - container images is created from Dockerfile (using nginx & index.html) and pushed to google container registry gcr.io

CD – container is pulled from gcr.io and deployed (deploy.yaml is used) on Google Kubernetes Cluster Engine GKE

No alt text provided for this image

Pre - requisites -

  • ?Google Cloud Account
  • ?GitHub Account

Implementation Steps -

Install gcloud cli and configure it

$ curl -O https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-388.0.0-linux-x86_64.tar.gz
$ tar -xf google-cloud-cli-388.0.0-linux-x86.tar.gz
$./google-cloud-sdk/install.sh
$ which gcloud
$ gcloud init
        

Create GKE cluster

# Set variables -
$ export GKE_CLUSTER=github-gke-cicd
$ echo $GKE_CLUSTER
$ export GKE_PROJECT=cloud-devops-demo-351618
$ echo $GKE_PROJECT
$export GKE_ZONE=us-central1-c
$echo $GKE_ZONE
$ export SA_NAME=github-gke-cicd-sa
$ echo $SA_NAME
Create cluster -
$ gcloud container clusters create $GKE_CLUSTER --project=$GKE_PROJECT --zone=$GKE_ZONE        
No alt text provided for this image

In GUI check that GKE k8s cluster is created -

No alt text provided for this image

Enable APIs and Create service account to install GKE -

# Enable APIs -
$ gcloud services enable containerregistry.googleapis.com container.googleapis.com

# Create service account -
$ gcloud iam service-accounts create $SA_NAME

# Get Email address -
$ gcloud iam service-accounts list

# Set variable -
$ export SA_EMAIL=gcp-gitlab-sa@cloud-devops-demo-351618.iam.gserviceaccount.com?

# Get value of variable -
$ echo $SA_EMAIL        
No alt text provided for this image
No alt text provided for this image

Add IAM policies based on service account and add roles -

We are adding below roles -

Container Admin, Storage Admin and Container Cluster Viewer

$ 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        

Create Service Account Key which we will add as secret variable in GitHub -

$ export GKE_SA_KEY=$(cat key.json | base64)
$ echo $GKE_SA_KEY        
No alt text provided for this image

Create two secret variables in GitHub –

GKE_SA_KEY and GKE_PROJECT

No alt text provided for this image

Create github repo with below files -

 index.html
 Dockerfile
 deploy.yaml
 kustomization.yaml
.github/workflows/github-gke-ci-cd.yml        

$ cat index.html

Nginx HTML Demo App        

$ cat Dockerfile

FROM nginx:alpine
COPY . /usr/share/nginx/html        

$ cat kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
? - deploy.yaml        

Deployment file

$ cat deploy.yaml

apiVersion: v1
kind: Service
metadata:
? name: nginx-html-app-svc
? labels:
? ? app: nginx-html-app
spec:
? type: NodePort
? ports:
? - port: 80
? ? nodePort: 30080
? selector:
? ? app: nginx-html-app
---
apiVersion: apps/v1
kind: Deployment
metadata:
? name: nginx-html-app
? labels:
? ? app: nginx-html-app
spec:
? replicas: 1
? selector:
? ? matchLabels:
? ? ? app: nginx-html-app
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app: nginx-html-app
? ? spec:
? ? ? containers:
? ? ? - name: nginx-html-app
? ? ? ? image: gcr.io/PROJECT_ID/IMAGE:TAG
? ? ? ? ports:
? ? ? ? - containerPort: 80
? ? ? imagePullSecrets:
? ? ? - name: regcred        

$ cat .github/workflows/github-gke-ci-cd.yml

name: Build and Deploy to GKE
on:
? push:
? ? branches:
? ? ? - main
env:
? PROJECT_ID: ${{ secrets.GKE_PROJECT }}
? GKE_CLUSTER: github-gke-cicd? ? # Add your cluster name here.
? GKE_ZONE: us-central1-c? ?# Add your cluster zone here.
? DEPLOYMENT_NAME: deploy.yaml # Add your deployment name here.
? IMAGE: nginx-html-app
jobs:
? setup-build-publish-deploy:
? ? name: Setup, Build, Publish, and Deploy
? ? runs-on: ubuntu-latest
? ? environment: production
? ? steps:
? ? - name: Checkout
? ? ? uses: actions/checkout@v3
? ? # Setup gcloud CLI
? ? - uses: google-github-actions/setup-gcloud@94337306dda8180d967a56932ceb4ddcf01edae7
? ? ? 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@fb08709ba27618c31c09e014e1d8364b02e5042e
? ? ? with:
? ? ? ? cluster_name: ${{ env.GKE_CLUSTER }}
? ? ? ? location: ${{ env.GKE_ZONE }}
? ? ? ? credentials: ${{ secrets.GKE_SA_KEY }}
? ? # Build the Docker image
? ? - name: Build
? ? ? run: |-
? ? ? ? docker build \
? ? ? ? ? --tag "gcr.io/$PROJECT_ID/$IMAGE:$GITHUB_SHA" \
? ? ? ? ? --build-arg GITHUB_SHA="$GITHUB_SHA" \
? ? ? ? ? --build-arg GITHUB_REF="$GITHUB_REF" \ 
  ? ? ? ? .
? ? # Push the Docker image to Google Container Registry
? ? - name: Publish
? ? ? run: |-
? ? ? ? docker push "gcr.io/$PROJECT_ID/$IMAGE:$GITHUB_SHA"
? ? # Set up kustomize
? ? - name: Set up Kustomize
? ? ? run: |-
? ? ? ? curl -sfLo kustomize https://github.com/kubernetes-sigs/kustomize/releases/download/v3.1.0/kustomize_3.1.0_linux_amd64
? ? ? ? chmod u+x ./kustomize
? ? # Deploy the Docker image to the GKE cluster
? ? - name: Deploy
? ? ? run: |-
? ? ? ? ./kustomize edit set image gcr.io/PROJECT_ID/IMAGE:TAG=gcr.io/$PROJECT_ID/$IMAGE:$GITHUB_SHA
? ? ? ? ./kustomize build . | kubectl apply -f -
? ? ? ? kubectl rollout status deployment/$DEPLOYMENT_NAME
? ? ? ? kubectl get services -o wide        

Create and clone github repo nginx-html-app and add above files, commit and push -

No alt text provided for this image
$ git clone [email protected]:prayag-sangode/nginx-html-app.git
$ git config --global user.name prayag-sangode
$ git config --global user.email “[email protected]”
$ git config --global push.default current
$ git add .
$ git commit -m "added index.html page"
$ git branch -M main
$ git push -u origin main
$ git branch        

On git push GitHub Actions is triggered and CI/CD pipeline is implemented. Check GitHub Actions for status of CI CD workflow

No alt text provided for this image
No alt text provided for this image


Check app deployment status using kubectl -

$ gcloud components install kubectl
$ gcloud components install gke-gcloud-auth-plugin
$ gcloud container clusters list
$ gcloud container clusters get-credentials --zone us-central1-c github-gke-cicd
$ kubectl get all
$ kubectl get nodes        

Check google container images and tags in GCR

$ gcloud container images list
$ gcloud container images list-tags gcr.io/cloud-devops-demo-351618/nginx-html-app        
No alt text provided for this image

I hope you found this article to be useful in some way. I'll be back with some more interesting new DevOps articles soon.

要查看或添加评论,请登录

Prayag Sangode的更多文章

社区洞察

其他会员也浏览了