This version is under construction, please use an official release version

Cluster Tuning and Limits

Cluster tuning baseline

The published numbers are not reproducible on stock component limits. The table below lists what was tuned and why.

ComponentStockTunedWhy
ovn-central (deployment)cpu 4 / mem 8 Gicpu 4 / mem 16 Giheadroom for NB and SB database growth at high object counts. The limit must never exceed control-plane node RAM: an oversized limit lets ovn-central grow past physical memory, and the kernel then OOM-kills the control-plane node, apiserver and etcd included. 16 Gi is safe on 24 GiB control-plane nodes; scale the limit to your own nodes
ovn-central probestimeout 45 stimeout 300 s, failureThreshold 10database replay after a pod restart exceeds 45 s at high object counts, so the longer timeout prevents kubelet from killing pods mid-replay
kube-ovn-controllercpu 2 / mem 4 Gicpu 8 / mem 8 Giworkqueue drain at high object counts (runs on 251 GiB workers)
ovs-ovn (DaemonSet, every node)cpu 2 / mem 1 Gicpu 4 / mem 8 Gieach node’s ovn-controller holds the whole cluster’s logical-flow set; the 1 Gi stock limit OOM-killed it at about 7.7 k subnets, which was the real per-node datapath wall before the bump
kube-ovn-cni (DaemonSet)mem 1 Gimem 2 Giheadroom for pod-wiring churn at scale
kube-multus-ds (DaemonSet)mem 256 Mimem 1 Giat the stock limit multus OOM-crash-looped (92 to 514 restarts over 102 days), which blocked all pod wiring on affected nodes and surfaced as a false 50-service ceiling

First binding factor per capability

ResourceFirst binding factor
Network tenants (VPCs)etcd database size (77 % of its danger line at 10 k; everything else below 50 %)
Subnetsnetwork-controller programming throughput; before tuning, per-node ovs-ovn memory (1 Gi OOM at about 7.7 k)
Firewall policiesnone observed up to 355 k ACLs cluster-wide (cap-bound)
Security groupskube-ovn-controller stability (a concurrent-map data race at the 20 k-SG load, an upstream bug)
Servicespod-wiring throughput (every functional VIP needs a Ready backend pod)
Static routescontroller programming cadence (drift between requested and programmed)
Combined tenants (degradation)per-VM datapath state (port binding, conntrack, and NAT); empty objects are nearly free

Interpretation caveats

  • Cap-bound versus wall-bound. Cap-bound means the run reached its configured cap while healthy, so the value is a lower bound. Wall-bound means something real stopped it (named in the tables). Only security groups and static routes are wall-bound; every other number published here is cap-bound or window-bound.
  • Catch-up-window-bound numbers understate the ceiling. The subnetsPerCluster figure of 11,822 is where programming settled within a 3-hour window, not a wall. A longer window or a faster controller raises it.
  • Security groups carry an upstream-bug caveat. The ceiling is a kube-ovn 1.14.30 stability bound, not an OVN capacity bound.
  • QoS policies and network-attachment templates have no standalone row by design. Both are binding-triggered: a bare CR programs nothing until a pod or EIP references it, so a bare-object ceiling would measure only API storage, which is meaningless under the programmed-and-functional definition.
  • Static routes used the earlier methodology (no functional verify, no catch-up settle).
  • One cluster shape. All numbers come from the reference cluster listed in the section overview; the tuning baseline above is part of the result.