LookupExtInterface() constructs a backend.ExternalInterface but never
sets the IfaceName field, leaving it as an empty string. When the VXLAN
device (flannel.1) is deleted — e.g. because the parent interface
specified via --flannel-iface transiently disappears — the recreation
code in vxlan_network.go:165 calls net.InterfaceByName(""), which
always fails. This puts flannel into an unrecoverable retry loop:
external interface not found, retrying in 30s
The fix adds IfaceName: iface.Name to the struct literal. The iface
variable already holds the correct *net.Interface; its Name field just
needs to be copied into the IfaceName string that the VXLAN recreation
path reads.
This is a one-line change that enables the VXLAN device recreation
logic added in flannel PR #2272 (v0.27.4+) to actually work when
flannel is embedded in K3s.
Affects any deployment using --flannel-iface with an overlay network
(Tailscale, Nebula, ZeroTier) where the parent interface can
transiently restart.
Ref: https://github.com/k3s-io/k3s/issues/12436
Ref: https://github.com/flannel-io/flannel/issues/2247
Signed-off-by: Jay Kubo <6161465+jkubo@users.noreply.github.com>
mux is replaced with a simple wrapper around http.ServeMux with middleware chain support
Unfortunately github.com/rootless-containers/rootlesskit/pkg/parent
still uses it so we can't drop the indirect dep yet.
Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
Add support for the "nix" snapshotter, which enables running container
images built with nix2container. Nix images reference store paths
directly, avoiding layer tarballs and enabling deduplication through
the nix store.
Changes:
- Register nix-snapshotter as a builtin containerd plugin
- Add NixSupported() validation (checks nix-store is in PATH)
- Configure nix-snapshotter image service proxy in V2/V3 templates
with containerd_address for CRI image operations
- Add Transfer service unpack_config with differ=walking for
multi-arch support
- Use containerd state dir for socket path (rootless compatible)
- Disable NRI in rootless mode to prevent bind failures
Usage: k3s server --snapshotter nix
Signed-off-by: Ada <ada@6bit.com>
Co-Authored-By: Joshua Perry <josh@6bit.com>
Signed-off-by: Ada <ada@6bit.com>
Add imports to the generated containerd config so containerd loads
drop-in TOML files: config.toml.d for v2, config-v3.toml.d for v3
(e.g. /var/lib/rancher/k3s/agent/etc/containerd/config.toml.d and
/var/lib/rancher/k3s/agent/etc/containerd/config-v3.toml.d).
Also fix the v3 header comment to say config-v3.toml.tmpl instead
of config.toml.tmpl.
Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
- Use os.CreateTemp to avoid race conditions with fixed temp filename
- Add f.Sync() before close to ensure data durability
- Check all fmt.Fprintf errors instead of ignoring them
- Preserve original file permissions when overwriting
- Handle dir== edge case from filepath.Split
- Check os.MkdirAll error
- Proper cleanup on all error paths
Signed-off-by: luojiyin <luojiyin@hotmail.com>
Add documentation comments to WriteSubnetFile
Clarify the design choices for atomic file writing:
- Explain why CreateTemp is used (defense-in-depth, avoids pre-existing file issues)
- Document the single-instance assumption
- Note the permission preservation logic
Signed-off-by: luojiyin <luojiyin@hotmail.com>
Update WriteSubnetFile comment to clarify CreateTemp rationale
Remove misleading reference to concurrent writes (K3s is single-instance).
Focus on the actual benefits: avoiding stale temp files from crashes,
handling unexpected permissions/ownership, and O_EXCL guarantees.
Signed-off-by: luojiyin <luojiyin@hotmail.com>
Refactor cleanup to use merr.NewErrors for better error aggregation
Address review feedback from @brandond to improve error handling:
- Change cleanup function to accept error parameter
- Use merr.NewErrors to aggregate original error with Close/Remove errors
- Simplify error handling with consistent return cleanup(err) pattern
Signed-off-by: luojiyin <luojiyin@hotmail.com>
Fix Close error handling to preserve original error
Add cleanupNoClose helper to avoid double Close and preserve the
original Close error when file close fails.
Signed-off-by: luojiyin <luojiyin@hotmail.com>
Move flannel annotations into flannel setup, and use patch helpers to manage other node labels and annotations
Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
Flannel and VPN setup shouldn't be done in generic agent config as it is only
used with embeded executor's flannel CNI.
Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
Allows properly delegating CNI startup to executor, so that it can be plugged in as platform and distro specific implimentation without relying on cli flag hacks
Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
Currently only waits on etcd and kine, as other components
are stateless and do not need to shut down cleanly.
Terminal but non-fatal errors now request shutdown via context
cancellation, instead of just logging a fatal error.
Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
Wait for updated ready condition before starting netpol controller, to ensure that node IPs have been updated following a restart. The current checks only ensure that the taint is removed, which works for the initial join - but does not handle changing node IPs on restarts.
Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
The container runtime endpoint value is passed into cri-dockerd as the docker socket address, so we need to check for --docker BEFORE checking for non-nil --container-runtime-endpoint.
Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
Move the `ipv4` and `ipv6` constants to their own constant
declaration. This ensures that the `iota` expression for the `ipv4`
constant evaluates to 0, not some arbitrary value. (`iota` evaluates
to N for the Nth constant in the constant declaration; see
<https://go.dev/ref/spec#Iota>.) This is also more idiomatic, which
improves readability.
Also switch from incremental integers to bit flags, and use bitwise
operators for checking. This is more idiomatic (the integer is
treated like a set of booleans), it avoids some code duplication, and
it is necessary to avoid ambiguity. Consider the following:
const (
ipv4 = iota
ipv6
)
In the above, `ipv4` would have the value 0 and `ipv6` would have the
value 1. This would make it impossible to distinguish an IPv6-only
stack from a dual-stack configuration because `ipv6` would equal
`ipv4 + ipv6`. With bit flags this problem doesn't exist.
And put the integer holding the bit flags in a custom type with
convenience methods to improve readability.
Signed-off-by: Richard Hansen <rhansen@rhansen.org>