GitHub Actions Tutorial — Deploy to Kubernetes
Deploy to Kubernetes
GitHub Actions can deploy to any Kubernetes cluster — EKS, GKE, AKS, or self-managed. The pattern is always: authenticate → set context → apply manifests (or run Helm).
kubectl Apply
With kubeconfig Secret
name: Deploy to Kubernetes
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Set kubeconfig
run: |
mkdir -p $HOME/.kube
echo "${{ secrets.KUBECONFIG }}" | base64 -d > $HOME/.kube/config
- name: Deploy
run: |
kubectl apply -f k8s/
kubectl rollout status deployment/my-app -n default --timeout=300s
With EKS
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1
- name: Update kubeconfig
run: aws eks update-kubeconfig --name my-cluster --region us-east-1
- run: kubectl apply -f k8s/
With AKS
steps:
- uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- uses: azure/aks-set-context@v4
with:
resource-group: my-rg
cluster-name: my-cluster
- run: kubectl apply -f k8s/
Helm Deployments
name: Helm Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Set kubeconfig
run: |
mkdir -p $HOME/.kube
echo "${{ secrets.KUBECONFIG }}" | base64 -d > $HOME/.kube/config
- name: Helm upgrade
run: |
helm upgrade --install my-app ./charts/my-app \
--namespace production \
--set image.tag=${{ github.sha }} \
--set replicas=3 \
--wait --timeout 5m
Kustomize
steps:
- uses: actions/checkout@v4
- name: Set image tag
run: |
cd k8s/overlays/production
kustomize edit set image my-app=my-registry/my-app:${{ github.sha }}
- name: Apply
run: kubectl apply -k k8s/overlays/production
Rolling Update Pattern
steps:
- name: Deploy
run: |
kubectl set image deployment/my-app \
my-app=my-registry/my-app:${{ github.sha }} \
-n production
- name: Wait for rollout
run: |
kubectl rollout status deployment/my-app \
-n production --timeout=300s
- name: Verify
run: |
kubectl get pods -n production -l app=my-app
Common Mistakes
| Mistake | Fix |
|---|---|
KUBECONFIG secret not base64 |
Encode: cat kubeconfig \| base64 -w0 |
| Rollout timeout | Increase --timeout or check pod events |
| Wrong namespace | Always specify -n namespace in kubectl commands |
| Helm values not updated | Use --set image.tag= to pass the commit SHA |
Quick Reference
| Tool | Command |
|---|---|
| kubectl | kubectl apply -f k8s/ |
| Helm | helm upgrade --install ... --wait |
| Kustomize | kubectl apply -k overlays/prod |
| EKS auth | aws eks update-kubeconfig |
| AKS auth | azure/aks-set-context@v4 |
| Rollout check | kubectl rollout status deployment/... |
← Previous: Deploy to Azure
Next: Deploy Docker Images →