This article will walk you through setting up a CI/CD pipeline for Kubernetes using GitHub, GitHub Actions, and Argo CD | Deploy to Kubernetes using GitHub Actions CI/CD, Docker, DockerHub and ArgoCD, following GitOps best practices by separating the application source code and Kubernetes configuration into two separate GitHub repositories.
In modern software development, CI/CD (Continuous Integration and Continuous Deployment) pipelines are essential for automating the software delivery process. Kubernetes, with its powerful orchestration and container management capabilities, is widely used for deploying applications. Combined with GitHub for source code management, GitHub Actions for CI/CD automation, and Argo CD for continuous deployment with GitOps practices, you can set up a robust and efficient CI/CD pipeline.
Table of Contents
Prerequisites
- A Kubernetes Cluster: Make sure you have access to a Kubernetes cluster either locally (Minikube, Docker-Desktop, etc.) or remotely.
- kubectl: Install the Kubernetes CLI tool to interact with your cluster.
- GitHub Account: Create a GitHub account and repositories.
- DockerHub: Set up a DockerHub account for storing your Docker images.
- Argo CD: A declarative, GitOps-based continuous delivery tool for Kubernetes.
Overview of GitHub Actions CI/CD Pipeline with ArgoCD and Kubernetes
- Kubernetes (K8s): An open-source container orchestration platform for automating the deployment, scaling, and management of containerized applications.
- Argo CD: A declarative GitOps continuous delivery tool for Kubernetes that automates the deployment of applications.
- GitHub Actions: A tool for automating workflows within GitHub repositories. It supports CI/CD pipelines and can be customized to run multiple steps, including building, testing, and deploying code.
- Continuous Delivery (CD) vs Continuous Deployment (CD):
- Continuous Delivery (CD) ensures that your application can be released at any time by automatically pushing code through different stages until it’s ready for production.
- Continuous Deployment (CD) automatically deploys code changes to production once they are ready.
GitHub Actions CI/CD Workflow
GitHub Actions Workflow 1 (CI):
- This workflow is triggered when there are changes in the application source code repository (via push, PR, or commit).
- It builds the Docker container, runs tests, and pushes the image to a Docker repository.
- This workflow will trigger Workflow 2 with the image tag as input.
GitHub Actions Workflow 2 (CD):
- Workflow 2 takes the newly built Docker image tag, updates the Kubernetes deployment manifest, and pushes it to the Application/K8s Configuration repository.
- Argo CD detects the change, pulls the update, and redeploys the application to the cluster.
Argo CD:
- Argo CD monitors the Application/K8s Configuration repository for changes. Once it detects the updated Docker image in the Kubernetes manifest, it deploys the new version to the cluster.
Deploy to Kubernetes using GitHub Actions CI/CD, Docker, DockerHub and ArgoCD
Step #1:Install Argo CD on Kubernetes Cluster
Install Argo CD in your Kubernetes cluster:
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
kubectl port-forward --address 0.0.0.0 svc/argocd-server 8888:80 -n argocd
Access the UI at http://localhost:8080 and log in with the username admin
and the password retrieved using:
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
Step #2:Set Up GitHub Repositories
You need two repositories:
- Application Source Code Repository: Contains your application code.
- Application/K8s Configuration Repository: Contains Kubernetes manifests (or Helm/Kustomize files).
Clone or set up repositories:
Step #3:Configure Argo CD for Deployment
In the Application/K8s Configuration repository, configure Argo CD
cd argocd-node-app-config
Update repoUrl
to match your repository and deploy with:
kubectl apply -f application.yaml
This will register the app with Argo CD and begin monitoring it.
Step #4:Set Up GitHub Actions Workflows
GitHub Actions will handle both the CI and CD processes. You will need to create two workflows in your application repository and Kubernetes configuration repository.
Workflow 1 (CI): This workflow will be triggered by code changes, pull requests, or manual triggers. It builds the Docker image, tags it, and pushes it to a container registry (e.g., DockerHub).
name: CI
on:
workflow_dispatch:
env:
IMAGE_NAME: examplenode-dev
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: ${{ github.actor }}/${{ env.IMAGE_NAME }}:${{ github.run_number }}
- name: Repository Dispatch
uses: peter-evans/repository-dispatch@v1
with:
token: ${{ secrets.PAT }}
repository: ${{ github.actor }}/argocd-node-app-config
event-type: new-image
client-payload: '{"image": "${{ github.actor }}/${{ env.IMAGE_NAME }}:${{ github.run_number }}"}'
Workflow 2 (CD): This workflow is triggered by the successful completion of Workflow 1. It updates the Kubernetes deployment manifest in the K8s Configuration repository with the new Docker image tag.
name: Repository Dispatch
on:
repository_dispatch:
types: [new-image]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Update Image Version
id: imgupd
uses: mikefarah/yq@master
with:
cmd: yq eval '.spec.template.spec.containers[0].image = "${{ github.event.client_payload.image }}"' -i node-app/deployment.yaml
- uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: Apply image name changes
Step #5:Add Secrets for DockerHub and GitHub Actions
In GitHub, go to your repository Settings > Secrets and Variables > Actions > Repository secrets and add the following secrets:
DOCKERHUB_USERNAME
: Your DockerHub username.DOCKERHUB_TOKEN
: Your DockerHub password.- PAT: A personal access token for GitHub to interact with the K8s Configuration repository.
Step #6:Triggering the CI/CD Pipeline
Trigger Workflow 1 (CI): Modify the application code (e.g., change a string) and commit it to the node-app
repository. This will trigger Workflow 1, which builds the Docker image and pushes it to DockerHub.
Trigger Workflow 2 (CD): Workflow 1 will trigger Workflow 2, which updates the Kubernetes manifest with the new Docker image tag. This change will be committed to the K8s Configuration repository.
Argo CD will then detect the change (by default every 3 minutes), pull the latest changes, and deploy the new image to the Kubernetes cluster.
Step #7:CI/CD Flow in GitHub Actions
Once everything is set up, you can test your application by accessing it via port forwarding to access the Kubernetes service.
kubectl port-forward --address 0.0.0.0 svc/node-app-service 8080:3000 -n node-app
Security Considerations
- Access Control: You can control access to the application source code and Kubernetes configuration repositories separately. For example, developers may only have access to the application repository, while DevOps teams handle the Kubernetes configurations.
- Secrets Management: Ensure sensitive data (e.g., DockerHub credentials, GitHub tokens) are managed as secrets in GitHub Actions.
Conclusion:
This CI/CD pipeline using GitHub Actions and Argo CD follows GitOps best practices by separating the application source code from its Kubernetes configuration. By leveraging continuous deployment and pull-based deployment strategies, we can ensure smooth and automated updates to Kubernetes applications.
Related Articles:
GitOps Workflow with ArgoCD and GitHub Actions
Reference: