Kubernetes high availability

Kubernetes high availability depends on a three or more node control plane, a load balancer in front of the API server, an etcd topology you can operate, and nodes spread across failure domains. This page covers the decisions, build sequence and verification.

On this page

Kubernetes high availability starts with the control plane, not the worker nodes

A cluster with a single control plane node has a single point of failure for the Kubernetes API, scheduling and cluster state, even when your workloads are spread across dozens of worker nodes. If that one control plane machine stops, existing pods may keep running for a while, but nothing can be created, updated, scaled or rescheduled, and controllers cannot react to failures. High availability therefore begins with the control plane. Adding more workers improves capacity and tolerance for individual worker loss, but it does not protect the API or the state that the cluster depends on.

The standard kubeadm topology uses at least three control plane nodes, each running kube-apiserver, kube-controller-manager and kube-scheduler, with a TCP load balancer in front of the API servers on port 6443. Clients and kubelets talk to the load balancer address, not to any single node. You also choose where etcd runs. In the stacked topology, etcd members share the control plane nodes. In the external topology, etcd runs on its own nodes, which separates their failure and scaling. Kubernetes documentation says etcd should have an odd number of members and recommends five members in production, so a majority can still form after losing members. Confirm the member count, topology and load balancer design against the kubeadm high availability guide and your own failure assumptions before you buy hardware.

The control plane is harder to make highly available than it looks. etcd quorum is the first constraint: with five members, the cluster tolerates two member failures, but losing a majority halts writes, and a placement that puts two members in one rack or zone can lose quorum from a single event. Certificates are the second. Each API server certificate must include the load balancer name and every node address that clients or peers use, and certificate renewal, kubelet client certificates and etcd peer certificates must be handled consistently on every node. The third is load balancer health checks. A check that only tests TCP connectivity can keep sending traffic to an API server that is running but unhealthy, so decide which health endpoint to use and test failover by stopping a node during a maintenance window.

Which etcd topology and control plane layout fits your environment

This table compares the main etcd topology, control plane size and load balancer options for a highly available cluster, with the operational cost of each. Read each row against your own failure domains, patching model and backup process, because the cheaper option to build is often the more expensive one to run. Whichever layout you choose, the kubeadm guide requires at least three control plane nodes.

DecisionWhat it meansOperational costWhen it fits
Stacked etcdetcd members run on the same nodes as kube-apiserver, kube-controller-manager and kube-scheduler, the kubeadm default layoutOne set of hosts to patch, monitor and back up; losing a control plane node also removes an etcd memberSmaller estates with limited hosts and a team that wants one node type to operate
External etcdetcd runs as a separate cluster on dedicated hosts, and the API servers connect to it over the networkSeparate hosts to patch, monitor and secure, plus a separate etcd backup path and certificate setTeams that want control plane failures and etcd maintenance decoupled, and can staff the extra hosts
Three control plane membersThree nodes, tolerating the loss of one member while keeping quorumLowest host count that meets the kubeadm minimum; upgrades and node replacements leave less margin during maintenanceClusters spread across three failure domains such as racks or availability zones with low change pressure
Five control plane membersFive members, tolerating the loss of two while keeping quorum; Kubernetes documentation recommends five etcd members in productionMore hosts to patch and monitor, and more replication traffic; each added member increases coordination workLarger or regulated estates that need more failure tolerance and can staff the extra nodes and monitoring
Managed or vendor load balancerA cloud or appliance load balancer in front of the API servers on TCP port 6443Provider handles availability of the balancer; you still verify health checks, certificates and failover behaviorEnvironments where the provider already operates load balancing with support you trust
Self-run load balancerA software or hardware balancer you deploy and operate, such as a pair of HAProxy or keepalived nodesYou patch, monitor and fail over the balancer itself, which becomes a control plane dependencyPrivate or air-gapped data centers without a suitable managed balancer, where the team already runs this tooling

How stacked and external etcd fail differently

The main difference between the two kubeadm high availability topologies is what a failed machine takes with it. In a stacked design, each control plane node runs kube-apiserver, kube-controller-manager, kube-scheduler and an etcd member together. Losing one node removes a control plane instance and an etcd member at the same moment. In an external design, etcd runs on its own three or more nodes, separate from the control plane. Losing a control plane node removes an API server, controller manager and scheduler instance, but etcd keeps its full membership and the data path stays intact. Before choosing, write down which failures you need to survive and whether the two should be coupled.

