Skip to content

Default multiInterfaceMode to Multus on new installations - #5239

Open
fasaxc wants to merge 1 commit into
masterfrom
default-multi-interface-mode-multus
Open

Default multiInterfaceMode to Multus on new installations#5239
fasaxc wants to merge 1 commit into
masterfrom
default-multi-interface-mode-multus

Conversation

@fasaxc

@fasaxc fasaxc commented Aug 21, 2026

Copy link
Copy Markdown
Member

Description

Type: enhancement.

spec.calicoNetwork.multiInterfaceMode selects which WorkloadEndpointConverter the
Calico Enterprise components use. None, the previous default, gives the
single-interface converter, which cannot express anything a modern cluster needs.
Multus gives the converter that reads the k8s.v1.cni.cncf.io/networks and
.../network-status pod annotations and produces a WorkloadEndpoint per pod interface.
New installations now get Multus.

Existing clusters keep the mode they were installed with. The core controller writes
its computed defaults back to the Installation spec precisely so that changing a default
cannot disturb a running cluster ("ensures that we don't surprise anyone by changing
defaults in a future version of the operator"), so every already-reconciled cluster
carries multiInterfaceMode: None and the defaulting code never sees a nil. #5203 keeps
this property by a different route — it records defaults in status.Defaults and seeds
defaulting from them first — so this change is correct both before and after that lands,
and the two don't need ordering.

The default stays in fillDefaults rather than becoming a +kubebuilder:default, even
though docs/api_design.md prefers markers: it only applies when the CNI is Calico, and
validation rejects the field outright for any other CNI, so a schema-level default would
fail every non-Calico-CNI Installation. It also has to stay distinguishable from a
user-set value for the status.Defaults bookkeeping in #5203.

Defaulting stays unconditional across variants, as it is today. Only the Enterprise
render paths emit MULTI_INTERFACE_MODE, so Calico OSS gets an inert value in its spec —
already true of None — and keeping it unconditional means an OSS cluster later
converted to Enterprise keeps what was recorded at install time instead of picking up a
new default mid-life.

Two behaviour changes worth a reviewer's attention

  1. Adopted manifest installs. A cluster migrated by pkg/controller/migration/convert
    has no persisted value, so it picks up Multus at migration. This is benign for pods
    with no Multus annotations — the Multus converter's defaultInterfaceForPod
    reproduces the default converter's WorkloadEndpoint name (<node>-k8s-<pod>-eth0) and
    host-side veth name (cali + 11 hex chars of sha1("<ns>.<pod>")) exactly. But on a
    cluster that already runs Multus with Calico in none mode, Calico will start
    creating WorkloadEndpoints for the secondary interfaces.
  2. Extra WorkloadEndpoint labels. Multus mode adds
    projectcalico.org/network-attachment,
    projectcalico.org/network-attachment-namespace and
    projectcalico.org/network-interface to every WorkloadEndpoint.

Testing

  • make ut — 101 suites, all pass. No render-fixture fallout: the render tests that
    exercise this field construct the Installation with an explicit mode rather than going
    through fillDefaults.
  • pkg/controller/installation/defaults_test.go — the two empty-instance tests
    (Calico and CalicoEnterprise) now assert the Multus default. The existing "should not
    override custom configuration" cases already pin an explicit None and pass unchanged,
    which is the regression guard for user-set values.
  • make gen-files produces exactly the two regenerated field descriptions (under spec
    and under status.computed) and nothing else; make format-check clean.

Affected components: pkg/controller/installation (defaulting), api/v1
(doc comment), and the regenerated Installation CRD. Behaviour reaches
calico-node (install-cni and calico-node containers), calico-typha,
calico-kube-controllers and the apiserver, all of which render
MULTI_INTERFACE_MODE from this field.

Related: #5203.

Release Note

New installations default spec.calicoNetwork.multiInterfaceMode to Multus, enabling multiple interfaces per pod via Multus annotations. Existing clusters keep the mode they were installed with.

For PR author

  • Tests for change.
  • If changing pkg/apis/, run make gen-files
  • If changing versions, run make gen-versions

For PR reviewers

A note for code reviewers - all pull requests must have the following:

  • Milestone set according to targeted release.
  • Appropriate labels:
    • kind/bug if this is a bugfix.
    • kind/enhancement if this is a a new feature.
    • enterprise if this PR applies to Calico Enterprise only.

multiInterfaceMode selects which WorkloadEndpointConverter the Calico
Enterprise components use. None, the previous default, gives the
single-interface converter, which cannot express anything a modern
cluster needs; Multus gives the converter that reads the
k8s.v1.cni.cncf.io annotations and produces a WorkloadEndpoint per pod
interface. New installations now get Multus.

Existing clusters keep the mode they were installed with. The core
controller writes its computed defaults back to the Installation spec
precisely so that changing a default cannot disturb a running cluster,
so every already-reconciled cluster carries multiInterfaceMode: None
and the defaulting code never sees a nil.

The default stays in fillDefaults rather than becoming a
+kubebuilder:default: it only applies when the CNI is Calico, and
validation rejects the field outright for any other CNI, so a schema
default would fail every non-Calico-CNI Installation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants