Deploying to Kubernetes from CI/CD
A Kubernetes deploy is a new image, an updated manifest, and a watched rollout.
This module starts with the fundamental Kubernetes deploy loop from a pipeline: build an image, push it, point the deployment at the new tag, and wait for the rollout. Later lessons add Helm, GitOps, and progressive delivery on top of this base.
The deploy loop
- Build and push a uniquely tagged image (use the commit SHA).
- Authenticate the pipeline to the cluster.
- Update the deployment to reference the new image tag.
- Wait for the rollout and verify pods are healthy.
Tag images immutably
Never deploy :latest. Tag images with the commit SHA so each deploy references an exact, reproducible build. This makes rollbacks deterministic and avoids the cluster pulling a different image than you tested under a moving tag.
A basic deploy job
Set the image on the deployment, then wait for the rollout to complete:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: |
IMAGE=registry.example.com/app:${{ github.sha }}
docker build -t $IMAGE . && docker push $IMAGE
kubectl set image deployment/app app=$IMAGE
kubectl rollout status deployment/app --timeout=120sVerify the rollout
The kubectl rollout status command blocks until new pods are ready or the timeout hits, failing the job if the rollout stalls. This catches crash-looping pods or failed readiness checks instead of reporting a broken deploy as success.
Key takeaways
- The Kubernetes deploy loop is push image, update deployment, watch rollout.
- Tag images by commit SHA for reproducible, rollback-friendly deploys.
- Use
kubectl rollout statusso a stalled rollout fails the job.