Start with the odd member count, because it determines how many failures the cluster can absorb. etcd uses majority voting, so a write needs agreement from more than half of the members. Three members tolerate one loss, five tolerate two. An even count adds cost without adding tolerance: four members still tolerate only one failure, the same as three. Kubernetes documentation calls for an odd number of etcd members and recommends five in production. Confirm the exact quorum and member-change behavior for the etcd version you plan to run, since the documentation for each release describes it in detail.

When you lose one member of a three-member etcd cluster, the cluster keeps quorum. The API server keeps serving reads and writes, and controllers keep reconciling. In a stacked design, that same loss also removes one API server endpoint behind the load balancer, so the load balancer must fail health checks on port 6443 quickly enough that clients are redirected. Losing a second member in a three-member cluster breaks quorum. etcd then stops accepting writes, the API server cannot persist changes, and controllers cannot update objects. In a stacked design, two control plane nodes are gone, so you have also lost most of your API capacity. Plan a runbook for restoring members and confirm how your version reports quorum loss through etcdctl endpoint health.

A whole zone failure tests the placement decision. If a three-member stacked cluster has one control plane node per zone, losing a zone is the same as losing one member, and quorum survives. If two nodes sit in one zone, a single zone outage breaks quorum. External etcd lets you place etcd members across zones independently of control plane nodes, but it does not fix a bad layout. Three etcd members in two zones still fail when the zone holding two members goes down. Map every member to a failure domain on paper before provisioning, and ask your infrastructure team to confirm that zone labels and anti-affinity match that map.

Restoring a cluster after quorum is lost is a different job from routine failover. Recovery usually means restoring from an etcd snapshot taken with etcdctl snapshot save and restoring it with etcdutl, which is why backup schedules and restore drills belong in your planning, as covered in the etcd backup and disaster recovery section. Stacked clusters also require you to rebuild the control plane components on replacement nodes, while external clusters let you replace etcd members and control plane nodes separately. Ask your team to rehearse each scenario in a staging cluster and record how long their own runbook takes, rather than relying on general estimates.

Build sequence for a highly available control plane with kubeadm

This sequence takes a set of machines from a planned network layout to a kubeadm control plane where every API server answers through one stable endpoint and each control plane node reports Ready. It also shows where etcd fits in the chosen topology and which check confirms each stage before the next one starts.

  1. Plan addresses and the API endpoint name

    Before any node is built, record the subnet, the addresses for each control plane node, the load balancer virtual address and a DNS name that clients and kubeconfigs will use for the API endpoint. Confirm with your network team which failure domains (racks, hypervisor hosts or availability zones) each node will sit in, and decide whether etcd runs stacked on the control plane nodes or as a separate external cluster. The step is done when this plan is written down and the DNS record is reserved and resolves to the planned load balancer address.

  2. Provision three or more control plane nodes

    Create at least three control plane nodes, placed across distinct failure domains so that losing one rack, host or zone does not remove quorum. The infrastructure or platform team builds the machines with consistent OS, time synchronization, container runtime and kubelet versions. Confirm that the nodes can reach each other on the required ports and that the chosen topology matches the plan. The step closes when every node passes basic connectivity and time checks and reports the same planned versions.

  3. Configure the TCP load balancer on port 6443

    Place a TCP load balancer in front of kube-apiserver on port 6443, with the virtual address and DNS name from the plan. Add a health check against each control plane node so that a failed API server is removed from rotation automatically. The load balancer should pass TLS through rather than terminate it, because the API server certificates must match the endpoint name. The step is verified when the load balancer lists every control plane backend and reports each one healthy once kube-apiserver is running on it.

  4. Prepare control plane images for restricted networks

    If the nodes cannot reach public registries, run kubeadm config images list to get the exact control plane image names and versions for the target release, then pull them into a private registry that the nodes can reach. Point kubeadm at that registry with the --image-repository option during initialization. On connected networks this step can be shorter, but the same list still confirms which images each node will need. The step closes when every listed image is present in the registry and a pull test succeeds from a control plane node.

  5. Initialize the first control plane node

    Run kubeadm init on the first control plane node with the stable endpoint set as the control plane endpoint, so every later join uses the load balancer name rather than a single node address. Include the certificate key option if other control plane nodes will join with certificates uploaded to the cluster. Save the join commands securely, since they contain tokens and keys. The step is done when kubectl on that node returns a response from the API server through the load balancer endpoint and the first node appears in kubectl get nodes.

  6. Join the remaining control plane nodes

    Join each remaining control plane node with the control plane join command, one node at a time, so that each new member finishes before the next starts. Confirm that each node receives its certificates and etcd membership if stacked etcd is used. Keep the cluster certificate key handling under the same controls as other secrets. The step closes with kubectl get nodes showing all control plane nodes Ready, and with the load balancer returning healthy backends for every API server.

  7. Add or verify the external etcd cluster

    If the external etcd topology was chosen, build a separate etcd cluster with an odd number of members, normally three for a minimum and five in production according to Kubernetes guidance, and point the kubeadm configuration at its endpoints and client certificates before initialization. If stacked etcd is used, verify the etcd members that kubeadm created on the control plane nodes instead. The step is done when the etcd member list shows the expected number of members, all healthy and with one leader, and when the API server can read and write cluster state through the endpoint. Confirm backup procedures for etcd before the cluster carries workloads.

