Deployment & GitOps
Deployment is GitOps: the desired cluster state lives in the
flux-deployments repo, and FluxCD continuously reconciles the cluster to
match it. Engineers don't kubectl apply to prod — they merge manifest changes,
and Flux (plus image automation) does the rest.
flux-deployments layout
Apps/
DEV/ PROD/ CONFIG-MANAGER/
<service>/ deployment.yaml, service.yaml, configmap.yaml,
secret.sops.yaml, ingress.yaml, kustomization.yaml
Infrastructure/
cert-manager/ Traefik/ Monitoring/ ImageAutoUpdator/ cloudflare/
clusters/
my-cluster/flux-system/ (gotk-components.yaml, gotk-sync.yaml, kustomization.yaml)
- Apps/ — one folder per service per environment (
DEV→kk-ns-dev,PROD→kk-ns-prod), each a Kustomize bundle. Deployed services: backend, frontend, ms-ai, ms-communication, ms-sessions, widget, knock-agents, scheduler, plus per-service Redis (redis-backend,redis-communication,redis-sessions).CONFIG-MANAGER/holds shared config. - Infrastructure/ — cluster-wide components (below).
- clusters/my-cluster/ — Flux bootstrap: the
GitRepositorysource and rootKustomizationthat pull in Apps + Infrastructure.
Environments
A single cluster (my-cluster) with DEV (kk-ns-dev) and PROD
(kk-ns-prod) namespaces. Container images are published to Azure Container
Registry (knockknockacr.azurecr.io), e.g. kk-backend-repo-prod:1.0.510.
(Note: some service buildspec.yml files also target AWS ECR/EKS — the platform
spans AWS and Azure; the Flux image automation tracks ACR tags.)
Infrastructure components
| Component | Role |
|---|---|
| Traefik | ingress controller (LoadBalancer, 2 replicas, HTTP→HTTPS, metrics) |
| cert-manager | TLS via Let's Encrypt (staging + prod ClusterIssuers, wildcard) |
| Monitoring | Prometheus + Grafana + AlertManager (Prom-stack), Loki (logs), Grafana dashboards |
| ImageAutoUpdator | Flux ImageUpdateAutomation per service — auto-bumps image tags on new pushes |
| cloudflare | DNS / WAF |
The deploy flow
1. merge code → CI (buildspec) builds image → push to ACR/ECR with new tag
2. Flux ImageAutoUpdator polls the registry (~1 min) → detects the new tag
3. it rewrites the image: tag in the target deployment YAML (Kustomize image
policy marker), commits & pushes to flux-deployments
4. Flux GitRepository syncs → Kustomization reconciles → rolling update
(maxSurge 1, maxUnavailable 0)
So shipping is usually just "merge and let CI + Flux carry it" — no manual cluster ops. See CI/CD for the build half.
Secrets management
Secrets are SOPS-encrypted (Age key) and committed as secret.sops.yaml files;
Flux decrypts them in-cluster during reconciliation. Never commit plaintext
secrets — encrypt with the project SOPS config (.sops.yaml).
Notable per-service deployment facts
- backend runs API replicas plus a separate scheduler pod (cron leader,
SERVICE_CRON=true). - ms-sessions runs an HTTP deployment plus an autoscaling recording-worker deployment (HPA on queue depth).
- ms-ai migrations are run outside the container (CI), not on pod start.