Skip to content

Cloud & Infrastructure

Kubernetes Consulting & Engineering

Most teams adopting Kubernetes do not need it. We will start by testing whether you are one of them, and we build the platform properly for the minority who genuinely are.

Overview

Let us put the important thing first, because it is the thing a consultancy is least likely to tell you: most teams that adopt Kubernetes do not need it. They need a way to run a handful of containers reliably, deploy without downtime, and scale a bit under load. Amazon ECS with Fargate, Google Cloud Run, Azure Container Apps, a platform-as-a-service, or two well-configured virtual machines behind a load balancer will all do that, at a fraction of the cost, with a fraction of the concepts, and without acquiring a standing operational commitment that has to be staffed for as long as the system exists. Kubernetes is excellent technology. It is also the most over-adopted infrastructure choice of the last decade, and a great deal of the pain attributed to it is really the pain of having chosen it too early.

With that said, here is what it actually is. Kubernetes is a container orchestrator built on a single idea: you declare the state you want, and control loops work continuously to make reality match. This many replicas of this image, exposed on this port, with these resource requests, these configuration values and these secrets. If a container crashes, it is replaced. If a node dies, its workloads are rescheduled elsewhere. If demand rises and the autoscaler is configured, replicas appear, and nodes appear underneath them. You never issue an instruction to do a thing. You state what should be true, and controllers spend their lives closing the gap. Once that distinction lands, you are operating the platform. Until it lands, you are fighting it.

The core objects are worth naming because they are the vocabulary of everything else. Pods are one or more containers scheduled together and sharing a network namespace. Deployments manage replica sets and handle rolling updates. Services give a stable network identity in front of pods that are individually ephemeral. Ingress or Gateway resources route external HTTP traffic in and terminate TLS. ConfigMaps and Secrets keep configuration and credentials out of images. StatefulSets, PersistentVolumes and StorageClasses handle workloads that must remember something. On top of all that, custom resource definitions and the operator pattern let you teach the same reconcile loop about your own domain, so that operational knowledge about running a database or rotating a certificate lives in software that runs on every loop rather than in a runbook that runs when somebody remembers it.

The reason Kubernetes won is genuine. It is a common, portable substrate that behaves the same way on EKS, GKE, AKS, OpenShift and hardware in your own building, with an enormous ecosystem and a large pool of engineers who know it. For an organisation running many services across many teams, it replaces a sprawl of bespoke deployment scripts and cron-driven glue with one declarative model everyone can read. That consistency is worth a great deal at a certain size. The mistake is assuming the benefit arrives at every size, when in fact below a certain threshold you are paying the full complexity cost for a consistency problem you do not yet have.

So a large share of our Kubernetes work begins with a question rather than a design: should you be running this at all. We look at how many services you have, how independently they need to deploy, what your traffic actually does across a week, how many engineers you have and whether any of them will own the platform, and what your availability requirement genuinely is rather than what it aspires to be. Sometimes the answer is a managed container service and a considerably smaller bill. Sometimes it is Kubernetes on a managed control plane, built properly and handed over to a team equipped to run it. We are equally happy delivering either, and refusing to sell the complex answer when the simple one fits is not a marketing position, it is the whole point.

Best for: Organisations running many independently deployed services at real scale, or with a genuine multi-environment portability requirement, and with somebody who will own the platform underneath.

Why teams choose Kubernetes

  • Self-healing that genuinely works

    The control loop restarts failed containers, reschedules workloads off dead nodes and holds the declared replica count without anybody being paged. A whole category of three in the morning incident becomes a graph you look at the next day. This is the benefit that is real and immediate, and the one people correctly get excited about.

  • One consistent model instead of many scripts

    At a certain number of services, the alternative to Kubernetes is not simplicity, it is a collection of bespoke deployment scripts, cron jobs and conventions that only their authors understand. Replacing that with one declarative model every team can read is worth a great deal, and it is the point at which the complexity starts paying for itself rather than costing.

  • Portability that is actually exercised

    The same manifests run on EKS, GKE, AKS, OpenShift and your own hardware. For organisations with a real reason to move workloads, a residency requirement, an acquisition, a customer contract, this is a genuine capability rather than theoretical insurance, and it is one of the few things no simpler platform can offer.

  • Scaling and rollouts as configuration

    Horizontal autoscaling, rolling updates, canary and blue-green deployments, pod disruption budgets and automatic rollback on failed health checks are settings rather than scripts. Once configured properly they behave the same for every service, which is what stops each team writing its own subtly different and subtly broken version.

  • A self-service platform for product teams

    Namespaces with quotas, role-based access, standard manifests and a continuous delivery path give product teams somewhere to ship without filing tickets or learning infrastructure. The value here is organisational rather than technical, and it is one of the more defensible reasons to adopt Kubernetes at scale.