Spreading control plane and worker nodes across failure domains

Placing three control plane nodes in three different zones or racks is the decision that gives a Kubernetes cluster zone-level resilience. Three members in one zone satisfy the quorum arithmetic on paper, but a single zone outage, a top-of-rack switch failure or a shared hypervisor fault takes all of them down together. The etcd members that back the cluster need an odd count so a majority can survive, and that majority only helps if the members are not all behind the same point of failure. For a stacked topology, each kube-apiserver, kube-controller-manager, kube-scheduler and etcd member should sit in a different failure domain. For an external etcd cluster, apply the same rule to the etcd nodes and keep the API server nodes spread the same way.

The first thing to confirm is what your platform calls a failure domain and whether it is independent in practice. In a cloud, a zone may share a network fabric, a control plane or a storage backend with other zones in the same region, and the vendor documentation should state which services are zonal and which are regional. In a data center, check whether two racks share power feeds, aggregation switches or a storage array. Ask the infrastructure team to show you the physical or logical dependencies, then map each etcd member to a domain that does not share them. Also confirm the latency between domains, because etcd is sensitive to disk and network round-trip times, and a domain that is far away may degrade write performance even when it survives.

Worker nodes need the same thinking, with more room for variation. Create node pools per zone or rack rather than one large pool that the scheduler can place anywhere, so you can control the size of each domain and drain one without affecting the others. Label every node with its topology values, using the well-known topology.kubernetes.io/zone label where your cloud provider or kubelet sets it, and add a custom label such as a rack identifier for on-premises racks. Confirm which labels your distribution applies automatically and which you must set during provisioning. Without accurate labels, the scheduler cannot make placement decisions based on the domain a node belongs to.

Topology spread constraints and pod anti-affinity are the two mechanisms that keep replicas apart. A topologySpreadConstraints entry with a topologyKey of the zone label and a maxSkew value limits how unevenly pods of one workload can be distributed across domains, and whenUnsatisfiable decides whether the scheduler blocks placement or accepts a skew. Pod anti-affinity can require or prefer that replicas avoid nodes that already run a matching pod. Hard requirements prevent co-location but can leave pods pending during a partial outage, so choose the mode per workload after testing. Set the constraints in your deployment templates, and confirm that the same rules are enforced for stateful sets, which need a storage class that can provision volumes in the zone where the pod is scheduled.

Size each domain so the cluster keeps running when one fails. If a zone is lost, the remaining replicas must fit on the surviving nodes at the resource requests they carry, and the control plane must still hold quorum with its remaining members. Work through the arithmetic with your own workload figures: total requested CPU and memory per replica set, the number of replicas you require to serve traffic, and the headroom your autoscaler and cluster autoscaler need to add nodes in time. Exact zone counts, node sizes and capacity margins depend on your infrastructure, workload and availability targets, so test them. Run a controlled drain of one domain in a staging environment, observe whether pods reschedule and whether the API server stays reachable through its load balancer, and record the results as the basis for your design.

