Skip to content

Conversation

@robmry
Copy link
Contributor

@robmry robmry commented Dec 6, 2024

- What I did

When running in a container (docker-in-docker), the host may not have required kernel modules loaded.

Try to trigger the module load using an ioctl() call, then modprobe if that doesn't work.

This should make IPv6 networks work in GitHub Codespaces / devcontainers:

This is based on the DinD official image's method of loading modules using ip link show, which was inspired by https://twitter.com/lucabruno/status/902934379835662336

- How I did it

- How to verify it

On a Debian 12.5 host, running dockerd 27.3.1, with systemd ...

  • With ip6_tables not loaded on the host (the host doesn't need it, because the daemon'sip6tables commands use a (deprecated) dbus interface to send raw firewall commands.
  • Started a dev container with the updated code, the ip6_tables module wasn't loaded.
  • Built the new dockerd and ran it, with ip6tables enabled by-default.
  • The module was loaded on the host, and inner-docker logs showed module was loaded using the ioctl method:
    • DEBU[2024-12-05T11:30:36.095500049Z] Modules loaded loadErrors="<nil>" loader=ioctl modules=ip6_tables
  • Restarted the inner docker, no load was attempted:
    • DEBU[2024-12-05T11:31:59.533424067Z] Modules already loaded modules=ip6_tables
  • Ditto (both times) for the conntrack modules:
    • DEBU[2024-12-05T11:31:59.590301221Z] Modules already loaded modules="nf_conntrack,nf_conntrack_netlink"

To check error logging, and fallback to modprobe:

if err := modprobe.LoadModules(context.TODO(), func() error {
        return fmt.Errorf("no fruit")
}, "bananas", "apples", "oranges"); err != nil {
        log.G(context.Background()).WithError(err).Debug("Loading breakfast")
}

Resulted in:

DEBU[2024-12-05T11:55:32.007075924Z] Modules not loaded                            checkResult="no fruit" loadErrors="<nil>" loader=ioctl modules="bananas,apples,oranges"
DEBU[2024-12-05T11:55:32.007147257Z] Modules not loaded                            checkResult="no fruit" loadErrors="modprobe bananas failed with message: \"\", error: exec: \"modprobe\": executable file not found in $PATH\nmodprobe apples failed with message: \"\", error: exec: \"modprobe\": executable file not found in $PATH\nmodprobe oranges failed with message: \"\", error: exec: \"modprobe\": executable file not found in $PATH" loader=modprobe modules="bananas,apples,oranges"
DEBU[2024-12-05T11:55:32.007172382Z] Loading breakfast                             error="no fruit"

- Description for the changelog

- Attempt to load kernel modules, including `ip6_tables` and `br_netfilter` when required, using a
  method that is likely to succeed inside a docker-in-docker container.

An ioctl() call to get the "interface index" for a kernel module triggers
the kernel to try to load the module, if the process is running with
CAP_SYS_MODULE. This tends to be more reliable than "modprobe" for
docker-in-docker.

If the ioctl() method fails, fall back to trying "modprobe".

Signed-off-by: Rob Murray <rob.murray@docker.com>
(cherry picked from commit 4740820)
Signed-off-by: Rob Murray <rob.murray@docker.com>
Signed-off-by: Rob Murray <rob.murray@docker.com>
(cherry picked from commit f2e1f52)
Signed-off-by: Rob Murray <rob.murray@docker.com>
dockerd will now do this itself, if ip6tables is enabled.

Signed-off-by: Rob Murray <rob.murray@docker.com>
(cherry picked from commit 2af19b6)
Signed-off-by: Rob Murray <rob.murray@docker.com>
These modprobes were added as a workaround in commit cce5dfe, but
dockerd should now be able to load the modules it needs.

Signed-off-by: Rob Murray <rob.murray@docker.com>
(cherry picked from commit 15ba03c)
Signed-off-by: Rob Murray <rob.murray@docker.com>
@robmry robmry added kind/enhancement Enhancements are not bugs or new features but can improve usability or performance. area/networking Networking impact/changelog area/daemon Core Engine area/networking/ipv6 Networking labels Dec 6, 2024
@robmry robmry self-assigned this Dec 6, 2024
@robmry robmry requested a review from tianon as a code owner December 6, 2024 14:47
@thaJeztah thaJeztah marked this pull request as draft December 6, 2024 16:15
@thaJeztah
Copy link
Member

Temporarily moving to draft while we decide whether this still should be in 27.4.0, or if we keep it for 27.4.1

@thaJeztah
Copy link
Member

(PR itself LGTM)

@thaJeztah thaJeztah added this to the 27.4.1 milestone Dec 6, 2024
@thaJeztah thaJeztah marked this pull request as ready for review December 13, 2024 01:14
@thaJeztah thaJeztah merged commit 8a8ab0d into moby:27.x Dec 13, 2024
144 checks passed
@robmry robmry deleted the backport-27.x/modprobeless branch February 26, 2025 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/daemon Core Engine area/networking/ipv6 Networking area/networking Networking impact/changelog kind/enhancement Enhancements are not bugs or new features but can improve usability or performance.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants