larsks / blog.oddbit.com

3 stars 0 forks source link

post/2014-08-11-four-ways-to-connect-a-docker/ #12

Open utterances-bot opened 3 years ago

utterances-bot commented 3 years ago

Four ways to connect a docker container to a local network · The Odd Bit

Update (2018-03-22) Since I wrote this document back in 2014, Docker has developed the macvlan network driver. That gives you a supported mechanism for direct connectivity to a local layer 2 network. I’ve written an article about working with the macvlan driver. This article discusses four ways to make a Docker container appear on a local network. These are not suggested as practical solutions, but are meant to illustrate some of the underlying network technology available in Linux.

https://blog.oddbit.com/post/2014-08-11-four-ways-to-connect-a-docker/

frkd-dev commented 3 years ago

Hi, This is a really useful guide. Despite it was written back in 2014 it's still actual in 2021. I'm trying to bring some of my containers in my home lan so I can directly access running services and really using your guide to make my stuff working. Thanks.

larsks commented 3 years ago

I'm glad you found it helpful! Note that in almost all cases, just using Docker port publishing (docker run -p <hostport>:<containerport> ...) is going to be more flexible and easier to manage, and will generally get you the same end result. Unless you're trying to run a containerized DHCP server or something, you don't generally need to expose containers directly to the local network.

frkd-dev commented 3 years ago

Yep, port publishing is an easy and good option until your containers don't require to be advertised using Avahi/mDNS which requires connection with dedicated IP and broadcasting support. A good example is Apple Home and AirPlay services.

ehivanov commented 3 years ago

HI I trust the guide is very useful, not only judging by the comments here , but also by the fact I found links to this article in some popular forums, recommending it as THE working solution. So I spent a few hours trying to implement the solution "With Linux Bridge devices", which matching my needs the best, but failed to make it work. Pretty sure it is my fault, but can't find what I'm doing wrong. All the steps went fine and in the end the container has an IP from the host network (192.168.3.0 in my case), but the host can't see the container by this IP and the container can't reach the host network. Any advice ? Thanks!

larsks commented 3 years ago

All the steps went fine and in the end the container has an IP from the host network (192.168.3.0 in my case), but the host can't see the container by this IP and the container can't reach the host network. Any advice ?

I don't have anything clever to suggest. In general, debugging networking issues like this means paying careful attention to each of your links, and possibly breaking out tcpdump and applying it at various points to see where traffic is disappearing.

Two things I'd like to note:

I'll reiterate here what I think I've said earlier, which is that 9 times out of 10 you'll be better off using regular Docker port forwardi

ehivanov commented 3 years ago

Thank you very much. Agree - in most of the cases the default port forwarding is the preferred and well working solution . However my case is one of the exclusions. Anyway - MacVLAN did the job. Everything works now as needed and expected. Thanks again ! Really useful blog !

parveenLily commented 3 years ago

hi, ip link set netns $(docker-pid web) dev web-int, fails with error. Error: argument "nginxhello" is wrong: Invalid "netns" value. I also noticed that when i created the link , there is no /proc/$PID folder on my docker WSL2 backend. any help will be appreciated. thanks!

larsks commented 3 years ago

@parveenLily the first problem is that apparently the docker-pid script is not returning a PID, hence the error from ip link set netns. What is the output if you just run docker inspect --format '{{ .State.Pid }}' your_container_name?

Also, I see that you're running WSL, which is an environment with which I am not familiar. It's possible that Docker running under WSL does not behave the same way as Docker under Linux.

isv485 commented 3 years ago

Hi, First of all, thanks a lot for your great article. It helps me a lot to understand containers networking.

Still, I have related to my specific network configuration question:

All this startup sequence works on host, but if the service started inside a docker container (linux), discovered through UDP protocol device IP address (example, 169.254.0.1), does not forward UDP messages to a device on the host network. Tried to use "network_mode: host", but discovered through UDP IP is not in a range 169.254.0.0 subnet and device is not reachable also.

Any help with expected docker container network configuration will be really appreciated. Thank you!

packetgeek commented 2 years ago

Wish I'd seen this article years ago... I'm still using the OVS option but had to figure out how to do it on my own. OVS becomes valuable when you're deploying redundant architectures in Docker, such as for a class, where each student gets an identical, private architecture with multiple IP spaces, to troubleshoot or attack/defend. With OVS, deployment of each "lab" was so simple, it was easy to automate. The hard part (now) is figuring out how to deploy it in Kubernetes.

I can make a similar statement about the nsenter features. I also used similar techniques to add virtual wifi to the above architectures. Fun!

takumade commented 2 years ago

I installed docker rootless and I cant access my containers by IP on 172.16.x.x/16

How can I achieve that

I want to access every container using its IP address e.g 172.16.0.1 from the host

larsks commented 2 years ago

That may not be possible with rootless Docker. While I haven't used rootless docker, I use podman which does have a rootless mode and in this model it's not possible to directly access a container (because it's not directly connected to a bridge device on the host). I imagine rootless Docker is similar. If that's true, your options are either:

takumade commented 2 years ago

Thanks @larks, Yeah its not possible to access containers directly using a rootless docker,

Docker says in their documentation:

IPAddress shown in docker inspect and is namespaced inside RootlessKit’s network namespace. This means the IP address is not reachable from the host without nsenter-ing into the network namespace.
Host network (docker run --net=host) is also namespaced inside RootlessKit.

So basically you need to enter Rootlesskit's namespace using nsenter:

nsenter -U --preserve-credentials -n -m -t $(cat $XDG_RUNTIME_DIR/docker.pid)

And you will be able to ping and access containers IP(in that namespace). It kind of sucks, I might have to go back to using root-full

albert-a commented 8 months ago

I also recently wanted to expose container to my network in L2, and found out that currently it is natively supported by docker. It can be done either with macvlan or with the bridge, check this comment: https://github.com/moby/libnetwork/issues/2310#issuecomment-1902248657