What drives the effort and cost of a Kubernetes HA build

This table lists the factors that most change the effort of a high availability build, how each one grows the work, and how to keep it contained. Read each row as a lever: the same build costs far less when the topology is standardized and the runbooks are rehearsed. Use the one-time and recurring columns to separate build work from the ongoing work you will carry after handover.

DriverWhy it changes effort or costHow to keep it downOne-time or recurring
Number of clusters and environmentsEach cluster needs its own control plane, etcd, load balancer, certificates and backup jobs. Every extra environment repeats the build and the testing.Use one standard node template and one documented topology for all clusters. Promote the same automation through environments instead of hand-building each one.Build work is one-time per cluster. Patching and checks recur per cluster.
Failure domains and whether they are true independent zonesThree control plane nodes only give real protection when they sit in separate failure domains with independent power, network and storage. Shared hardware hides the single point of failure.Confirm with your data center or cloud team which racks, hosts or availability zones are truly independent before design starts. Document the mapping of nodes to domains.One-time design and verification. Recurs if capacity moves or zones change.
Stacked versus external etcdStacked etcd is fewer machines and simpler operations, but etcd shares failure with the control plane node. External etcd adds a separate cluster to build, secure, back up and upgrade.Choose one topology per platform based on how much separate etcd operations your team can run. Write the decision and its reasons into the build record.Build work is one-time. External etcd adds recurring operations for its own upgrades and backups.
Network and load balancer complexityThe API server needs a TCP load balancer on port 6443 with health checks, certificate SANs and stable DNS. Each extra network segment, firewall rule or proxy adds test cases.Keep one load balancer pattern and one API endpoint name. Limit firewall changes to a single reviewed rule set and test failover of a control plane node before go-live.Build work is one-time. Certificate renewal and load balancer changes recur.
Air-gapped image mirroringControl plane, add-on and system images must be pulled, verified and pushed to a private registry for every version. Each Kubernetes upgrade repeats this work offline.Mirror only the image list your chosen version and add-ons require. Script the pull, scan and push steps so each release follows the same path.Initial mirror is one-time. Every version change recurs.
Certificate and identity integrationCluster certificates, the API server endpoint and the identity provider settings must agree. Users, groups and service accounts need mapping before the cluster is trusted with production access.Agree the certificate authority, the endpoint name and the identity provider settings in writing early. Reuse the same identity configuration across clusters.Setup is one-time. Certificate rotation and identity changes recur.
Storage that must follow workloads across zonesPersistent volumes that cannot attach in another zone limit where pods can recover. Replicated or zone-aware storage needs its own design, testing and backup plan.List which workloads are stateful and which storage classes they use. Choose storage that supports the zone model you documented, and test a pod move across zones.Design and test are one-time. Storage capacity growth and backup jobs recur.
Workloads that need zone-aware schedulingEach workload with spread, anti-affinity or disruption requirements needs its own manifests, labels and tests. Many workloads with different rules multiply the review effort.Group workloads into a small number of spread patterns. Set pod disruption budgets and topology spread rules from a shared template, and test a node drain for each pattern.Initial configuration is one-time. New workloads and rule changes recur.

Securing the API endpoint and etcd in a highly available cluster

A highly available control plane gives an attacker more entry points: a load balancer in front of several API servers, etcd members that hold cluster state, and admin credentials copied to every control plane node. The cards below cover the configuration and checks that close those paths, and they point to broader hardening topics where the detail lives.

Restrict the API load balancer exposure

The TCP load balancer in front of kube-apiserver on port 6443 should accept connections only from the networks that need the API, such as administrator workstations, CI runners and worker nodes. Confirm the listener's allowed source ranges, check that the backend pool contains only control plane nodes, and test from a network outside the allowed set that the port does not answer. Record the rules as part of the cluster's change history.

Enable mutual TLS between API server and etcd

