Accessing Container Network from Host or Other Container
on Blog
In my network based or related to network projects, for debugging I execute another shell at same container and I install network tools to these container.
Ex.
docker exec --privileged -it Netherland.Amsterdam1 bash
~> apt update && apt install tcpdump
This method is bored to me due to install same tools after each container building. Also some container is only have a one executable file, installing new tools is impossible with regular or basic methods.
So I have to access container inside network from host to prevent installing anything for my service container.
Here is the normal method for Accessing From host.
Firstly we have to make a symbolic link from container netns to regular netns folder.
container_name="Netherland.Amsterdam1" # Replace with Your container name
container_pid=$(docker inspect -f '' $container_name) # Getting Container pid from docker
ln -s /proc/$container_pid/ns/net /var/run/netns/$container_name # Make a symbolic link
Now you can see your container network with ip netns
command.
root@amsterdamsv~>ip netns
Netherland.Amsterdam1 (id: 4)
dockernet
You can enter container network with again ip command.
ip netns exec $container_name bash
# Example command
root@amsterdamsv~>ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.19.0.2 netmask 255.255.0.0 broadcast 172.19.255.255
inet6 2001:db8:1234:900d:c0fe:e prefixlen 80 scopeid 0x0<global>
inet6 fe80::00:11:22:3 prefixlen 64 scopeid 0x20<link>
ether 00:11:22:33:44:55 txqueuelen 0 (Ethernet)
RX packets 368 bytes 58880 (58.8 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 439 bytes 66308 (66.3 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 72 bytes 9760 (9.7 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 72 bytes 9760 (9.7 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Accessing from host is some times is not enough. For example I have a net-tools-service container to serve my looking-glass services. I want to add Teredo network to this service. Should i make a another container with Teredo capabilities and push to register and also other network projects. Adding one by one is not efficient to managing for each repo for timing to engineer cost and also this takes many spaces on my servers.
Prohibiting to this ve can give a first container network to second container network.
container_name="Netherland.Amsterdam1" # Replace with Your container name
docker run -it --rm --privileged -v /proc/$(docker inspect -f '' $container_name)/ns/net:/var/run/netns/container alpine
~>apk add iproute2 # Default busybox iproute does not support namespaces in alpine
~>ip netns
container
~>ip netns exec container ifconfig # Here is other container network
eth0 Link encap:Ethernet HWaddr 00:11:22:33:44:55
inet addr:172.10.0.2 Bcast:172.19.255.255 Mask:255.255.0.0
inet6 addr: 2001:db8:1234:900d:c0fe::e/80 Scope:Global
inet6 addr: fe80::00:11:22:3/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:408 errors:0 dropped:0 overruns:0 frame:0
TX packets:476 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:63847 (62.3 KiB) TX bytes:73114 (71.4 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:78 errors:0 dropped:0 overruns:0 frame:0
TX packets:78 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:10450 (10.2 KiB) TX bytes:10450 (10.2 KiB)
~> ifconfig # Current Container network
eth0 Link encap:Ethernet HWaddr 00:11:22:33:44:66
inet addr:172.15.0.3 Bcast:172.17.255.255 Mask:255.255.0.0
inet6 addr: 2001:db8:1234:900d::code/80 Scope:Global
inet6 addr: fe80::00:33:22:4/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:387 errors:0 dropped:0 overruns:0 frame:0
TX packets:238 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3413869 (3.2 MiB) TX bytes:21510 (21.0 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Example with my neighbor network supported containers.
container_name="Netherland.Amsterdam1" # Replace with Your container name
# For adding Teredo
docker run -it --rm --privileged -v /proc/$(docker inspect -f '' $container_name)/ns/net:/var/run/netns/container ahmetozer/docker-teredo
# Or make a network inspect on container
docker run -it --rm --privileged -v /proc/$(docker inspect -f '' $container_name)/ns/net:/var/run/netns/container ahmetozer/cna
# SOURCE Code for ahmetozer/cna https://gitlab.com/ahmetozer/container-network-admin
NOTE: After restarting first server, your second container is unable to access first container. Container pids are changes by every restart.
You have to execute second container after each first container startup.
container_name="Netherland.Amsterdam1" # Replace with Your container name
root@amsterdamsv~>docker inspect -f '' $container_name
95321
root@amsterdamsv~>docker restart $container_name
Netherland.Amsterdam1
root@amsterdamsv~>docker inspect -f '' $container_name
321736
This problem can also has a solution. First method is make a first container as a service and execute second container after first container. If you don’t want to create service, the way for solving this issue is make a full /proc/ folder mirror to inside container and make link netns in each startup at container, but adding proc volume is not secure way to do this. Which container has a this method, it can be access every namespace and might be break security. You can only use this method to trusted containers.
docker run -it --rm --privileged -v /proc/:/proc2 -v /var/run/docker.sock:/var/run/docker.sock alpine
container_name="Netherland.Amsterdam1" # Replace with Your container name
apk add iproute2 curl
mkdir -pv /var/run/netns
rm /var/run/netns/neighbornet # in first time you can get a err.
container_pid=$(curl --unix-socket /var/run/docker.sock http/containers/$container_name/json -s | awk -v RS=',' -F: '{ if ( $1 == "\"Pid\"") {print $2}}')
ln -s /proc2/$container_pid/ns/net /var/run/netns/neighbornet
ip netns exec neighbornet bash
Here is example Container which is used this method.
container_name="Netherland.Amsterdam1" # Replace with Your container name
docker run -it --rm --privileged -e container_name=$container_name -v /proc/:/proc2/ -v /var/run/docker.sock:/var/run/docker.sock --name teredo ahmetozer/docker-teredo
# SOURCE Code for ahmetozer/docker-teredo https://github.com/ahmetozer/docker-teredo
Thank you for reading this blog.