Modify the Host Kernel from a Docker Container

Search for a command to run...

No comments yet. Be the first to comment.
If you use Docker regularly and want to understand what’s really happening behind the scenes, this series is for you.
If you’re containerizing your Go app and losing sleep over the image size even for a simple project. Then you’re probably overlooking Docker’s multi-stage builds feature. This technique lets you separ
For those who don't know, Wayle is a project from the same creator as Hyprpanel, which is apparently going to be deprecated soon. Probably because of that, I couldn't find a proper theming guide anywh

Once you've spent years on an operating system, things soon start becoming stagnant. I hit that wall recently. I realized I'm spending most of my time at a full-time job, so I have very little time le

If you just want Thunar to work properly without digging into details, run: sudo pacman -S thunar gvfs tumbler ffmpegthumbnailer thunar-archive-plugin Optional (but useful): sudo pacman -S thunar-vol

I was bored and just wanted to code something to spark the life, of course. And, to fight it, my brain thought, "how fast really is my DNS provider?" No architecture diagram. No benchmarking framewo

What really happens when you run docker ps: from CLI to Kernel Internals

Can we prove Docker shares the same kernel as the host machine?
Yes — and we can prove it hands-on.
This was actually a random thought. I didn’t research existing proofs or blog posts because I wanted to reason from first principles using my understanding of Linux and Docker. Heck, I don’t even know if there are any. So, there may be more sophisticated PoCs out there, but this one is based purely on Linux and Docker fundamentals I know. So anyone with basic CLI knowledge can follow along.
Lame question for this topic. I know but I got commentators to cover.
But let’s cover the basics in five lines for anyone wondering why we’re even here.
Here’s my least-effort explanation:
The short answer is Docker shares the kernel of the host system.
Docker containers do not boot their own operating system. They do not run their own kernel. They are simply isolated processes running on the host’s kernel.
That’s the core idea.
Now let’s prove it in four different ways.
Every time a Linux system boots, it generates a unique boot ID. You can find it here: /proc/sys/kernel/random/boot_id. So, if a container truly shares the host kernel, both should show the same boot ID.
And, yep! that is the case.
Host Machine:
cat /proc/sys/kernel/random/boot_id
Docker Container:
docker run --rm archlinux:latest cat /proc/sys/kernel/random/boot_id
As shown in below screenshot they both share the same boot ID.
This was easy mode. However, it does not strictly guarantee it. For example, alternative container runtimes like gVisor can virtualize certain kernel interfaces and potentially invalidate this test or PoC.
This one is actually real good. I’m going to use two different Linux flavors just to make the contrast obvious.
Like Such:
Host system = Ubuntu
Container = Arch Linux
You can swap them however you like the distro choice doesn’t matter.
Logic is simple: since both resources allegedly share same kernel then they must show the same Linux kernel version even though they’re different operating systems.
If you’ve fiddled around with different Linux distros, you probably know that each distro typically has its own kernel build format. If Arch were running its own kernel, you’d expect something like:
~ uname -r
6.18.x-arch1-2 # Arch Linux Kernel Version Format
But instead, you see the Ubuntu kernel version.
But Is This Enough? Not really. This only proves both environments report the same kernel version. Doesn’t mean they’re literally share the same kernel.
“What if Docker somehow copies the host kernel into the container?”
That would still result in the same version number without necessarily sharing the same running kernel instance. So again — strong evidence. But not really.
Now we’re getting serious. Because if Docker shares the same kernel instance, then both environments must share the same kernel log buffer. That means dmesg output should be exactly the same.
By default, containers cannot access kernel logs. So we must tell docker to grant permission.
Start Container With SYSLOG Capability
docker run --rm --cap-add SYSLOG ubuntu:latest bash -c "dmesg | tail -20"
You could also use --privileged instead of --cap-add SYSLOG, but that grants far more access than we need.
See, the logs are not just similar — they are identical. This is a very strong evidence.
Could This Still Be Fake? Theoretically, one might argue:
“What if Docker is exposing /dev/kmsg to containers?”
Even in that case, the container would still be reading the host’s live kernel message buffer which means there is no separate kernel instance running inside the container.
If you really wanted to push this further, you could even compare checksums of the full dmesg output from host and container. But at that point, we’re just mathematically proving what’s already practically obvious.
But we’re not stopping here.
Time for final boss.
/dev/kmsg, we could easily verify that.Let’s go for the head of the guy who’s so skeptical that he thinks Docker has nothing better to do than lie to people.
Login is simple: modifying the kernel from inside the container should affect the host.
So let’s test exactly that. We’ll insert a kernel module from inside the container and observe its effect on the host.
I’ll go with a good old simple “Hello World” kernel module that prints something into the kernel log buffer. Just enough to prove a point. You could take this further and experiment with things like modifying the network stack, blocking traffic, or other kernel-level changes.
We’ll need a bit more configuration for this step.
Start a Privileged Container With Module Access
docker run -it --privileged \
-v /lib/modules:/lib/modules \
-v /usr/src:/usr/src \
ubuntu:latest /bin/bash
Why mount /lib/modules and /usr/src?
/lib/modules contains kernel modules for the running kernel.
/usr/src contains kernel headers required to compile modules.
We mount them so the container can compile modules against the host kernel.
Without this, module compilation would fail.
Install required tools inside the container
apt update && apt install nano kmod build-essential linux-headers-$(uname -r)
Create a filename hello_kernel.c and paste below code.
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
static int __init hello_init(void)
{
printk(KERN_INFO "[hello_kernel] Hello, kernel world!\n");
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_INFO "[hello_kernel] Goodbye, kernel world!\n");
}
module_init(hello_init);
module_exit(hello_exit);
The above code prints “[hello_kernel] Hello, kernel world!” into the kernel log buffer when the module is inserted, and prints “[hello_kernel] Goodbye, kernel world!” when the module is removed.
Create a filename Makefile in the same directory and paste below code.
obj-m += hello_kernel.o
all:
make -C /lib/modules/\((shell uname -r)/build M=\)(PWD) modules
clean:
make -C /lib/modules/\((shell uname -r)/build M=\)(PWD) clean
Once that is done. Let’s compile them inside container with below make command.
make
The “make“ command will produce multiple files we only care about hello_kernel.ko. It’s kernel object file.
Let’s insert the module in the kernel and as soon as I do that, it would print “[hello_kernel] Hello, kernel world!“ in kernel’s log buffer.
insmod hello_kernel.ko
Now run dmesg on host system and inside container you would see both places hello message printed as show in the screenshot.
To see goodbye message remove the module from container with below command.
rmmod hello_kernel
Voila! we modified Linux kernel from container which proves that Docker containers share the kernel of the host system.
Since the host and Docker container are sharing the same kernel, the module we inserted from inside the container is visible on the host system as well.
Which means we can remove the module from the host system too, and that change will immediately reflect inside the Docker container also.
Because again — there is only one kernel.
On Host System:
lsmod | grep hello_kernel
rmmod hello_kernel
dmesg | tail -5
There are may be cleaner, more formal, or more academically rigorous demonstrations out there and if you know one, I’d genuinely like to see it. This was simply a practical exploration based on how Linux works and how Docker is designed.
But from an engineering standpoint, after inserting a kernel module from inside a container and seeing it reflected instantly on the host, there isn’t much ambiguity left.
Docker doesn’t emulate a kernel. It doesn’t clone one. It shares one.
If you enjoy breaking systems apart and understanding what’s actually happening underneath the abstraction layer, you might also find these interesting:
Hacking Discord: Why Does Session Hijacking Exist & How it Works?
Most Viewed: Hyprland Getting-Started: Configure Screen Lock, Authentication and More.
Thanks For Your Time.
If you want to see everything from kernel modules to Docker internals in action, I recorded a full step-by-step video.