kubeadm creates separate certificate authorities and client certificates for the API server to reach etcd, and etcd peers authenticate each other. Verify that the API server's etcd client certificate, key and CA paths match the etcd server configuration, that etcd requires client certificates, and that peer certificates are not shared with client certificates. Check certificate expiry dates before go-live and plan their renewal.

Encrypt Secrets at rest

Secrets are stored unencrypted in etcd by default, so anyone who reads an etcd snapshot or disk can read them. Configure an encryption provider configuration for the API server, set the key management approach your organization uses, and confirm encryption applies to existing Secrets by rewriting them after the change. Verify on every control plane node, because each API server needs the same configuration before you rely on it.

Limit list and watch access to Secrets

Reading Secrets through list or watch exposes every value in a namespace in one request, which is more than most workloads need. Audit existing ClusterRoles and RoleBindings for verbs on secrets, remove wildcard grants, and scope remaining access to named resources where the API allows it. Check the result with a permission test for each service account that runs in the cluster.

Protect etcd snapshot files

An etcd snapshot from etcdctl snapshot save contains the full cluster state, including Secrets in the form stored in etcd. Restrict file permissions on snapshot directories, encrypt snapshots before they leave the node, and limit who can read backup storage. Confirm that restore procedures include the decryption key and that the people who can restore are the same people you have approved to see Secret data.

Secure kubeconfig admin credentials

kubeadm places an admin kubeconfig on the first control plane node, and operators often copy it to other control plane nodes and laptops, so one leaked file grants full cluster access. Inventory every copy, restrict file mode and ownership, remove copies that are no longer needed, and plan to replace shared admin credentials with individually identified access. Confirm that certificate-based admin credentials can be revoked or rotated through your process.

How to test that the cluster survives node and zone loss

Run a failure test plan in staging before production, and treat every test as a written hypothesis with an expected result recorded before you run it. The goal is to prove that the control plane and your workloads behave as the high availability design says they will, not to discover the design during a real outage. Use the same topology as production where you can: the same number of control plane nodes, the same load balancer in front of kube-apiserver on TCP port 6443, the same node labels and the same failure domain layout. A test on a smaller or differently spread cluster proves very little about production.

Start with the control plane. Stop one control plane node and confirm that the API remains reachable through the load balancer, using a health check from outside the cluster network as well as kubectl from an admin workstation. Check that the load balancer removes the failed backend and that kubectl commands continue to succeed without manual kubeconfig changes. Then stop one etcd member and confirm that writes still succeed, for example by creating and deleting a test ConfigMap and reading back its resourceVersion. In a stacked topology the etcd member lives on the same node as kube-apiserver, so the first test also removes an etcd member. Confirm the member list with etcdctl and the health of the remaining members before you bring the node back.

Next, drain or isolate a whole failure domain. Cordon and drain every node in one zone or rack, or cut its network access at the hypervisor or switch level if you want a closer simulation of a zone outage. Confirm that Deployments and StatefulSets reschedule their pods onto surviving nodes, that topologySpreadConstraints, pod anti-affinity and PodDisruptionBudgets are honored, and that no workload is pushed onto a node that breaks its own constraints. Pods that cannot be placed should remain Pending with a clear scheduler event rather than silently overloading a survivor. Record how long each workload took to return to its desired replica count, and compare that with the recovery expectations your application owners have agreed.

Test the failure you hope never happens: loss of quorum. Stop enough etcd members to break majority, then confirm that the API server and etcd refuse writes instead of accepting them on a minority. There should be no split brain, two leaders making conflicting changes, or corrupted data after the members return. Confirm the behavior by reading cluster state after recovery and comparing it with the last known good state. Then rehearse a restore from an etcd snapshot taken with etcdctl snapshot save, and restore it with etcdutl into a fresh data directory on a clean node. Verify the restored object counts and a sample of Secrets, then document each step, including who authorizes the restore and where the snapshot is stored.

Add two credential checks to the same drill. Confirm that the kubeadm join token used for adding nodes has not expired or, if it has, that a new one can be created and used, and list the expiry of every control plane certificate with kubeadm certs check-expiration. Also record the certificate authority location and who can renew it. Repeat the full plan after each Kubernetes minor version upgrade, because control plane components, etcd and add-ons change between releases. Keep a dated results log with expected and observed outcomes, any deviations, and the fix for each one. That log is your evidence that the cluster was tested, and it becomes the baseline you compare against the next run.

