Kubernetes and Docker, run as a paved road.
Containers, clusters, Helm and GitOps from engineers who operate them under our own products. The platform your teams deploy to without thinking about it.
- Docker
- Kubernetes
- Helm
- ArgoCD
- Terraform
- GitHub Actions
Docker gave us one artefact that runs the same on a laptop, in CI and in production.
Kubernetes gave us one API for putting that artefact somewhere, keeping it alive, scaling it and routing traffic to it — on AWS, Azure, Google Cloud or a rack in Türkiye, with the same manifests. It is part of the stack our own products run on — Loyalty & Retention, Sales Performance, Order & Supply Management and Workflow & Procurement — on clusters our DevOps & Cloud practice operates.
The value is not the scheduler. It is what a cluster makes cheap: rolling deploys with automatic rollback, horizontal scaling from a metric, self-healing on node failure, and one place — the manifest — where the whole shape of a service is written down and reviewed. Teams that have this can ship small changes often. Teams that do not ship big changes on weekends.
When we don’t: a single monolith with three engineers and steady traffic does not need a cluster; managed containers (ECS, Azure Container Apps, Cloud Run) or a PaaS such as Vercel carry it for a fraction of the platform work. We say so in the assessment, in writing, before anyone buys a control plane.
Six things we ship on Kubernetes.
Managed clusters as code
EKS, AKS and GKE clusters defined in Terraform — node pools, IAM or workload identity, networking, private endpoints — reproducible per environment and disposable when a client wants to prove it.
The paved road for application teams
A base Helm chart, a Dockerfile template per language, a pipeline that builds, scans, signs and deploys. A new service can reach production with dashboards and alerts already attached.
GitOps delivery
ArgoCD reconciling clusters from Git, so the desired state is reviewed in a pull request and drift is visible. Rollback is a revert, not a war room.
Ingress, service mesh and zero-trust networking
Ingress controllers, mTLS between services where the compliance posture requires it, network policies that default to deny, and egress that is allow-listed and logged.
Stateful workloads done carefully
Kafka, Redis and search clusters run on Kubernetes with operators, persistent volumes and rehearsed restores. PostgreSQL usually stays managed, and we explain why.
Migration onto containers
Containerising legacy Java, .NET and Node.js services during a cloud migration — one workload at a time, behind the same ingress, with rollback to the VM until the cutover is proven.
When to choose it.
Choose Kubernetes when you run many services, several teams deploy independently, traffic varies enough that scaling by hand hurts, or you need the same platform across more than one cloud or an on-premise data centre. It fits estates where a platform team can own the cluster and application teams consume it through a paved road. It also fits regulated organisations that need network policy, admission control and an audit trail of every change as code.
Look elsewhere when there is one application and no platform team to run the cluster — the control plane becomes a second product nobody asked for. Look elsewhere when the workload is a website or an API that a managed container service or a PaaS runs happily, and when your organisation is not yet ready to invest in observability; Kubernetes without traces and dashboards is harder to operate than the VMs it replaced.
A deployment that can be rolled back and rolled forward safely.
image: registry.odeontech.internal/loyalty-api:2.14.3
replicas: 3
# Pods only receive traffic once they can actually serve it
readinessProbe: { httpGet: { path: /ready, port: 8080 }, periodSeconds: 5 }
livenessProbe: { httpGet: { path: /live, port: 8080 }, periodSeconds: 10 }
resources:
requests: { cpu: 250m, memory: 512Mi }
limits: { memory: 512Mi }
# Never lose the last healthy replica during a rollout or a node drain
strategy: { rollingUpdate: { maxUnavailable: 0, maxSurge: 1 } }
podDisruptionBudget: { minAvailable: 2 }
+ autoscaling: { min: 3, max: 12, targetCPU: 65 }
topologySpreadConstraints: zoneA cluster the way we hand it over.
What the clusters we hand over have.
- Everything as code. Cluster, node pools, namespaces, RBAC and add-ons in Terraform; workloads in Helm or Kustomize; both reviewed in pull requests. No
kubectl applyfrom a laptop into production. - Small, reproducible images. Multi-stage Dockerfiles, distroless or slim bases, non-root users, pinned digests and an SBOM per build. Images are scanned in CI and signed before a cluster will admit them.
- Requests and limits on every pod, with memory limits equal to requests so the scheduler’s picture matches reality. Vertical recommendations reviewed regularly, at a rhythm agreed with you; nobody guesses capacity.
- Probes that tell the truth. Readiness reflects real dependencies, liveness reflects only the process, and startup probes cover slow JVMs — because a wrong probe turns a slow database into a restart storm.
- Observability from the first deploy: OpenTelemetry traces, Prometheus metrics and structured logs shipped by default, with SLO dashboards and alerting on symptoms users feel.
- Network policy default-deny per namespace, secrets from a vault or the cloud’s secret manager via CSI, and admission policies that reject privileged pods and unsigned images.
- Disruption budgets, spread constraints and rehearsed node drains — a cluster upgrade or a spot reclaim is routine, tested in staging on the same versions first.
- A runbook and a cost report. Upgrade, rollback, scale, restore and on-call procedures in writing; per-namespace cost visible from the first deploy so rightsizing is a habit, not a project.
What usually ships alongside the cluster.
- Terraform modules for the cluster and its landing zone, with a documented environment promotion path
- A base Helm chart and Dockerfile templates for each language your teams use
- CI pipelines that build, test, scan, sign and publish images, and an ArgoCD application set that deploys them
- Grafana dashboards, alert rules and SLO definitions exported as code
- Load-test results that established the autoscaling thresholds
- Runbooks for upgrades, rollback, incident response and disaster recovery, rehearsed in a game day with your team
Frequently asked questions
Neighbouring stacks and the services that use them.
Want deploys to be the least interesting event of the day?
Tell us how many services you run and how you deploy them today. A Kubernetes engineer reads it and replies in writing with how we would approach it.