Domain: E-commerce checkout
Stack: Go 1.22 · PostgreSQL 16 · Redis 7 · Kubernetes 1.35 · Helm 3
Namespace: payment-platform
A customer visits the store, browses products in the catalog, places an order (which reserves inventory), pays via the payment service, and receives a confirmation through notifications. User identity and JWT tokens are managed by the identity service.
| Service | Port | Responsibility |
|---|---|---|
| identity | 8081 | User registration, login (JWT), profile |
| catalog | 8082 | Product listing, inventory reserve/release |
| order | 8083 | Order creation, checkout orchestration |
| payment | 8084 | Transaction processing, mock webhook |
| notification | 8085 | Event records, notifications dispatch |
Each service owns its own PostgreSQL database. Redis is shared for session caching.
See docs/architecture.md for full ASCII diagram and data flow.
Ingress (nginx)
/auth/* → identity:8081
/products/* → catalog:8082
/orders/* → order:8083
/payments/* → payment:8084
/notifications/* → notification:8085
order orchestrates: catalog → payment → notification
| Tool | Version |
|---|---|
kubectl |
1.28+ |
helm |
v3.14+ |
docker |
24+ |
| Kubernetes cluster | 1.35 (Docker Desktop, kind, etc.) |
| Ingress controller | ingress-nginx installed |
metrics-server |
Required for HPA |
kubectl apply -f \
https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.1/deploy/static/provider/cloud/deploy.yaml
kubectl -n ingress-nginx rollout status deployment/ingress-nginx-controller --timeout=180skubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
kubectl -n kube-system patch deployment metrics-server \
--type=json \
-p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]'# Default tag: 1.0.0
./scripts/build.sh
# Custom tag
TAG=dev ./scripts/build.sh# Create namespace first
kubectl create namespace payment-platform
# Apply all resources (dev overlay: single replicas, dev tags)
./scripts/deploy.sh kustomize dev
# Or production overlay (2 replicas, explicit 1.0.0 tags)
./scripts/deploy.sh kustomize prod
# Apply Ingress + NetworkPolicy separately (needs ingress-nginx ready)
./scripts/deploy.sh network# Install all charts (platform + each service)
make capstone-helm-install
# → releases: platform, identity, catalog, payment, notification, frontend, order
# Upgrade a single service chart
make capstone-helm-upgrade CHART=identity
helm upgrade identity helm/identity -n payment-platform --set replicaCount=2
# Rollback one service
make capstone-helm-rollback CHART=identity REV=1
helm -n payment-platform history identitySee helm/README.md for chart layout.
./scripts/smoke-test.sh # via Ingress (localhost:80)
./scripts/smoke-test.sh portforward # via port-forwardFull verification commands in docs/ckad-checklist.md.
Quick summary:
# Pods running
kubectl -n payment-platform get pods -o wide
# Services have endpoints
kubectl -n payment-platform get endpoints
# ConfigMap & Secret injection
kubectl -n payment-platform exec deploy/catalog -c app -- env | grep -E 'PORT|APP_ENV'
kubectl -n payment-platform exec deploy/identity -c app -- env | grep JWT_SECRET
# SecurityContext
kubectl -n payment-platform exec deploy/identity -c app -- id
# → uid=<non-root>
kubectl -n payment-platform exec deploy/identity -c app -- sh -c 'grep CapEff /proc/1/status'
# → CapEff: 0000000000000000
# RBAC
kubectl auth can-i list pods -n payment-platform \
--as=system:serviceaccount:payment-platform:payment-platform-sa
# Quotas
kubectl -n payment-platform describe resourcequota
kubectl -n payment-platform describe limitrange
# HPA
kubectl -n payment-platform get hpa
# PVC persistence
kubectl -n payment-platform get pvc
# Ingress routing
curl http://localhost/auth/health
curl http://localhost/orders/health
# NetworkPolicy (applied, enforcement needs Calico/Cilium CNI)
kubectl -n payment-platform get networkpolicykubectl -n payment-platform get pods -o wide
kubectl -n payment-platform get svc,endpoints
kubectl -n payment-platform get ingresscurl http://localhost/auth/health # → identity
curl http://localhost/products/health # → catalogkubectl -n payment-platform exec deploy/catalog -c app -- env | grep APP_ENV
kubectl -n payment-platform get secret app-secrets -o yaml# Readiness depends on /health returning 200.
# Simulate failure by pointing to a wrong port temporarily:
kubectl -n payment-platform get endpoints catalog
# Show endpoint drops out of rotation when readiness failskubectl -n payment-platform set image deployment/catalog app=payment-platform/catalog:1.1.0
kubectl -n payment-platform rollout status deployment/catalog
kubectl -n payment-platform rollout undo deployment/catalogkubectl -n payment-platform get svc identity -o jsonpath='{.spec.selector}'
kubectl -n payment-platform patch svc identity \
-p '{"spec":{"selector":{"app":"identity","version":"v2"}}}'
kubectl -n payment-platform get endpoints identity
kubectl -n payment-platform patch svc identity \
-p '{"spec":{"selector":{"app":"identity","version":"v1"}}}'kubectl -n payment-platform get hpa order-hpa
kubectl -n payment-platform describe hpa order-hpakubectl -n payment-platform get networkpolicy
# Briefly explain default-deny + allow ruleskubectl -n payment-platform get pvc notification-audit-pvc
kubectl -n payment-platform exec deploy/notification -c app -- sh -c 'echo $(date) >> /data/audit/demo.log && cat /data/audit/demo.log'
kubectl -n payment-platform rollout restart deployment/notification
kubectl -n payment-platform rollout status deployment/notification
kubectl -n payment-platform exec deploy/notification -c app -- cat /data/audit/demo.log
# → data is still there after restarthelm -n payment-platform history payment
helm -n payment-platform rollback payment 1
helm -n payment-platform status payment- NetworkPolicy enforcement requires a CNI that supports it (Calico, Cilium, Kindnet ≥1.3). Docker Desktop's default CNI applies the policies to the API but does not enforce them at the network level.
- HPA requires
metrics-serverwith--kubelet-insecure-tlson Docker Desktop. - Secrets in
k8s/base/secrets.yamlusestringDatafor demo convenience. In production, replace with Sealed Secrets or External Secrets Operator. Never commit real secrets to git. - Image tags for
devoverlay require building withTAG=dev ./scripts/build.shbefore applying the dev overlay. - The
notificationservice writes audit records to/data/audit/via PVC, but the application itself doesn't yet persist structured events there — the volume is mounted and ready for future use.
.
├── README.md ← this file
├── docs/
│ ├── architecture.md ← service diagram, data flow
│ └── ckad-checklist.md ← §4 item → manifest path → verify command
├── services/ ← Go source code
│ ├── identity/
│ ├── catalog/
│ ├── order/
│ ├── payment/
│ └── notification/
├── pkg/ ← shared Go packages (auth, db, etc.)
├── docker/
│ ├── Dockerfile ← multi-stage build (--build-arg SERVICE=<svc>)
│ ├── entrypoint.sh
│ └── init/
│ ├── Dockerfile ← wait-for init container
│ └── wait-for.sh
├── k8s/
│ ├── namespace.yaml
│ ├── base/ ← canonical manifests (Kustomize base)
│ │ ├── kustomization.yaml
│ │ ├── configmaps.yaml
│ │ ├── secrets.yaml
│ │ ├── fluent-bit-config.yaml
│ │ ├── infra/ ← redis, 5× postgres StatefulSets
│ │ └── services/ ← 5 Deployments + Services + HPA
│ ├── overlays/
│ │ ├── dev/kustomization.yaml ← dev tags, 1 replica
│ │ └── prod/kustomization.yaml← 1.0.0 tags, 2 replicas
│ ├── network/
│ │ ├── ingress.yaml ← 6-path Ingress (nginx)
│ │ └── netpol.yaml ← 11 NetworkPolicies (default-deny + allow)
│ ├── security/
│ │ ├── serviceaccount.yaml
│ │ ├── role.yaml
│ │ └── rolebinding.yaml
│ ├── quota/
│ │ ├── resourcequota.yaml
│ │ └── limitrange.yaml
│ ├── storage/
│ │ └── pvc.yaml ← notification-audit-pvc (1Gi RWO)
│ └── jobs/
│ ├── log-cleanup-cronjob.yaml ← nightly @ 00:00 UTC
│ └── health-check-job.yaml ← one-off smoke-test Job
├── helm/
│ └── payment-platform/ ← Helm chart (full app)
│ ├── Chart.yaml
│ ├── values.yaml
│ └── templates/
│ ├── _helpers.tpl
│ ├── configmaps.yaml
│ ├── secrets.yaml
│ ├── rbac.yaml
│ ├── storage.yaml
│ ├── infra.yaml
│ ├── identity.yaml
│ ├── catalog.yaml
│ ├── order.yaml ← includes HPA
│ ├── payment.yaml
│ ├── notification.yaml
│ └── ingress.yaml
└── scripts/
├── build.sh ← build & tag all Docker images
├── deploy.sh ← kustomize / helm / network / clean
└── smoke-test.sh ← end-to-end HTTP + cluster checks