Hands-On Class (Using Real Repositories)
π― Class Objective
- Understand GitOps
- Install Argo CD
- Build a real CI/CD pipeline
- Use GitHub Actions for CI
- Use Argo CD for CD
- Debug real-world failures (ImagePullBackOff, secrets, pipelines)
This is exactly how production systems work.
π§ CORE IDEA
β Why GitOps?
Traditional deployment:
β Manual
β Not auditable
β Not scalable
β GitOps approach:
- Git = Single Source of Truth
- No manual
kubectl apply - Rollback =
git revert
π§© ARCHITECTURE OVERVIEW
Developer
|
v
GitHub (CI Repo)
|
v
GitHub Actions (CI)
|
v
GitHub Container Registry (GHCR)
|
v
GitHub (GitOps Repo)
|
v
Argo CD (CD)
|
v
Kubernetes (Minikube)
π Clone this repository
git clone https://github.com/jumptotechschooldevops/k8s-ci-build.git
cd k8s-ci-build
π Structure:
k8s-ci-build/
βββ Dockerfile
βββ src/
β βββ app.js
β βββ package.json
β βββ package-lock.json
βββ .github/workflows/ci-cd.yml
π Purpose:
- Build Docker image
- Push image to GHCR
- Update GitOps repo
2οΈβ£ GitOps Repository (Deployment Only)
π Clone this repository
git clone https://github.com/jumptotechschooldevops/grade-api-gitops.git
cd grade-api-gitops
π Structure:
grade-api-gitops/
βββ deployment.yaml
π Purpose:
- Contains only Kubernetes manifests
- Argo CD watches this repo
- CI modifies this repo
- Humans do NOT deploy manually
π§° REQUIRED TOOLS (INSTALLATION)
1οΈβ£ Docker Desktop
Required for:
- Docker builds
- Minikube driver
Verify:
docker version
2οΈβ£ kubectl
Verify:
kubectl version --client
3οΈβ£ Minikube
minikube start
kubectl get nodes
Expected:
STATUS: Ready
π INSTALL ARGO CD
Step 1: Create namespace
kubectl create namespace argocd
Step 2: Install Argo CD
kubectl apply -n argocd \
-f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Step 3: Wait for pods
kubectl get pods -n argocd -w
Explain to students:
-
Initcontainers - Controllers starting
- Normal startup delays
Step 4: Access Argo CD UI
kubectl port-forward svc/argocd-server -n argocd 8080:443
Open browser:
https://localhost:8080
Ignore SSL warning.
Step 5: Login to Argo CD
Get password:
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 --decode
Login:
- Username:
admin - Password: decoded value
π¦ CREATE ARGO CD APPLICATION
π Create file: grade-api-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: grade-api
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/jumptotechschooldevops/grade-api-gitops.git
targetRevision: main
path: .
destination:
server: https://kubernetes.default.svc
namespace: grade
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Apply:
kubectl apply -f grade-api-app.yaml
π§Ύ GITOPS DEPLOYMENT FILE (IMPORTANT)
π File:
grade-api-gitops/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: grade-submission-api
namespace: grade
spec:
replicas: 1
selector:
matchLabels:
app: grade-submission-api
template:
metadata:
labels:
app: grade-submission-api
spec:
imagePullSecrets:
- name: ghcr-secret
containers:
- name: grade-submission-api
image: ghcr.io/jumptotechschooldevops/k8s-ci-build:PLACEHOLDER
ports:
- containerPort: 3000
β οΈ
PLACEHOLDER is intentional β CI will replace it.
π CREATE GHCR IMAGE PULL SECRET
GitHub PAT requirements:
read:packages
Create secret:
kubectl -n grade create secret docker-registry ghcr-secret \
--docker-server=ghcr.io \
--docker-username=jumptotechschooldevops \
--docker-password=<YOUR_GITHUB_PAT> \
--docker-email=devnull@example.com
βοΈ CI PIPELINE (GitHub Actions)
π File:
k8s-ci-build/.github/workflows/ci-cd.yml
name: CI - Build Image and Update GitOps
on:
push:
branches:
- main
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.CR_PAT }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ghcr.io/jumptotechschooldevops/k8s-ci-build:${{ github.sha }}
- name: Checkout GitOps repo
uses: actions/checkout@v4
with:
repository: jumptotechschooldevops/grade-api-gitops
token: ${{ secrets.GITOPS_PAT }}
path: gitops
- name: Update image tag
run: |
cd gitops
sed -i "s/PLACEHOLDER/${{ github.sha }}/g" deployment.yaml
- name: Commit and push
run: |
cd gitops
git config user.name "GitHub Actions"
git config user.email "ci@jumptotech.dev"
git add deployment.yaml
git commit -m "Update image to ${{ github.sha }}" || echo "No changes"
git push
π REQUIRED GITHUB SECRETS (CI REPO)
Repo: k8s-ci-build β Settings β Secrets β Actions
| Secret Name | Purpose |
|---|---|
CR_PAT |
Push image to GHCR |
GITOPS_PAT |
Push to GitOps repo |
𧨠TROUBLESHOOTING (REAL ISSUES WE FACED)
β ImagePullBackOff
Cause:
- Image tag =
PLACEHOLDER
Fix:
- CI replaces it with commit SHA
β CI error: Password required
Cause:
- Missing
CR_PAT
Fix:
- Create GitHub PAT
- Add to repo secrets
β CI error: nothing to commit
Cause:
- File unchanged
Fix:
git commit ... || echo "No changes"
β Argo CD shows Synced but pod fails
Cause:
- Missing
imagePullSecret
Fix:
- Create
ghcr-secret - Restart pod
β FINAL VERIFICATION
kubectl get pods -n grade
Expected:
READY STATUS
1/1 Running
π PIPELINE COMPLETE
Top comments (0)