fix(multus): bake CNI plugins into an image, drop the node-side fetch #447
Merged
k.renner
merged 2 commits from 2026-07-30 12:33:49 +00:00
cni-plugins-image into master
2
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d62c5da5a0 |
fix(multus): include dhcp in the cni-plugins build assertion
Review point on #447. The build-time check asserted macvlan, static and host-local were executable but omitted dhcp, which the sibling cni-dhcp-daemon DaemonSet runs and which its own comment says ships from this installer ("the dhcp binary ships from the sibling cni-plugins-installer DaemonSet ... whole tarball extracted"). Verified that dependency in kubernetes/infrastructure/multus/ cni-dhcp-daemon.yaml before changing anything, rather than taking the review's word for it. Consequence of the omission: since the whole /plugins directory is copied regardless of what the loop checks, nothing is broken today — but the "fail loudly if upstream restructures the archive" guarantee only covered three of the four binaries this repo depends on. Upstream dropping dhcp while keeping the others would have built green and surfaced later as a broken DHCP daemon on whichever node rolled first. Confirmed all four are executable in the already-published image, so this tightens the assertion without changing what ships. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
8ac30b0ef7 |
fix(multus): bake CNI plugins into an image, drop the node-side fetch
Supersedes the wget-instead-of-curl approach in #446, which removed the `apk add` but left the real problems in place. The installer fetched the containernetworking/plugins release tarball from GitHub on the node and extracted it into /opt/cni/bin with NO integrity verification of any kind. That directory is executed as root in the CNI path on every node, so a tampered or MITM'd artifact would have obtained privileged execution cluster-wide with nothing to detect it. It also put github.com on the critical path of every node rebuild. Now the binaries are baked into ci/images/cni-plugins, where the download happens once and the sha256 IS verified, and the installer is a local file copy with zero network calls (verified: no wget/curl/apk/https in the rendered script). The pinned digest was cross-checked against upstream's own published cni-plugins-linux-amd64-v1.5.1.tgz.sha256 asset, not merely recorded from a local download — a download can be tampered with, so comparing against what upstream states is the point: 77baa2f669980a82255ffa2f2717de823992480271ee778aa51a9c60ae89ff9b Verified the gate actually gates: with the correct digest the layer logic downloads, verifies, extracts and asserts macvlan/static/host-local are executable; with a deliberately wrong digest `sha256sum -c` FAILS and the extract step is never reached. Install script changes beyond dropping the fetch: - Copies unconditionally instead of the old "already installed?" guard. The guard existed to avoid re-downloading; a local copy is cheap, so copying every time means a node always matches the version pinned in the manifest rather than keeping whatever it first installed. - Copies to a temp name in the same directory then rename(2)s over the target. `cp` onto a plugin the kubelet is currently executing can fail with ETXTBSY; rename never does and is atomic, so a concurrent CNI invocation sees either the old or the new binary, never a partial one. - LICENSE and README.md are no longer installed into /opt/cni/bin; the old tar extraction put them there. The chown 0:0 is kept but re-framed as a REPAIR. Its original cause is gone — extraction applied the archive's `./` uid/gid (1001/127, the github-actions runner) to the destination, and `cp` into an existing directory does not touch its ownership. It still runs because nodes provisioned by the old installer may already carry the wrong ownership, which breaks Cilium's apply-sysctl-overwrites init container. Verified end-to-end with the rendered script, including that repair path: pre-seeded owner 1001:127 -> 0:0 after run fresh install -> host-local/macvlan/static present, macvlan executes and reports "CNI macvlan plugin v1.5.1", exit 0 re-run -> idempotent, exit 0, 18 plugins, no .tmp files left Note the image carries ~80MB of extracted plugins (18 binaries), matching what the old installer put on each node. All are kept rather than trimming to the few in use, to avoid removing plugins already present on nodes as a side effect of this change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |