By default LXC drops the following capabilities from container.
  • mac_admin
  • mac_override
  • sys_time
  • sys_module
  • sys_rawio
As can be seen in the following line from "/usr/share/lxc/config/common.conf".

# Drop some harmful capabilities
lxc.cap.drop = mac_admin mac_override sys_time sys_module sys_rawio

Capability keeping and dropping in lxc can be controlled by,
  • lxc.cap.drop
  • lxc.cap.keep

Installing a module requires sys_module (CAP_SYS_MODULE), and since it is dropped when a container is started, it cannot run.
Apart from Linux Capabilities LXC also uses SECOMP, and APPARMOR (in my system it used these, however it can interface with many other security mechanisms, as well, for example SELinux). SECOMP filter specified in "/usr/share/lxc/config/common.seccomp" prevents some system calls from being executed. Lets have a look at the default SECOMP filter on my system.


#SECOMP filter - notice that "#" is used for commenting
2
blacklist
reject_force_umount # comment this to allow umount -f; not recommended
[all]
kexec_load errno 1
open_by_handle_at errno 1
init_module errno 1
finit_module errno 1
delete_module errno 1

As can be seen, SECOMP prevents "finit_module", and "init_module" from getting executed. These system calls are used for installing kernel modules. Therefore, for installing a kernel module from a container (for whatever reason), you will have to edit SECOMP config as well.

See my other article to know how to print capabilities of a process with the given PID, from inside the Linux Kernel.

My system -
Ubuntu 16.04.1
Linux 4.7.3 kernel