How do I install a kernel module in an LXC guest machine?

Solution 1:

Short answer is, you can't. LXC containers share their kernel with the host's and by default aren't allowed to load modules (as this would be pretty dangerous).

The standard recommendation is to have any module loaded on the host prior to starting the container. You can either do that with a good old init script or by using an lxc hook (see my recent post here for details: https://www.stgraber.org/2013/12/23/lxc-1-0-some-more-advanced-container-usage/)

Solution 2:

For the purposes of this answer, let's assume your container is named `"foo".

PART A

  1. From the host, save a copy of /var/lib/lxc/foo/config, in case my instructions break something.

  2. You will need to configure your container to keep the SYS_MODULE capability.

    Be aware that such a configuration gives that container the ability to take over kernel and thereby the host.

    To do this, you will want to change the "lxc.cap.drop" or "lxc.cap.keep" configuration line.

    If you are running an Ubuntu 19.04 guest that was created with "lxc-create --name foo --template download -- ..." then:

    • /var/lib/lxc/foo/config will contain a line

      lxc.include = /usr/share/lxc/ubuntu.common.conf
      
    • /usr/share/lxc/ubuntu.common.conf will contain a line

      lxc.include = /usr/share/lxc/config/common.conf
      
    • /usr/share/lxc/config/common.conf will contain a line like this

      lxc.cap.drop = mac_admin mac_override sys_time sys_module sys_rawio
      

You should copy that last line to the end of /var/lib/lxc/foo/config (or any place after the "include /usr/share/lxc/ubuntu.common.conf") and then delete "sys_module" from that list.

Part B

You need a copy of your kernel modules in the container.

If your host is running an Ubuntu kernel, then you may be able to do something like "sudo apt install kernel-image-$(uname -r)" from the guest.

Otherwise from the host, may need to do something like this (assuming your container is named "foo"):

mkdir -p /var/lib/lxc/foo/rootfs/lib/modules
cp -apr /lib/modules/$(uname -r) /var/lib/lxc/foo/rootfs/lib/modules/

After that, shut down the guest foo if it is running, and then restart it with something like "lxc-start --name foo".

The LXC container should now be able to load and unload kernel modules.