Why businesses choose Kubernetes

  • Because you genuinely have many services, and one consistent declarative model is now cheaper than the pile of bespoke deployment scripts you would otherwise maintain.
  • Because self-healing and autoscaling turn a class of incidents into non-events, which is worth real money once availability is a business requirement rather than an aspiration.
  • Because you have a concrete portability requirement across clouds or into your own hardware, and you would rather pay for it in a platform you control than in a migration you did not plan.
  • Because multiple teams need to ship independently onto shared infrastructure, with guardrails and boundaries that hold, and you would rather build a paved road once than arbitrate every deployment.
  • Because you want somebody to test that reasoning honestly before you commit, and to tell you if a managed container service would serve you better. That conversation costs very little and saves a great deal.

What we build with Kubernetes

The capabilities this technology is genuinely strong at, and what we most often build with it.

  • Declarative desired state and GitOps

    The whole platform described as versioned manifests and reconciled continuously from a repository, so git is the source of truth and the cluster converges towards it. Changes are reviewed as code, drift is detected rather than discovered, and rolling back is a revert. This is the working model that makes a cluster maintainable by a team rather than by whoever last ran a command.

  • Deployments and rollout strategies

    Rolling updates by default, with canary or blue-green where a release needs a safer path, surge and unavailability limits set deliberately, and automatic rollback when readiness probes fail. Pod disruption budgets keep a node drain from taking a service below its minimum. This only works if health checks are honest, which is why we spend real time on probes rather than accepting whatever the template shipped with.

  • Requests, limits and autoscaling

    Every container declares what it is guaranteed and what it may not exceed, and the scheduler bin-packs pods onto nodes based on those requests. The horizontal pod autoscaler adds replicas on CPU, memory or custom metrics such as queue depth, and the cluster autoscaler adds nodes underneath. Getting requests right is the single largest cost lever in a cluster, and getting the scaling metric right is the difference between absorbing a spike and thrashing expensively.

  • Networking, ingress and service mesh

    Stable service discovery in front of ephemeral pods, ingress or Gateway API for HTTP routing and TLS termination, and a CNI plugin providing the pod network. A service mesh adds mutual TLS, fine-grained traffic shifting and per-service telemetry, and it also adds a substantial amount of machinery: we recommend one when the requirement is specific, and advise against it when it is being adopted because it is the next thing on the list.

  • Namespaces, RBAC and multi-tenancy

    Namespaces with resource quotas and limit ranges so one team cannot consume the cluster, role-based access scoped tightly to what each identity needs, and admission policy enforcing standards centrally rather than by convention. This is how a shared cluster stays shared rather than becoming a source of arguments, and it is much easier to establish at the start than to retrofit.

  • Config, secrets and external secret stores

    Configuration in ConfigMaps and credentials kept out of images, with secrets sourced from a managed store and injected at runtime rather than committed to a repository. Kubernetes Secrets are base64 encoded rather than encrypted by default, which surprises people, so encryption at rest and an external store are part of a serious setup rather than an enhancement.

  • Persistent storage and StatefulSets

    StorageClasses, dynamic provisioning, persistent volume claims and StatefulSets for workloads that must remember something, with backup and restore designed and rehearsed rather than assumed. We are deliberately conservative here and will often recommend that data lives in a managed service outside the cluster, because the consequence of getting this wrong is not an outage.

  • Operators and custom resources

    Custom controllers that manage complex systems, databases, brokers, certificates, by the same reconcile-to-desired-state loop, encoding failover, backup and upgrade as software. Mature operators are genuinely valuable. Immature ones are a new dependency with its own bugs sitting underneath your most critical data, so we choose them carefully rather than enthusiastically.

  • Observability and cluster cost visibility

    Metrics, logs and traces wired in before the first real workload lands, dashboards aimed at the questions people ask during an incident, and alerting tuned to symptoms a human should act on. Alongside that, cost attribution by namespace and workload, because a cluster with no visibility into which team is consuming what is a cluster where nobody can act on the bill.

Use cases

  • A microservices estate that has outgrown its scripts

    An organisation with dozens of services, each with its own deployment script, its own conventions and its own way of failing, where onboarding a new service means copying something and hoping. Kubernetes replaces that with one model, one set of guardrails and one paved road. This is the canonical case where the complexity genuinely pays, and it is defined by the number of services and teams rather than by traffic volume.

  • An internal developer platform

    A self-service layer where product teams deploy to standard manifests, a shared continuous delivery pipeline and sensible defaults, without each team reinventing infrastructure or filing a ticket to release. The value is organisational: it turns platform engineering into a product with users rather than a queue of requests.

  • Genuine hybrid and multi-environment requirements

    A platform that must run identically in a cloud and in your own building, or across two clouds, because of data residency, regulation, an acquisition or a customer contract. Kubernetes is one of the very few things that makes this tractable, and it is the strongest single argument for it.

  • Bursty batch and queue-driven workloads

    Jobs that need a great deal of capacity briefly and nothing the rest of the time, or consumers that should scale on queue depth rather than CPU. Kubernetes handles this shape well with jobs, cron jobs, custom autoscaling metrics and node pools that scale to zero, and it can be substantially cheaper than keeping capacity warm.

  • Rescuing a cluster that was set up and then abandoned

    Frequent, and rarely spoken about. A cluster built during an enthusiastic quarter, running an unsupported version, with manifests applied by hand and no record of why, permissions granted broadly to make something work, and nobody currently responsible. The work is to make it legible, get it to a supported version safely, bring the workloads under version control, and then have an honest conversation about whether it should continue to exist at all.

  • Deciding against Kubernetes, deliberately

    A genuine outcome of our engagements and worth listing as one. A team preparing to adopt Kubernetes, where the assessment shows a managed container service meets every requirement at a fraction of the operating cost. The deliverable is the written reasoning, the alternative design and the migration path, and it is often the most valuable thing we produce all year.

When Kubernetes is the right choice

  • Right when you genuinely run many services, on the order of dozens rather than a handful, that need to deploy independently, scale independently and fail independently. This is the condition that actually justifies Kubernetes, and the one most often assumed rather than met.
  • Right when several teams ship to the same infrastructure and you need a paved road: shared conventions, guardrails, namespaces with quotas and role-based access, so teams move fast without reinventing deployment or reaching into each other’s workloads.
  • Right when you have a hard requirement for the same platform to run identically across clouds, or across cloud and your own hardware, whether that is driven by data residency, an acquisition, a regulator or a customer contract. Portability is one of the few things Kubernetes offers that alternatives genuinely cannot.
  • Right when workloads are bursty or batch-heavy in a way that a simpler platform handles badly: jobs that need a hundred pods for twenty minutes and nothing for the rest of the day, or queue-driven work that should scale on queue depth rather than CPU.
  • Right when you will encode real operational knowledge as software. If the operator pattern lets you turn failover, backup and upgrade procedures into controllers rather than wiki pages, that is a durable asset that survives the person who wrote it.
  • Right when you have, or are willing to fund, somebody who owns the platform. Not as a side responsibility. Kubernetes assumes an engineering function exists to run it, and that assumption is the real cost of entry.
  • Wrong for one application, or five, with modest traffic and a small team. A managed container service, a platform-as-a-service or a couple of well-run virtual machines will be cheaper, simpler, more reliable for you, and far easier to hand to the next engineer. This describes most teams considering Kubernetes.
  • Wrong when nobody will own it. An unowned cluster does not stay still, it decays: upgrades are deferred until the version is unsupported, certificates expire, resource requests drift from reality, and the first real incident finds nobody who understands the networking. This is the fastest way to turn infrastructure into a liability.
  • Wrong when the real driver is hiring, fashion or a slide. Adopting Kubernetes to look like a serious engineering organisation is a decision your engineers pay for every week, and it does not survive contact with an on-call rota.

Kubernetes: pros and cons

Strengths

  • The industry standard orchestrator, with managed control planes on every major cloud and an ecosystem covering ingress, service mesh, secrets, observability, policy and delivery.
  • Genuine self-healing, horizontal and cluster autoscaling, and zero-downtime rollouts with automatic rollback, once the platform is configured correctly and health checks tell the truth.
  • Vendor-neutral and portable in a way that actually holds up: the same primitives behave the same across clouds and on your own hardware.
  • The operator pattern and custom resources let you extend the reconcile model to your own systems, turning operational procedures into version-controlled software.
  • A large, well-documented ecosystem and a deep hiring pool, so you are not depending on knowledge that exists in one person or one vendor.
  • Strong multi-tenancy primitives, namespaces, quotas, role-based access control and network policy, which make it viable to run many teams on shared infrastructure with real boundaries between them.

