How to manage hosts network namespaces from docker container
The only solution which I found is to start a docker with binding /proc from host and using nsenter to change the mount namespace.
host # docker run .... -v /proc:/host/proc /bin/bash
container # nsenter --mount=/host/proc/1/ns/mnt ip netns add test
Docker Network Namespace
It looks like you're running in a container. If you want to be able to handle namespaces and such, your container has to be started with the -privileged
flag.
How do `ip netns` and `unshare` save their persistent network namespaces? Can they use each others?
Both unshare --net=/somefile
and ip netns add somename
create a new network namespace and bind-mount it to somewhere. The only difference is that unshare
bind-mounts it to whatever file you specify, and ip
bind-mounts it to a new file in /var/run/netns/
. In other words, if you used /var/run/netns/mynetns1
in place of /root/mynetns1
, then you could later interact with it with ip
.
Error when creating a network namespace inside a docker container. error: mount --make-shared /run/netns failed: Permission denied
--cap-add
& --privileged
are not same.
Ref: https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities
Issue is sorted by running the container with privilege. Capabilities seems not required for adding network namespace.
docker run -d --name=<name> --network=none --privileged <image>:<tag>
Can you bind the default network interface of the host into the container to read network stats?
There is a way to enter the host network namespace after starting the container. This can be used to run one process in the container in the container network namespace and another process in the host network namespace. Communication between the processes can be done using a unix domain socket.
Alternatively you can just mount a new instance of the sysfs which points to the host network namespace. If I understood correctly this is what you really need.
For this to work you need access to the host net
namespace (I mount /proc/1/ns/net to the container for this purpose). Additionally the capabilities CAP_SYS_PTRACE and CAP_SYS_ADMIN are needed.
# /proc/1 is the 'init' process of the host which is always running in host network namespace
$ docker run -it --rm --cap-add CAP_SYS_PTRACE --cap-add CAP_SYS_ADMIN -v /proc/1/ns/net:/host_ns_net:ro debian:bullseye-slim bash
root@8b40f2f48808:/ ls -l /sys/class/net
lrwxrwxrwx 1 root root 0 Jun 2 21:09 eth0 -> ../../devices/virtual/net/eth0
lrwxrwxrwx 1 root root 0 Jun 2 21:09 lo -> ../../devices/virtual/net/lo
# enter the host network namespace
root@8b40f2f48808:/ nsenter --net=/host_ns_net bash
# now we are in the host network namespace and can see the host network interfaces
root@8b40f2f48808:/ mkdir /sys2
root@8b40f2f48808:/ mount -t sysfs nodevice /sys2
root@8b40f2f48808:/ ls -l /sys2/class/net/
lrwxrwxrwx 1 root root 0 Oct 25 2021 enp2s0 -> ../../devices/pci0000:00/0000:00:1c.1/0000:02:00.0/net/enp2s0
lrwxrwxrwx 1 root root 0 Oct 25 2021 enp3s0 -> ../../devices/pci0000:00/0000:00:1c.2/0000:03:00.0/net/enp3s0
[...]
root@8b40f2f48808:/ ls -l /sys2/class/net/enp2s0/
-r--r--r-- 1 root root 4096 Oct 25 2021 addr_assign_type
-r--r--r-- 1 root root 4096 Oct 25 2021 addr_len
-r--r--r-- 1 root root 4096 Oct 25 2021 address
-r--r--r-- 1 root root 4096 Oct 25 2021 broadcast
[...]
# Now you can switch back to the original network namespace
# of the container; the dir "/sys2" is still accessible
root@8b40f2f48808:/ exit
Putting this together for non-interactive usage:
Use the docker run
with the following parameters:
docker run -it --rm --cap-add CAP_SYS_PTRACE --cap-add CAP_SYS_ADMIN -v /proc/1/ns/net:/host_ns_net:ro debian:bullseye-slim bash
Execute these commands in the container before starting your node app:
mkdir /sys2
nsenter --net=/host_ns_net mount -t sysfs nodevice /sys2
After nsenter (and mount) exits, you are back in the network namespace of the container. In theory you could drop the extended capabilities now.
Now you can access the network devices under /sys2/class/net.
Related Topics
Using Bash Script to Find Line Number of String in File
How to Detect If a Git Clone Failed in a Bash Script
Opening a .Tar.Gz File with a Single Command
How to Recursively Download a Folder Via Ftp on Linux
A Light Solution to Convert Text to PDF in Linux
Which Context Are Softirq and Tasklet In
What Are Meanings of Fields in /Proc/Net/Dev
How to Include a Pipe | in My Linux Find -Exec Command
How to Find All Files with a Filename That Ends with Tilde
How to Automate HTML-To-Pdf Conversions
How to Retain Docker Alpine Container After "Exit" Is Used
Need an Overview of Debugging Process from the Hardware Layer
How Do Linux File Descriptor Limits Work
How to Divide in the Linux Console