Kubernetes Capstone and Next Steps¶
Overview¶
You have progressed from your first Pod to GitOps delivery, autoscaling, observability, and cluster hardening. This capstone deploys VoteStack — the multi-service poll application from the Docker capstone — on a production-style Kubernetes cluster. You will wire every layer from the Module 6 tutorials into one cohesive project and document a roadmap to Terraform for infrastructure and GitLab CI/CD for enterprise pipelines.
This is Tutorial 20 — the finale of Module 6: Production and the complete REBASH Academy Kubernetes track.
Prerequisites¶
- Kubernetes Security Hardening
- GitOps and CI/CD with Kubernetes
- Production Patterns — HPA, PDB, and Affinity
- Monitoring and Logging in Kubernetes
- Helm Package Management
- Ingress and External Access
- Persistent Volumes and Storage
- Cluster with ingress controller, metrics-server, and Helm 3
- Container images from Docker track or GitOps CI pipeline
Learning Objectives¶
By the end of this capstone, you will be able to:
- Deploy VoteStack on Kubernetes using a Helm chart and Argo CD
- Configure HPA, PDB, and topology spread for api and worker tiers
- Expose the app via Ingress with TLS and internal NetworkPolicies
- Instrument services with Prometheus metrics and centralized logging
- Apply Pod Security Standards and Kyverno policies to the stack
- Document operational runbooks and a learning path to Terraform and GitLab
Architecture Diagram¶
flowchart TB
subgraph External
USER[Browser]
DNS[votestack.example.com]
end
subgraph IngressLayer["ingress-nginx"]
ING[Ingress + TLS]
end
subgraph Votestack["namespace: votestack"]
WEB[web Deployment]
API[api Deployment + HPA]
WORK[worker Deployment + HPA]
REDIS[redis StatefulSet]
PG[postgres StatefulSet + PVC]
end
subgraph Platform
ARGO[Argo CD]
PROM["Prometheus / Grafana"]
KYV[Kyverno]
end
USER --> DNS --> ING
ING --> WEB
ING --> API
API --> REDIS
API --> PG
WORK --> REDIS
WORK --> PG
ARGO -.->|sync| Votestack
PROM -.->|scrape| API
KYV -.->|enforce| Votestack Project Overview — VoteStack on Kubernetes¶
VoteStack mirrors the Docker capstone with Kubernetes-native primitives:
| Service | Kubernetes resource | Notes |
|---|---|---|
| web | Deployment + Service | Static UI; 2 replicas |
| api | Deployment + Service + HPA + PDB | REST API; /health, /ready, /metrics |
| worker | Deployment + HPA | Queue consumer; scales on Redis depth |
| redis | StatefulSet + headless Service | Persistent queue (dev lab); use ElastiCache in prod |
| postgres | StatefulSet + PVC | Dev lab; use RDS/Cloud SQL in prod |
| edge | Ingress | TLS via cert-manager |
Same container images built in the Docker track — only deployment manifests change.
Project Structure¶
votestack-gitops/
├── apps/
│ ├── root-app.yaml # App-of-Apps bootstrap
│ └── votestack/
│ └── application.yaml
├── charts/
│ └── votestack/
│ ├── Chart.yaml
│ ├── values.yaml
│ ├── values-dev.yaml
│ ├── values-prod.yaml
│ └── templates/
│ ├── namespace.yaml
│ ├── web/
│ ├── api/
│ ├── worker/
│ ├── redis/
│ ├── postgres/
│ ├── ingress.yaml
│ ├── hpa.yaml
│ ├── pdb.yaml
│ ├── networkpolicy.yaml
│ └── servicemonitor.yaml
├── policies/
│ └── kyverno/
│ ├── require-limits.yaml
│ └── disallow-latest.yaml
└── README.md
Hands-on Lab¶
Lab 1 — Bootstrap GitOps (App of Apps)¶
apps/root-app.yaml:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: votestack-root
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/org/votestack-gitops.git
targetRevision: main
path: charts/votestack
helm:
valueFiles:
- values-dev.yaml
destination:
server: https://kubernetes.default.svc
namespace: votestack
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Lab 2 — Stateful data tier¶
Postgres StatefulSet excerpt (templates/postgres/statefulset.yaml):
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
namespace: votestack
spec:
serviceName: postgres
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
securityContext:
fsGroup: 999
containers:
- name: postgres
image: postgres:16-alpine
envFrom:
- secretRef:
name: postgres-credentials
ports:
- containerPort: 5432
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 10Gi
Apply SealedSecret for credentials (see Kubernetes Security Hardening).
Verify: kubectl get pvc -n votestack
Lab 3 — Ingress with TLS¶
Install cert-manager (once per cluster):
helm repo add jetstack https://charts.jetstack.io
helm install cert-manager jetstack/cert-manager \
-n cert-manager --create-namespace \
--set crds.enabled=true
Ingress template:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: votestack
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts: [votestack.example.com]
secretName: votestack-tls
rules:
- host: votestack.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: votestack-api
port:
number: 8080
- path: /
pathType: Prefix
backend:
service:
name: votestack-web
port:
number: 3000
Smoke test:
curl -sf https://votestack.example.com/api/health
curl -sf https://votestack.example.com/ -o /dev/null
Lab 4 — HPA, PDB, and spread (production patterns)¶
Enable in values-dev.yaml:
api:
replicas: 2
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 8
targetCPUUtilization: 70
pdb:
minAvailable: 1
topologySpread:
enabled: true
worker:
autoscaling:
enabled: true
minReplicas: 1
maxReplicas: 5
Sync and validate:
Lab 5 — Observability stack integration¶
Add ServiceMonitor to Helm chart (see Monitoring and Logging). Import VoteStack Grafana dashboard. Confirm alerts:
kubectl port-forward svc/kube-prometheus-grafana -n monitoring 3000:80
# Dashboard: error rate, p99 latency, pod restarts
Log query in Loki:
Lab 6 — Security hardening checklist¶
Apply the full security stack from Tutorial 19:
# Pod Security
kubectl label namespace votestack \
pod-security.kubernetes.io/enforce=restricted --overwrite
# NetworkPolicies
kubectl apply -f charts/votestack/templates/networkpolicy.yaml
# Kyverno policies
kubectl apply -f policies/kyverno/
# Verify
kubectl run bad --rm -it --image=nginx:latest -n votestack
# Expected: blocked by admission policy
Lab 7 — Operations runbook¶
# Backup postgres
kubectl exec -n votestack postgres-0 -- \
pg_dump -U voteapp votes > "backups/votes-$(date +%Y%m%d).sql"
# Rollback via GitOps
cd votestack-gitops
git revert HEAD && git push
argocd app sync votestack-root
# Scale manually (temporary — prefer HPA)
kubectl scale deployment votestack-api -n votestack --replicas=5
# Node drain simulation (respects PDB)
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data
Document results in README.md — architecture diagram, deploy steps, rollback procedure.
Commands & Code¶
# End-to-end status
kubectl get deploy,sts,svc,ingress,hpa,pdb -n votestack
argocd app get votestack-root
# End-to-end smoke
curl -sf https://votestack.example.com/api/health
curl -sf https://votestack.example.com/api/polls | jq .
# Debug chain
kubectl logs -n votestack deploy/votestack-api --tail=50
kubectl describe pod -n votestack -l app=votestack-api
kubectl get events -n votestack --sort-by='.lastTimestamp' | tail -10
Common Mistakes¶
Running postgres/redis in prod without backups
StatefulSets need backup automation and tested restore — or use managed databases.
Skipping TLS on Ingress
allowInsecure is for dev only — prod requires cert-manager or cloud LB certs.
Capstone without NetworkPolicies
A complete stack demo that ignores segmentation fails security interviews.
Manual kubectl edits in GitOps workflow
selfHeal reverts them — always change Git, not live cluster.
No resource requests on any tier
HPA and scheduling break — every container needs requests.
Best Practices¶
Portfolio README
Include architecture diagram, tech stack, and kubectl get screenshot — strong interview artifact.
Managed services in real prod
Replace in-cluster postgres/redis with RDS and ElastiCache — keep StatefulSets for learning labs.
Environment parity
Same Helm chart, different values files — dev/staging/prod differ only in replicas, hosts, and secrets backend.
Chaos exercise
Delete api pods during load test — observe HPA, PDB, and Ingress recovery.
Continue the platform path
Kubernetes completes orchestration — Terraform provisions the cluster itself.
Troubleshooting¶
| Issue | Cause | Solution |
|---|---|---|
| Ingress 502 | api not ready | Check probes; postgres/redis connectivity |
| TLS not issued | cert-manager misconfig | kubectl describe certificate -n votestack |
| HPA no scale | Missing metrics-server | Install metrics-server; verify requests |
| Argo OutOfSync loop | Helm hook or ignored diff | Add ignoreDifferences for known fields |
| NetworkPolicy blocks traffic | Missing DNS/ingress rule | Add egress UDP 53; allow ingress namespace |
| PVC Pending | No StorageClass | kubectl get sc; set default class |
Summary¶
- The VoteStack Kubernetes capstone combines Helm, GitOps, Ingress, StatefulSets, HPA, PDB, observability, and security hardening
- Same images from the Docker track — Kubernetes adds scheduling, scaling, segmentation, and declarative delivery
- GitOps is the deployment interface — runbooks center on Git revert, Argo sync, and backup/restore
- Production reality swaps in-cluster databases for managed services and clusters for Terraform-provisioned infrastructure
- You have finished all 20 Kubernetes tutorials — continue to Terraform, GitLab CI/CD, and Learning Paths
Interview Questions¶
- Walk through VoteStack architecture on Kubernetes — from Ingress to postgres.
- Why use StatefulSet for postgres instead of Deployment?
- How does GitOps rollback differ from
kubectl rollout undo? - What would you change moving from dev cluster to production AWS EKS?
- Explain how HPA, PDB, and topology spread work together during a node upgrade.
- How do NetworkPolicies map to the Docker Compose internal network model?
- What metrics and alerts would you define for VoteStack in production?
- Why seal secrets instead of using Kubernetes Secrets directly in Git?
- How does this capstone demonstrate the full Kubernetes track skills?
- What is the natural next skill after completing Kubernetes?
Sample Answers (Questions 1, 4, and 10)
Q1 — K8s VoteStack flow: Browser resolves votestack.example.com → Ingress (TLS) routes /api to api Service → api pods (HPA-scaled, PDB-protected) validate and enqueue votes to redis. worker pods consume queue, write to postgres StatefulSet. web pods serve UI. NetworkPolicies restrict api to redis/postgres only. Prometheus scrapes /metrics; logs flow to Loki. Argo CD syncs all resources from Git.
Q4 — Dev to EKS prod: Provision EKS with Terraform (VPC, node groups, IRSA). Replace in-cluster postgres/redis with RDS and ElastiCache. Use ALB Ingress Controller and ACM certs. External Secrets for credentials. Multi-AZ node groups; Cluster Autoscaler. Centralized observability (AMP/Grafana or Datadog). GitOps with prod approval gates; separate AWS accounts for envs.
Q10 — After Kubernetes: Terraform for infrastructure-as-code — VPC, EKS/GKE, IAM, RDS. GitLab CI/CD for enterprise pipeline patterns. Service mesh (Istio/Linkerd) for advanced traffic management. Platform engineering — Internal Developer Platforms (Backstage, Crossplane). Return to Learning Paths for role-specific roadmaps.
Next Steps — Terraform and GitLab¶
Terraform track¶
Kubernetes clusters do not appear by magic. The Terraform track teaches:
| Topic | Delivers |
|---|---|
| HCL fundamentals | Variables, modules, state |
| AWS/GCP/Azure providers | VPC, subnets, security groups |
| EKS/GKE modules | Managed control plane + node pools |
| IAM and IRSA | Pod-level AWS permissions without static keys |
VoteStack prod target architecture:
Terraform → EKS cluster + RDS + ElastiCache + ECR
↓
GitOps repo → Helm deploys VoteStack to EKS
↓
CI pipeline → builds images, updates tags
GitLab CI/CD track¶
The GitLab track complements GitHub Actions patterns from Tutorial 16:
- Multi-environment deploy pipelines with manual approval gates
- Container registry integrated with CI
- GitLab Agent for Kubernetes (agent-based deploy alternative)
- Compliance frameworks and audit trails
If your organization standardizes on GitLab, port the VoteStack CI workflow — build, scan, update GitOps manifest — to .gitlab-ci.yml.
Recommended learning path¶
flowchart LR
DOCKER[Docker track ✓]
K8S[Kubernetes track ✓]
TF[Terraform track]
GL["GitLab CI/CD"]
LP[Learning Paths]
DOCKER --> K8S
K8S --> TF
K8S --> GL
TF --> LP
GL --> LP - Deploy VoteStack capstone as portfolio project
- Begin Terraform – Introduction — provision a lab EKS cluster
- Migrate VoteStack GitOps target from kind/minikube to Terraform-managed EKS
- Optional: GitLab CI/CD Overview — enterprise pipeline patterns
- Follow DevOps Engineer Learning Path for role certification goals
Related Tutorials¶
- Kubernetes Security Hardening (previous)
- GitOps and CI/CD with Kubernetes
- Production Patterns — HPA, PDB, and Affinity
- Monitoring and Logging in Kubernetes
- Docker Capstone and Next Steps
- From Docker to Kubernetes
- Kubernetes – Category Overview — track complete
- Terraform – Category Overview — next track
- GitLab CI/CD Overview
- Learning Paths
References¶
- Kubernetes – Production Best Practices
- CNCF – Trail Map
- The Twelve-Factor App
- Google SRE Book
- REBASH Academy – Terraform Overview
- REBASH Academy – GitLab Overview
- REBASH Academy – Roadmap
Congratulations¶
You have completed all 20 tutorials in the REBASH Academy Kubernetes track — from orchestration fundamentals through GitOps delivery, autoscaling, observability, security hardening, and the VoteStack capstone. Return to the Kubernetes Overview to review the curriculum, publish VoteStack as a portfolio project, and begin the Terraform track when you are ready to provision cloud infrastructure that runs your clusters.