Skip to content

fix: fall back to nftables proxy mode on nftables-only kernels - #5531

Closed
sakiphan wants to merge 1 commit into
canonical:masterfrom
sakiphan:fix/nftables-only-kernel-proxy-mode
Closed

fix: fall back to nftables proxy mode on nftables-only kernels#5531
sakiphan wants to merge 1 commit into
canonical:masterfrom
sakiphan:fix/nftables-only-kernel-proxy-mode

Conversation

@sakiphan

@sakiphan sakiphan commented Jun 3, 2026

Copy link
Copy Markdown

Summary

MicroK8s fails silently on nftables-only kernels (kernels shipped without the
ip_tables module). kube-proxy runs in the default iptables proxy mode, which
needs the ip_tables kernel module; when it is absent, kube-proxy fails to start
with modprobe: FATAL: Module ip_tables not found and the node enters a
crash-restart loop. Neither microk8s status nor microk8s inspect surface the
cause — the error is only visible in journalctl.

Fixes #5525

Changes

  • microk8s-resources/actions/common/utils.sh: add an is_kernel_module_available
    helper that checks /sys/module for loaded/built-in modules and falls back to a
    modprobe -nq dry-run for loadable ones, mirroring the existing
    nf_conntrack/br_netfilter handling in run-kubelite-with-args.
  • microk8s-resources/wrappers/run-kubelite-with-args: before starting kubelite,
    if the user has not explicitly set a proxy mode and ip_tables is unavailable
    while nf_tables can be used, fall back to --proxy-mode=nftables. A
    user-selected proxy mode is never overridden, and the check is idempotent across
    restarts.
  • scripts/inspect.sh: add a suggest_fixes warning that surfaces the missing
    ip_tables module and the manual workaround, for the cases the auto-fallback
    cannot cover (e.g. nf_tables also missing, or the user pinned
    --proxy-mode=iptables).

Testing

  • Verified is_kernel_module_available against a real loaded module (reports
    available) and a non-existent module name (reports unavailable).
  • Exercised the fallback decision across 5 scenarios using the actual code block
    from run-kubelite-with-args (mocking module availability and
    refresh_opt_in_local_config):
    • ip_tables missing + nf_tables available + no mode set → --proxy-mode=nftables added
    • ip_tables available → no change
    • both modules missing → no change (cannot fall back)
    • user pinned --proxy-mode=iptables → preserved, not overridden
    • already --proxy-mode=nftables → unchanged
  • codespell is clean on the changed files and shellcheck reports no new
    findings versus master.
  • I do not have access to an nftables-only kernel; the --proxy-mode=nftables
    workaround was confirmed working on the affected hardware by the reporter in bug: microk8s silently fails on nftables-only kernels #5525.

Possible Regressions

  • On kernels where ip_tables is present (the common case) the helper short-circuits
    via /sys/module and no fallback is applied — behavior is unchanged.
  • A user-selected --proxy-mode (including iptables) is always respected.
  • The fallback only triggers when nf_tables is usable; if neither module is
    available no change is made and microk8s inspect surfaces the problem instead.
  • The nftables proxy mode is GA since Kubernetes 1.33 and beta (on by default) since
    1.31, so this is safe on master/latest. If backported below 1.31 it would require
    enabling the NFTablesProxyMode feature gate.

Checklist

  • Read the contributions page.
  • Submitted the CLA form, if you are a first time contributor.
  • The introduced changes are covered by unit and/or integration tests.

Notes

The shell wrappers (run-kubelite-with-args, inspect.sh) have no in-tree unit-test
harness, so the changes were validated manually as described under Testing rather than
with a committed test. Happy to add coverage if you can point me at the preferred place
for wrapper-level tests. This targets master; let me know if you'd like it backported
and to which release branches.

kube-proxy defaults to the iptables proxy mode, which needs the
ip_tables kernel module. On nftables-only kernels this module is
absent, so kube-proxy fails to start ("modprobe: FATAL: Module
ip_tables not found") and the node enters a crash-restart loop that
is not surfaced by `microk8s status` or `microk8s inspect`.

- Add an `is_kernel_module_available` helper to actions/common/utils.sh.
- run-kubelite-with-args now falls back to `--proxy-mode=nftables` when
  ip_tables is unavailable and nf_tables can be used, unless the user
  has already selected a proxy mode.
- `microk8s inspect` now warns when ip_tables is missing and points to
  the manual workaround.

Fixes canonical#5525
@sakiphan sakiphan closed this Jul 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: microk8s silently fails on nftables-only kernels

1 participant