Trade-offs

  • It is frequently massive over-engineering, and this belongs at the top of the list rather than buried. For a large share of the teams that adopt it, a managed container service or plain virtual machines would have been cheaper, more reliable and easier to hand over. The complexity is permanent, it is paid weekly, and it is very rarely reversed once production depends on it.
  • The operational burden is a standing cost, not a setup cost. Control plane and node upgrades on a cycle you do not control, deprecated APIs that break manifests between versions, certificate rotation, ingress controller and add-on upgrades, and a steady stream of ecosystem components that each have their own release cadence. This work never finishes, and it needs an owner.
  • The learning curve is genuinely steep and the concept count is high. Networking alone spans services, ingress, CNI plugins, network policy, DNS and possibly a service mesh, and each has its own failure modes. A team that is competent everywhere else can still spend months being unproductive here.
  • Debugging is harder than on a simpler platform, because there are more layers between a user’s request and the process serving it. A pod that will not start might be an image pull failure, a resource request no node can satisfy, a failing readiness probe, a missing secret, a node taint, a storage class that cannot provision, or a network policy blocking something it should not. Working through that list is a skill in itself.
  • Stateful workloads are markedly harder than stateless ones, and the failure mode is data loss rather than downtime. StatefulSets, persistent volumes, storage classes, backup and failover all have to be designed rather than assumed, and operators reduce the work without removing the responsibility.
  • Clusters are almost always over-provisioned, and it is expensive. Resource requests set generously at the start and never revisited mean the scheduler reserves capacity that nothing uses, so you pay for a fleet sized to guesses. In most clusters we inherit, a substantial share of the compute bill is reserved headroom that has never been touched.
  • The defaults are permissive because they optimise for getting started. A pod network with no policy is flat and wide open, service accounts are more capable than most workloads need, and nothing stops a container running privileged or as root until you configure something that does.

The control plane and the reconcile loop

A cluster is a control plane governing a set of worker nodes. The control plane holds the API server, which is the single front door and the source of truth, backed by etcd; the scheduler, which decides which node each pod lands on based on resource requests, affinities and taints; and a set of controllers that each watch for a difference between declared and actual state and act to close it. On each node sits a kubelet that ensures the containers it has been assigned are running, and a network proxy handling service routing. Everything else, including most of the ecosystem, is built on the same pattern: watch the API, compare, reconcile.

That reconcile loop is the whole idea, and understanding it changes how you operate. You do not tell Kubernetes to restart a service, you change what should be true and controllers make it so. It explains why a manual change to a running resource is quietly reverted, why deleting a pod produces a new one, and why the right debugging question is usually not "what happened" but "what does the cluster currently believe should be true, and which controller disagrees". Teams that internalise this find Kubernetes predictable. Teams that do not find it capricious.

We design clusters around blast radius and ownership rather than around features. Namespaces divide the cluster along team or workload lines, with resource quotas so one namespace cannot consume everything and role-based access so identities can only reach what they should. Network policy is default-deny, because the out-of-the-box pod network is flat and any pod can reach any other. Node pools separate workloads with different profiles, so a batch job cannot evict a latency-sensitive service, and taints and tolerations keep that separation deliberate rather than accidental.

On the control plane itself, our recommendation is almost always a managed offering. EKS, GKE and AKS run the API server and etcd for you, which removes an entire category of thankless, high-consequence work: etcd backup and compaction, control plane availability, control plane upgrades. You still own workloads, networking, security, storage and cost, which is more than enough. Self-managed or bare-metal Kubernetes is justified by specific requirements, particular hardware, air-gapped environments, a residency position no provider satisfies, and not by a preference for control.

Stateless workloads are treated as disposable and scaled freely. Stateful ones get deliberate design: storage class, backup, restore rehearsal, failover behaviour, and a clear-eyed decision about whether they belong in the cluster at all. For a great many systems the right architecture is stateless workloads on Kubernetes talking to managed data services outside it, and we recommend exactly that more often than not.

Scheduling, resource requests and the cost of guessing

Kubernetes performance is mostly a resource management story, and it begins with requests and limits. A request is what the scheduler reserves for a container and is the number that determines where it lands and how much of your fleet is committed. A limit is the ceiling it may not exceed. Set requests too high and you pay for reserved capacity nothing uses, across every replica of every service, permanently. Set them too low and pods are throttled on CPU or evicted on memory under exactly the load where you needed them. Both mistakes are common and both are invisible without measurement.

So we size from observed behaviour rather than from a guess made when the service was new, and we revisit it, because workloads change and nobody goes back to the numbers unprompted. In most clusters we inherit, requests are set generously and a substantial share of the compute bill is headroom that has never been touched. Correcting that is usually the largest single cost improvement available, and it is straightforward once there is data. It is worth knowing that CPU limits in particular can cause throttling that looks like an application performance problem, which sends teams optimising code that was never slow.

Above the pod, the horizontal pod autoscaler adds and removes replicas and the cluster autoscaler adds and removes nodes underneath. Tuned together with sensible readiness probes, pod disruption budgets and anti-affinity rules, the platform absorbs traffic spikes and node failures without intervention and without running peak capacity around the clock. The failure mode to avoid is autoscaling on a metric that does not actually track load, which produces thrashing: scaling up, scaling down, and paying for both. For queue consumers, queue depth is almost always a better signal than CPU, and we validate the signal before trusting it with the bill.

Two effects catch people out and are worth naming. Scheduling latency: a pod that needs a new node waits for that node to be provisioned and to join, which can be minutes, so a cluster with no warm capacity responds to a spike more slowly than the autoscaler graph suggests. And startup time: an image that takes ninety seconds to pull and an application that takes a further sixty to warm up means your scaling response is two and a half minutes regardless of configuration, which brings the problem right back to image size and start-up work.

Permissive by default, and what to do about it

Kubernetes is secure when it is configured to be, and its defaults are permissive because they optimise for a cluster that works on the first try. The pod network is flat, so any pod can reach any other pod and most cluster services. Service accounts are mounted into pods automatically. Nothing prevents a container running privileged, as root, or with host paths mounted, until you configure something that does. None of this is a flaw in the design, but it does mean a cluster that has not been hardened is considerably more open than most teams assume.

We close that in layers. Role-based access control scoped to least privilege, for humans federated to your identity provider and for workloads through service accounts that can do only what they must, with cluster-admin treated as an exception rather than a convenience. Network policy default-deny, so pods reach only the peers they are explicitly permitted to, which converts a flat network into a set of deliberate paths and dramatically limits what a compromised workload can explore. Pod security standards and admission policy to keep privileged containers, host mounts and root users out, enforced centrally rather than relying on every team remembering.

Then the supply chain and secrets. Images are scanned in the pipeline and pulled from trusted registries, referenced by digest so what runs is what was reviewed. Secrets come from a managed external store injected at runtime, because Kubernetes Secrets are base64 encoded rather than encrypted by default and are readable by anyone with the right access to the API or to etcd; encryption at rest for etcd is a baseline rather than an enhancement. Control plane and node access is locked down, and audit logging is enabled and retained so an incident can be reconstructed rather than reasoned about from memory.

The part that is easy to defer and expensive to defer is upgrades. Kubernetes moves quickly, versions fall out of support on a schedule you do not control, and deprecated APIs break manifests between releases. A cluster that is two versions behind is not merely missing features, it is missing security fixes and is progressively harder to upgrade because the gap compounds. A regular, rehearsed upgrade cadence is part of running Kubernetes securely, and the absence of one is the clearest sign that a cluster has no owner.

One boundary worth stating: none of this substitutes for an independent assessment or a formal certification, which need a qualified assessor rather than the team that built the platform. What it gives you is a posture that is consistent, evidenced and defensible, which is what an auditor or an enterprise security review is actually asking for.

Scaling out, and the human cost nobody prices in

Horizontal scaling is where Kubernetes is genuinely strong, and this is not in dispute. Stateless services scale to very large replica counts across a growing node pool with little more than a configuration change. Rollouts happen without downtime. Failed nodes are drained and replaced without anybody touching a keyboard. Node pools with different instance types let you place workloads where they belong, and pools that scale to zero make bursty batch work cost almost nothing when idle. For systems that must grow elastically and stay available while they do, this is precisely what you are buying and it works.

Statefulness is where the honesty has to come in. Databases, queues and anything holding data are markedly harder on Kubernetes than stateless services. Persistent volumes are usually zone-bound, which constrains where a pod can be rescheduled and quietly limits your failover story. StatefulSets give ordering and stable identity but not a backup strategy. Operators encode a great deal of expertise and are genuinely useful, but they introduce a dependency of their own directly underneath your most critical data. For most teams the right architecture is stateless workloads on Kubernetes talking to managed data services outside the cluster, and we will recommend that unless there is a specific reason not to.

There are also real ceilings worth planning around. etcd has practical limits on object count and churn, so a cluster accumulating many thousands of resources will feel it in API latency. Very large clusters need attention to control plane sizing and to how much the API server is being polled by add-ons. And the sensible answer beyond a certain scale is often more clusters rather than one enormous one, which brings its own set of questions about how you deploy consistently across them.

The cost that is almost never priced in is human. A Kubernetes platform assumes an engineering function to run it, permanently, and that is the largest line item over the life of the system by a wide margin. Upgrades on a schedule you do not control, add-ons with their own release cadences, security policy that has to be maintained, cost that has to be reviewed, and somebody on call who understands the networking. Before we scale anybody onto Kubernetes, we make sure that ownership genuinely exists, because a cluster with no owner does not stay as it is. It quietly degrades until the first serious incident finds nobody who can help.

