Default bridge IP for Intel NUC is missing

All docker Linux instances have a fixed IP address for the host (172.17.0.1). Balena engine seems to be no exception, with Raspberry Pi devices always coming up on that IP. Raspberry Pi 4:

br-17bf457e9f0b Link encap:Ethernet  HWaddr 02:42:F4:17:D1:F7  
          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST MULTICAST  MTU:1500  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:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

This is useful and expected behaviour, there is even apps built around this expectation: Does wifi-connect need to be mounted to host instead of port? - #6 by majorz && Docker Tip - How to use the host's IP Address inside a Docker container on macOS, Windows, and Linux - DEV Community

I just started using an Intel NUC device with Balena OS, and this isn’t the behaviour. The IP address seems to change. This is usually only behaviour seen on Docker MacOS or Docker Windows. Any ideas what could be going on?

balenaOS 2.89.15

Hi @maggie, as far as I’m aware the 172.17.0.0 subnet is the default bridge network but it’s possible that balena-engine chooses a different one from a set of predefined subnets (see balena-libnetwork/utils.go at 20.10-balena · balena-os/balena-libnetwork · GitHub). I’m not sure under what circumstances this happens however, for example if you create additional bridge networks, or if there is a collision, but I’ll ask the engine team to see if they can provide insight.

That said, you shouldn’t assume 172.17.0.1 is always the host, even for specific device types. For example on my NUC it is 172.17.0.1, and I’ve certainly seen Pi’s with 172.18.x.x:

root@geth:~# cat /etc/os-release 
ID="balena-os"
NAME="balenaOS"
VERSION="2.89.15"
VERSION_ID="2.89.15"
PRETTY_NAME="balenaOS 2.89.15"
MACHINE="genericx86-64"
META_BALENA_VERSION="2.89.15"
BALENA_BOARD_REV="096fd83"
META_BALENA_REV="53ab6811"
SLUG="intel-nuc"
root@geth:~# ifconfig | grep br-* -A 8
br-d42acd5d23d6 Link encap:Ethernet  HWaddr 02:42:61:95:B0:84  
          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
          inet6 addr: fe80::42:61ff:fe95:b084/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:9055 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9109 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:744403 (726.9 KiB)  TX bytes:3727962 (3.5 MiB)

What I typically do is use the following commands to get the hostOS IP address on the bridge network:

  • On a network_mode: bridge container: ip route | awk '/default / { print $3 }'
  • On a network_mode: host container: ip route | awk '/br-/ { print $7 }'
1 Like

Thanks for sharing your experiences with it. I had considered the idea of awk or grep, but been trying to avoid it, it just felt a bit hacky. And considered a bunch of other things too, using unix sockets, moving everything to the host network, the list goes on. I guess in this instance, without any official Docker/Balena engine hostname that can be relied on like with Docker for Mac they are all a little bit hacky and the awk method probably most reliable.

I’m thinking the host IP address should be static once the device is online, so could run it on start of a container and store it in an env variable? Has that been your experience? Maybe via an entry point script? Would be helpful if you have anything you have already put together that works to base it off, rather than reinventing the wheel.

@tmigone here is a new one I haven’t seen before. On a Raspberry Pi 4 I was getting multiple IP addressed returned from ip route | awk '/br-/ { print $7 }'. When putting it in a env variable it ended up failing as it was trying to read a long list. I changed it instead to:

ip route | awk '/br-/ { print $7 }' | head -n 1