What to monitor, back up, upgrade and document after go-live

A highly available control plane needs continuous attention after go-live. Most of the work below recurs, and each item needs a named owner who knows when to act, so failures are caught before they cost quorum.

Watch etcd leader changes and disk latency

Track leader changes, member health, disk latency and database size on every etcd member. Frequent leader elections often point to slow disks or unstable networking between members, so alert on them and investigate before they become outages. Compare database size against the quota your team sets so compaction and defragmentation keep pace. Owner: the platform on-call engineer. This check recurs continuously.

Check API server availability through the load balancer

Confirm that the TCP load balancer in front of kube-apiserver on port 6443 passes health checks from every control plane node, and alert when a backend drops out of rotation. Test reachability from client networks as well as from inside the cluster, because a healthy node can still be unreachable through the balancer. Owner: the network team for the balancer and the platform team for the API probes. This check recurs continuously.

Track certificate expiry dates

Inventory every control plane certificate, the etcd peer and client certificates, and the kubelet certificates, then record their expiry dates. Alert well before any of them lapse. Confirm with your distribution how renewal happens, such as during upgrades or through a scheduled command, because renewal behavior differs between tooling. Owner: the platform team, with a documented backup contact. Review this inventory at each upgrade and after any certificate change.

Schedule off-cluster etcd snapshots

Take etcd snapshots on a fixed schedule with etcdctl snapshot save from a healthy member. Store copies outside the cluster's failure domain and encrypt them before they leave the node, since snapshots contain Secrets and other sensitive state. Keep the encryption keys separate from the snapshots. Test restores with etcdutl in staging on a recurring basis. Owner: the platform team for the schedule and the security team for key management.

Upgrade one minor version at a time

Upgrade kube-apiserver first, one minor version at a time, then kube-controller-manager and kube-scheduler, then kubelets. Under the version skew policy, kubelets may run up to three minor versions behind kube-apiserver, so use that window to stage node upgrades. Only the three most recent minor releases receive fixes, so schedule upgrades against the published end-of-life dates. Owner: the platform lead. Rehearse each upgrade in staging first.

Document topology and recovery runbooks

Keep a current record of the topology, including whether etcd is stacked or external, how nodes spread across zones, and the load balancer configuration. Write runbooks for member replacement and quorum recovery, and rehearse them. Etcd should keep an odd member count, and Kubernetes recommends five members in production, so record any deviation and its reason. Owner: the platform team lead. Update the documents after every topology or configuration change.

Questions teams ask before building Kubernetes high availability

How much does a Kubernetes high availability build cost?

The cost depends on the work the build requires, not on a single number, so ask for a written quote tied to a scope. The main components are infrastructure (at least three control plane nodes, a TCP load balancer in front of the API server on port 6443, and, for external etcd, a separate etcd cluster of three or five members), the engineering time to design and build it, the testing of failure scenarios, and the handover documentation. Infrastructure and licensing recur, while design, build and handover are usually one-time. Costs rise with the number of clusters, the number of failure domains, air-gapped requirements and the number of distributions involved. Ask each quote to separate one-time work from recurring items such as node capacity, support subscriptions and retainers.

How long does it take to build Kubernetes high availability?

Timeline is set by the decisions made before any node is built: the topology, the number of failure domains, how etcd will be backed up, and how identity and networking integrate. Teams that already have virtual machines, a private registry, DNS and a load balancer product usually move faster than teams that must procure all of them. Testing node loss, zone loss and etcd quorum loss takes time because each scenario needs a controlled run and a documented result. Ask the provider for a schedule with named milestones and for the acceptance tests that close each one. Confirm the supported Kubernetes minor versions and their end-of-life dates on the official Kubernetes releases page before fixing the target version, because that date affects how long the build will be current.

Can our own team build Kubernetes high availability without a partner?