Kubernetes integrations & ecosystem

The technologies we most often pair with it. Each links to how we work with it.

How we deliver, starting with whether to

We start with the question most vendors skip, and we mean it. We look at how many services you run and how independently they deploy, what traffic actually does across a week rather than at its most flattering, how many engineers you have and whether any of them will own a platform, what your availability requirement genuinely is, and whether there is a real portability constraint or only a hypothetical one. Then we give a straight answer. Sometimes it is a managed container service such as ECS with Fargate or Cloud Run, which meets the requirement at a fraction of the operating cost. Sometimes it is Kubernetes on a managed control plane. We would much rather tell you the cheaper thing is right than sell you a platform you will resent operating in eighteen months.

Where Kubernetes is the answer, we default to a managed control plane so you are not maintaining etcd and an API server by hand, and we build the platform in code from the first day. Cluster, node pools and networking in Terraform or OpenTofu. Workloads as version-controlled manifests reconciled through GitOps, so the repository is the source of truth and a rollback is a revert. Role-based access and default-deny network policy in from the start rather than retrofitted, because retrofitting either one against running workloads is considerably harder than establishing it. Observability wired in before the first real workload lands, so you can see what the platform is doing rather than inferring it.

Migration is incremental and boring on purpose. Stateless services first, one at a time, with traffic shifted gradually and a route back. Stateful systems are designed deliberately or, more often, pointed at managed data services outside the cluster. We do not do big-bang cutovers onto a platform the team has not yet operated, because the point at which you learn Kubernetes should not be the point at which your production traffic depends on it.

Then we hand over properly, and this is the part we care most about. Runbooks written for somebody who did not build the platform, an upgrade procedure that has been rehearsed rather than described, cost attribution your team can read, and a walkthrough rather than a document drop. We would rather leave you self-sufficient than turn a cluster into a dependency on us, and if you want us to stay and operate it alongside you, that should be a decision you make freely.

The service behind it

Delivered throughCloud Engineering

What we build with Kubernetes

The disciplines this technology most often shows up in, from a first build to taking over and stabilising an existing one.

How we deliver

  1. 01

    Discover

    We map the system, the constraints and the business it serves, including the parts nobody documented.

    Architecture brief

  2. 02

    Architect

    Decisions get made, written down and defended before a line of production code exists.

    Decision records

  3. 03

    Build

    Short cycles against working software. You see progress in the product, not in a status deck.

    Shipping increments

  4. 04

    Operate

    Monitoring, incident response and iteration. The system is alive, so the engagement is too.

    Runbooks & SLOs

Weighing up Kubernetes?

A short call with engineers who build in it and operate the result. If Kubernetes is the wrong tool for what you are doing, we would rather tell you now than bill you later.

Industries we use Kubernetes in

Domain knowledge changes what gets built. A few of the sectors we know before the first meeting.

Also in Cloud & Infrastructure

Related terms

Kubernetes compared

Why teams choose us for Kubernetes

  • We will tell you not to use it

    A large share of Kubernetes projects should never have been Kubernetes projects, and we open every engagement by pressure-testing that assumption rather than by designing a cluster. Recommending the simpler, cheaper platform when it fits is the single most useful thing we do in this area, and we do it often.

  • We run what we build

    We operate Kubernetes in production ourselves, so our advice comes from upgrades that went sideways, pods that would not schedule at an inconvenient hour and bills that needed explaining. That experience is exactly why we are cautious about recommending it, and exactly why we build it properly when we do.

  • Senior engineers only

    Cluster design, networking, role-based access, storage and operators are unforgiving of inexperience, and the mistakes are the kind you find months later. The people architecting your platform are the ones who have run one before, not juniors learning on your infrastructure.

  • Handover, not dependency

    We build platforms your team can own: defined in code, documented in runnable form, with the upgrade path rehearsed together rather than described in a document. Ending the engagement should mean we stop working, not that something has to be untangled from us.

Typical timeline

  1. 01

    Assessment and decision

    One to two weeks reviewing workloads, traffic, team, ownership and constraints, ending in a straight answer on whether Kubernetes is the right platform and, if not, what is, with the alternative designed and costed. This is the phase that saves the most money, and it is a real deliverable rather than a preamble to a build.

  2. 02

    Platform build

    A managed cluster with node pools, networking and default-deny policy, role-based access federated to your identity provider, external secrets, admission policy, continuous delivery through GitOps and observability, all defined in code. The paved road your teams will deploy onto, established before anybody deploys onto it.

  3. 03

    Workload migration

    Services moved incrementally, stateless first, with traffic shifted gradually and a route back at every step. Stateful systems designed deliberately or pointed at managed data services outside the cluster. Health checks, resource requests and shutdown behaviour corrected as each workload lands rather than afterwards.

  4. 04

    Tune, rehearse and hand over

    Resource requests right-sized against observed usage, autoscaling validated against a metric that genuinely tracks load, an upgrade rehearsed rather than merely documented, security policy verified, cost attributed by namespace, and runbooks and access handed to a team equipped to own the platform.

How pricing works

  • A paid assessment first, and for Kubernetes this is genuinely the most valuable thing we sell. A fixed-scope review of your services, traffic, team, roadmap and constraints, ending in a written recommendation on whether Kubernetes is right for you and, if it is not, what is, with the alternative design and a rough comparison of what each would cost to operate. It stands alone as a deliverable, and it is where we save clients the most money, frequently by talking them out of the work.
  • Fixed-scope engagements for a defined build: a managed cluster with networking, role-based access, secrets, policy, continuous delivery and observability, plus a named set of workloads migrated onto it. Quoted once the assessment has established what is actually there, because estimating platform work without that is guesswork with a number attached.
  • A monthly senior engagement for the ongoing reality, which is the larger cost and the one most often underestimated. Upgrades on a supported cadence, add-on maintenance, cost and resource-request review, security policy, and senior hands available when something breaks. We are explicit that this standing load is the real expense of Kubernetes, and we would rather you saw it in a proposal than discovered it in a year.
  • Rescue and stabilisation for an inherited cluster: getting an unsupported version to a supported one safely, bringing hand-applied resources under version control, tightening permissions and policy in stages, and giving you an honest assessment of whether the cluster should continue to exist.
  • Your cloud bill is yours and is unmarked-up. The clusters run in accounts you own, the provider invoices you directly at their prices, and there is no reseller margin, no markup and no consumption commission anywhere in our arrangement. Third-party tooling and licences are bought on your accounts too. That matters more here than almost anywhere else, because it means we have no financial interest in you running a larger cluster than you need, which is precisely why we can open every engagement by asking whether you need one at all.

Hire Kubernetes engineers

Need Kubernetes capacity on your own team? We embed named senior engineers into your existing team (reporting to your leads, working in your rituals), so you add capacity without a hiring cycle.

Hire Kubernetes engineers

Common questions

Do we actually need Kubernetes?

Probably not, and we would rather say that plainly than lead you towards a design. If you run one to a few services with modest traffic and a small team, a managed container service such as ECS with Fargate, Cloud Run or Azure Container Apps, a platform-as-a-service, or a couple of well-run virtual machines behind a load balancer will be cheaper, simpler, more reliable for you and far easier to hand to the next engineer. Kubernetes earns its complexity when you have many services deploying independently, several teams sharing infrastructure, genuinely bursty or batch-heavy workloads, or a hard requirement to run identically across clouds or into your own hardware. The other condition is ownership: somebody has to run the platform, permanently, and if nobody will, the answer is no regardless of the technical fit. We start every engagement by testing this, and we are glad to talk you out of it.

What are the actual alternatives if we do not use it?

More than people assume, and they are good. Managed container services take an image and handle scheduling, health, scaling, rollouts and load balancing without you operating a cluster: ECS with Fargate on AWS, Cloud Run on Google Cloud, Azure Container Apps. These cover the requirements of most teams who think they need Kubernetes, and the operational difference is enormous. A platform-as-a-service such as Render, Fly.io or Vercel goes further and takes your code rather than your image, which suits teams who want to think about infrastructure as little as possible. And for a genuinely small system, one or two well-configured virtual machines with a process supervisor, a load balancer and tested backups is a legitimate production architecture rather than something to apologise for. The right answer is whichever meets your requirements with the least standing operational load.

Should we run our own cluster or use EKS, GKE or AKS?

Almost always a managed offering. EKS, GKE and AKS run the control plane for you, which removes a large, thankless and high-consequence class of work: etcd backup and compaction, API server availability, control plane upgrades. You still own workloads, networking, security, storage, upgrades of everything above the control plane, and cost, which is plenty to be getting on with. Self-managed or bare-metal Kubernetes is justified by a specific requirement the managed platforms cannot meet, such as particular hardware, an air-gapped environment or a data residency position no provider satisfies. It is not justified by a preference for control, because what you gain is control of the part you least want to be responsible for.

Can we run our databases on Kubernetes?

