Repository navigation
Hold bpfKubeProxyHealthzPort=0 until every calico-node accepts it - #5303
Closed
tomastigera wants to merge 1 commit into
Closed
tomastigera wants to merge 1 commit into
tomastigera wants to merge 1 commit into
Conversation
…cepts it Connecting an OSS v3.31.x BPF cluster to Calico Cloud left calico-node in CrashLoopBackOff and deadlocked the manifest->operator migration: Unable to set global default configuration error=error with field BPFKubeProxyHealthzPort = '0' (Reason: failed to validate Field: BPFKubeProxyHealthzPort because of Tag: gte) 0 meaning "disabled" is only accepted from Calico v3.32.0 and Enterprise v3.23.0-2.0. Validation is client-side in libcalico-go, so an older node fails it while writing back the global defaults at startup and crashloops, even though the field means nothing to it. The operator stamped the value into the shared FelixConfiguration while v3.31.7 pods were still serving nodes out of kube-system. Gate the default on allNodesRunTargetVersion: skip the write while the kube-system migration is pending and, once an operator-managed DaemonSet exists, until Status.Variant and Status.CalicoVersion report the version this operator rolls out. A fresh install still writes it immediately, so the AKS case CORE-12755 fixed is unchanged. CORE-13540
Member
|
Heads up - operator development on master has moved into the Calico monorepo at projectcalico/calico, under The move shifted every file down a directory and changed the import prefix, so a plain cherry-pick won't apply. This gets most of the way: Anything the PR touched outside the operator tree ( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Bug fix. Connecting an OSS v3.31.x BPF cluster to Calico Cloud leaves
calico-nodein CrashLoopBackOff and deadlocks the manifest->operator migration:0meaning "disabled" is only accepted from Calico v3.32.0 and Enterprise v3.23.0-2.0. Validation is client-side in libcalico-go andstartup.gowrites the global defaults back on every pod start, so a node predating the value crashloops on a field it does not even use. #4768 (CORE-12755) defaults the port to0on BPF clusters where the operator does not manage kube-proxy, gated only on BPF being enabled, kube-proxy being unmanaged and the field being nil — nothing about what version is running. The value therefore lands in the shared FelixConfiguration while old pods are still serving nodes.Two paths are exposed:
kube-system, and the migration recreates them when it edits the nodeSelector, so they re-read FelixConfiguration and die. The migration then waits for them and times out.Reconcile, before the DaemonSet is rendered. The rolling update itself mostly survives, since each terminated pod returns on the new image, but an old pod restarting out of turn does not — and neither does a rollback, where the0stays in the datastore and every node crashloops with no way forward.The fix gates the write on
allNodesRunTargetVersion:Status.VariantandStatus.CalicoVersionreport the version this operator rolls out. Those are written only on a reconcile that got paststatus.IsAvailable(), so they mean "the whole stack was seen up on that version".The existing calico-node DaemonSet lookup moves above the healthz block so it and the
bpfEnabledderivation share one Get.isRolloutCompleteWithBPFVolumeswas considered and does not fit: it inspects the calico-system DaemonSet, which during migration is nodeSelector-limited to already-migrated nodes and so reports a complete rollout while unmigrated pods run. It is also count-based, hence trivially true on a DaemonSet the operator has not touched yet this reconcile — safe for the eBPF flip only because thebpffsvolume marks "new spec applied", and there is no equivalent marker for a version bump.The helper is written to be reusable: the hazard is generic to any FelixConfiguration value whose validator is newer than the oldest running node. Only this call site is wired up here; whether other operator-written defaults want the same gate is worth a separate look.
Testing. A 7-entry table on the helper plus three reconcile specs — upgrade in flight (not written), status reports the target (written), ns-migration pending (not written).
fakeNamespaceMigrationgained aneedsMigrationfield.go test ./pkg/controller/installation/is green at 303 specs; the 22CEL validationspecs need envtest assets and are skipped locally. Every branch of the new helper was mutation-tested: four are caught by a failing test, and a fifth turned out redundant and was removed. Removing the fresh-install branch breaks #4768's original AKS spec, which confirms that path is untouched.Internal: CORE-13540.
Release Note
For PR author
make gen-filesmake gen-versions