Yes, many teams do, provided they have engineers who can operate Linux, networking, certificates and etcd, and they follow the kubeadm high availability guide. The harder parts are rarely the first install. They are the failure tests, certificate rotation, the etcd backup and restore process, and the upgrade rehearsal. Be honest about the skills in house and the people who will be on call. A partner is useful when the team needs a fixed scope, an independent design review, or a rehearsed runbook on a deadline. Ask any partner to show how the handover will let your staff run the cluster without them, and whether the work includes training.

What does the work need from our staff and infrastructure?

Plan for named owners on the platform, networking, identity, storage and security sides, and for at least three control plane machines that are separated by failure domain. You also need a load balancer or virtual IP for kube-apiserver, reliable DNS, time synchronization, a private container registry if the network is restricted, and a backup target that is off the cluster. Staff must be able to restore etcd from a snapshot using etcdutl and to read cluster logs during an incident. Infrastructure owners should confirm that the chosen zones really have independent power and network paths, since two nodes in one rack do not give zone-level protection.

Is stacked etcd acceptable for our risk tolerance?

Stacked etcd can be acceptable when the cluster is small, the team is comfortable with the failure modes, and the risk is limited to losing one control plane node at a time. In the stacked topology, etcd members run on the control plane nodes, so losing two of the three nodes loses etcd quorum and the control plane. External etcd separates the two layers and lets you size and protect the etcd cluster independently, but it adds machines, certificates and operational work. Kubernetes documentation recommends an odd number of etcd members and a five-member cluster in production. Decide on the topology by writing down the failure you must survive, the recovery time you can accept and who will perform the restore.

How do Kubernetes upgrades change a high availability setup?

Upgrades become a rolling procedure across the control plane, and the skew rules decide the order. The version skew policy requires kube-apiserver to be upgraded one minor version at a time, before kube-controller-manager, kube-scheduler and kubelets, and kubelets may be up to three minor versions older than the API server. In an HA cluster, upgrade one control plane node at a time, confirm API health and etcd membership after each step, and take an etcd snapshot before starting. Each upgrade also needs a check of add-ons, load balancer health checks and deprecated APIs. Ask providers to include a staging rehearsal in the quote and to state how many upgrade windows the handover covers.

What should we ask for in a written quote for this work?

Ask for a scope that names the topology, the number of control plane and etcd nodes, the failure domains, the load balancer method, the backup target and the acceptance tests. Ask which items are one-time (design, build, testing, documentation, training) and which recur (infrastructure, subscriptions, support retainers, upgrade work). Ask which Kubernetes version is in scope and what happens if the target version changes before the work is finished. Ask who performs the failure tests, what evidence you receive, what the client must provide, and which assumptions would change the price or timeline. Fixed-scope agreements with written deliverables make these comparisons possible.

How DeployOpen works on this

DeployOpen plans, builds, tests, documents and supports Kubernetes high availability inside your own infrastructure, whether that is your cloud accounts, data centers or air-gapped networks. The work starts with a written scope that fixes the topology, failure domains and deliverables before any node is provisioned.

How we scope

  • Choose stacked or external etcd topology and document the trade-offs for your failure tolerance
  • Map three or more control plane nodes to failure domains such as racks, hosts or availability zones
  • Agree the API server load balancer design, port 6443 exposure and the health checks it uses
  • Confirm the Kubernetes minor version and the distribution or kubeadm path, aligned to supported releases

How we build

  • Provision control plane nodes, etcd members and the TCP load balancer in front of kube-apiserver
  • Configure etcd with an odd member count, with five members as the production recommendation
  • Test node loss and zone loss scenarios and record how workloads reschedule and recover
  • Set up etcd snapshot backups with etcdctl and rehearse restores with etcdutl before handover

How we hand over

  • Deliver the written architecture, topology diagram, failover runbook and node inventory
  • Provide tested procedures for replacing a failed control plane node and recovering from lost quorum
  • Walk your platform team through monitoring of etcd health, API server availability and certificate expiry
  • Record the evidence from failure tests so your auditors and operators can review what was verified

How we support

  • Offer ongoing support, upgrades and continuous testing as a retainer after handover
  • Plan control plane upgrades one minor version at a time, following the version skew policy
  • Re-run failure tests after upgrades, node pool changes or changes to the load balancer
  • Confirm support boundaries, response expectations and access arrangements in the written agreement

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.