Explanation
Availability levels
When you move a Kubernetes cluster from a single-node laptop environment to a multi-zone cloud environment, you normally have to revisit every Deployment and StatefulSet to bump replica counts, add pod anti-affinity rules, and create PodDisruptionBudgets. In Kix, you declare the failure scope your cluster needs (none, pod, node, or zone) in one place, and Kix works with each package to configure replicas, placement constraints, and disruption budgets automatically.
One setting, four failure scopes
Section titled “One setting, four failure scopes”Rather than asking a cluster operator to know the replica flags of every package in the cluster, Kix defines four availability levels based on what kind of failure the cluster must survive without downtime:
| Level | What the service must survive |
|---|---|
none | Nothing guaranteed; a pod crash or rolling update may cause brief downtime. |
pod | Losing a single pod, or replacing pods during a rolling update, must not cause downtime. |
node | Losing an entire Kubernetes worker node must not cause downtime. |
zone | Losing an entire cloud availability zone must not cause downtime. |
The cluster’s declared hardware capabilities establish the read-only cluster.availability.substrate option, which records the highest level the underlying nodes can support and provides the default for cluster.availability.default. Each package then translates the active level into its own replica and quorum counts, and Kix adds the matching placement rules and PodDisruptionBudgets.
One requirement, several compiled decisions
Section titled “One requirement, several compiled decisions”Different kinds of software need different numbers of replicas to survive the same failure. A stateless HTTP server only needs 2 replicas to survive a pod, node, or zone outage, as long as those 2 pods sit in different failure domains. A Raft or Paxos quorum store needs at least 3 members so it can lose one member and still keep a majority. A legacy controller that does not support leader election may only be able to run 1 replica no matter what the cluster asks for.
Kix splits this decision cleanly between the package author and the cluster operator:
- The package author knows the software’s architecture and uses
kix.availability.pick availability { ... }to mapnone,pod,node, andzoneto appropriate replica counts. - The cluster operator sets
cluster.availability.defaulton the cluster (or overridesavailabilityon a specific instance) without needing to memorize each package’s internal options.
Whenever a Deployment or StatefulSet resolves to more than one replica under an availability level above none, Kix automatically derives:
topologySpreadConstraintsacross the cluster’s failure-domain labels (kubernetes.io/hostnameandtopology.kubernetes.io/zone);- hard placement (
DoNotSchedule) on the domain required by the chosen level, and best-effort placement (ScheduleAnyway) on the remaining domains; - a
PodDisruptionBudgetwithmaxUnavailable = 1selecting the workload’s pods.
The generated topology spread constraints use maxSkew = 1. That balances pods evenly across the available failure domains without requiring the replica count to be an exact multiple of the zone count (for example, 5 replicas across 3 zones settle cleanly as 2/2/1).
Hardware capabilities keep configuration honest
Section titled “Hardware capabilities keep configuration honest”Setting replicas = 3 on a single-node cluster gives a false sense of security: if the one node goes down, all three pods go down with it. Similarly, adding zone spread constraints on a cluster whose nodes have no topology.kubernetes.io/zone labels will either leave pods Pending or pack them onto the same hardware.
Kix checks the requested availability level against cluster.capabilities.multiNode and cluster.capabilities.availabilityZones:
- A confirmed single-node cluster (
multiNode = false, such askix.flavors.kind) supports at mostnone. - A multi-node cluster without multiple zones supports up to
node. - A multi-node cluster with two or more declared zones supports
zone.
If you request a level higher than the cluster’s substrate and the deciding capabilities are explicitly set (multiNode = false or an explicit availabilityZones list with fewer than two zones), evaluation fails immediately with a clear error. When the requested level is above the inferred substrate and the substrate is uncertain because a deciding capability is left unset (null), Kix emits a warning so you know the substrate guarantees could not be verified at build time.
Package and workload ceilings
Section titled “Package and workload ceilings”Some programs cannot run multiple active replicas safely. When a package declares meta.availability.max (for example, max = "none" or max = "pod"), Kix caps the resolved availability level for that package at its ceiling and emits a warning when the cluster requested a higher level.
Other packages combine a replicated data plane with a single-replica management component in the same package. For those cases, the individual workload builder (scope.mkDeployment or scope.mkStatefulSet) can set availability.max = "none" on just that workload while the rest of the package honors the full cluster level. Because a none ceiling means the workload cannot safely run concurrent copies, Kix rejects a workload that sets availability.max = "none" alongside replicas > 1.
Explicit placement takes ownership
Section titled “Explicit placement takes ownership”When a package explicitly sets its own topologySpreadConstraints on a workload, Kix steps back: it neither injects generated spread constraints nor generates a default PodDisruptionBudget for that workload. If a multi-replica workload supplies custom placement constraints without shipping a matching PodDisruptionBudget in the same instance, Kix emits a warning so voluntary-disruption protection is not forgotten by accident.