Container Static IP, Host DHCP?

We have an existing product that we are considering moving to Balena. It is a device that does not generally have internet access, and users manage its static ip address(es) via a touch screen interface (Qt).

We would like use Balena to manage the device and provide the host internet access via DHCP, while limiting the change to the local control system that just expects to connect to some static ip address(es).

So ideally we would like to see…

  1. Host OS uses DHCP to connect back to Balena Cloud (say it gets 10.1.2.3/24 assigned with gateway and dns)
  2. Container opens listening sockets on static ip of external network (something like 10.4.3.2/24, no gateway, no dns services exist on that network)
  3. Container could also publish data to internet via host (on some other interface?)

My searching at large has suggested I should use the macvlan driver to give the containers their static ip addresses, but Balena has no support for macvlan. But I think I may just be approaching this wrong.

What would the Balena recommended path be? Should I put static IPs on the host and just expose my container ports? I was hoping to keep DHCP but if that’s the only way, so be it.

Replying to my own question, I think the answer is “No, Balena can’t do that”.

It does appear at the host layer I can have static addresses on top of DHCP.

nmcli connection modify "Wired connection 1" ipv4.addresses "10.4.3.2/24"

Changes didn’t take effect until after I rebooted the host OS.

Hi Nathan,

So you would like to use both a DHCP assigned address and static IP addresses on top of a single interface. NetworkManager that we use for connection management indeed supports that and you seem on the right track.

First ipv4.method is how one enable IP address assignment mode. The default auto is through DHCP. However you may add additional IP addresses on top like you did with the nmcli command.

You do not have to reboot the host OS for the change to take effect, but instead you may issue:
nmcli connection up <ConnectionName>.

When you do that part in a container, I would advice towards using a library for interacting with NetworkManager. There are many different examples inside the NM repo: NetworkManager/examples at main · NetworkManager/NetworkManager · GitHub

Also please check those documentation sections as well:

For the containers sometimes you may need to set network_mode: "host" in the docker-compose.yml file. That would allow direct access to the networking interfaces from the container like when you need to listen on specific IP address. For other cases please note that if you interact with NetworkManager from a container specifying network mode to host won’t be needed as NetworkManager operates inside host OS namespace.

The “Wired connection 1” connection that you modify in the example above is a connection created automatically by NetworkManager if NO other connection profile for the Ethernet interface is not already defined. That is to say you may create your own NetworkManager connection profile and the automatic one will not be created.

Your third question is 3. Container could also publish data to internet via host (on some other interface?) and that should not be a problem. Even if the container is using default bridge network mode (opposed to network_mode: "host"), it can still connect to external IP addresses because of the networking routing rules where packets will be forwarded through the appropriate interface.

I hope that will give you a few pointers to continue forward with this.

Thanks,
Zahari

Thank you!