You can, and for most teams you should not. Stateful workloads are meaningfully harder than stateless ones and the failure mode is lost data rather than downtime. Persistent volumes are typically bound to an availability zone, which constrains rescheduling and quietly limits failover. StatefulSets give you ordering and stable identity but not a backup strategy. Operators encode real expertise and genuinely help, but they add a dependency with its own release cycle sitting directly under your most critical data. Our usual recommendation is stateless workloads on Kubernetes talking to managed data services outside the cluster, which removes the hardest part of the problem for a modest cost. Where a database genuinely belongs in-cluster, we use a mature operator, design storage and recovery deliberately, and rehearse a restore before anyone relies on it.

What does Kubernetes really cost to run over time?

Considerably more than the compute bill, and the gap is the part people underestimate. The compute itself is usually over-provisioned, because resource requests are set generously at the start and never revisited, so the scheduler reserves capacity nothing uses across every replica of every service. On top of that sit control plane charges, load balancers, and the ecosystem add-ons that each need maintaining. But the dominant cost is human: somebody owning upgrades on a cycle you do not control, add-on maintenance, security policy, cost review and incidents. That standing engineering load is the real price of admission, it does not decrease once the platform is built, and it is why an unowned cluster becomes a liability. We size honestly, tune requests and autoscaling to real usage, and factor the human cost into the recommendation, including telling you when a simpler platform would cost far less across the life of the system.

How long does it take a team to become productive with Kubernetes?

Longer than the proof of concept suggests, and that gap is where projects get into trouble. Getting a service running on a cluster takes an afternoon. Becoming genuinely comfortable, being able to diagnose why a pod will not schedule, understanding why a network policy is blocking something, knowing what a readiness probe failure means, handling an upgrade without anxiety, takes months of real exposure for a capable team. We plan for that rather than pretending otherwise: we build the paved road so the common path is simple, migrate incrementally so the learning happens while the stakes are low, and rehearse the operational procedures with your engineers rather than writing them down and leaving. The teams that struggle are the ones who went to production on day one and started learning during their first incident.

How do you keep a cluster secure?

In layers, because the defaults are permissive by design. Role-based access scoped to least privilege, with human access federated to your identity provider and cluster-admin treated as an exception. Network policy default-deny, because the pod network is otherwise flat and any pod can reach any other. Pod security standards and admission policy keeping workloads from running privileged, as root or with host mounts, enforced centrally rather than by convention. Images scanned in the pipeline and referenced by digest. Secrets from a managed external store injected at runtime, since Kubernetes Secrets are base64 encoded rather than encrypted by default, with etcd encryption at rest as a baseline. Control plane and node access locked down and audit logging retained. And regular upgrades, because a cluster two versions behind is missing security fixes and gets harder to move with every release that passes.

We have inherited a cluster nobody understands. What now?

This is common and it is fixable, though the first step is not a redesign. We establish what is actually running and how it got there, which usually means finding resources applied by hand with no record, and we get the current state into version control so the cluster becomes reviewable. Then we assess the version gap, because an unsupported cluster is the most urgent problem and upgrading gets harder the longer it waits, and we plan a rehearsed upgrade path rather than an optimistic one. Permissions and network policy are tightened in stages using real usage data, since a single aggressive pass tends to break something undocumented and get reverted wholesale. And we give you an honest assessment of whether the cluster should exist at all, because a fair number of inherited clusters are running three services that would be happier and cheaper on a managed container service.

Will Kubernetes make our deployments faster or more reliable?

More reliable, usually yes, once it is configured properly: rolling updates with automatic rollback on failed health checks, pod disruption budgets, and self-healing genuinely remove a class of deployment incidents. Faster is a different question, and the honest answer is not necessarily. Kubernetes adds steps between a commit and a running container, and the deployment itself is gated by image pull time, readiness probe timing and rollout strategy. Teams that see deployments get faster usually improved their pipeline and their images at the same time, and would have seen much of that benefit on a simpler platform. If deployment speed is the problem you are solving, we would look at your build and your image before we looked at your orchestrator.

Building on Kubernetes?

Tell us what you are building and where it is stuck. A senior engineer reads it and gives you an honest read on whether Kubernetes is the right fit for the problem, or what we would reach for instead.

  1. 01A senior engineer reads it. Not a form queue, and not an account manager.
  2. 02We reply either with questions or with a straight answer that we are not the right fit.
  3. 03If it looks like a fit, a technical call with the person who would actually run the delivery.
  4. 04Then scope, effort and risk in writing, before anyone signs anything.

Two fields required. We reply to real enquiries. No list, no sequence.