balena-os / balena-supervisor

Balena Supervisor: balena's agent on devices.
https://balena.io
Other
147 stars 61 forks source link

Allow easier .local hostname resolution in containers #1593

Open majorz opened 3 years ago

majorz commented 3 years ago

While .local names are resolvable by default from the host OS, they are not from inside a container. One has to install an init system like systemd, and Avahi + nss-mdns libc plugin or systemd-resolved + nss-resolve.

The glibc nss-mdns plugin is used for resolving .local host names through Avahi. In order for nss-mdns to function it needs access to the Avahi socket, which is usually located at /var/run/run/avahi-daemon/socket.

Since we already run Avahi on the host OS if we introduce a new label avahi-socket that binds the host OS Avahi socket to the container, then Avahi + systemd will not be needed to be installed inside a container and only the nss-mdns plugin needs to be installed. This will simplify such use-case a lot and make the container much more lightweight.

jellyfish-bot commented 3 years ago

[majorz] This issue has attached support thread https://jel.ly.fish/2e147e2b-fe94-4d90-977c-26d7903799ce

20k-ultra commented 3 years ago

Thanks for adding the label implementation that fixes this. I wasn't sure what the easiest approach to this was but that solution seems very straight forward.

20k-ultra commented 3 years ago

@majorz @alexgg I can access the avahi socket from the host via the /mnt/root mount or we can add another mount.

What do you think ?

This feature is as simple as me submitting a PR with the following + tests:

        'io.balena.features.avahi-socket': () =>
            service.config.volumes.push(
                `${constants.rootMountPoint}/var/run/avahi-daemon/socket:/var/run/avahi-daemon/socket`,
            ),
alexgg commented 3 years ago

@20k-ultra sounds good, let's ack it in an arch call first though.

majorz commented 3 years ago

Initially I looked at how the docker socket specified.

We pass the location as environmental variable when the supervisor container is launched -e DOCKER_SOCKET=/var/run/balena-engine.sock (https://github.com/balena-os/meta-balena/blob/457c37c7fc652af296d045bd00df804aea0dabed/meta-balena-common/recipes-containers/resin-supervisor/resin-supervisor/start-resin-supervisor#L76)

A default value is also specified in supervisor: https://github.com/balena-io/balena-supervisor/blob/fb9a73b3d66fdc27ea77920929ae002ac2d5760e/src/lib/constants.ts#L13

Finally it is added: https://github.com/balena-io/balena-supervisor/blob/cfc72e673bec47dd5f7743393568d755251b01e3/src/compose/utils.ts#L346-L349

I do not think the Avahi socket location needs to be configurable as it most probably won't change, so we can use the hardcoded paths directly.

We do not need to access it through /mnt/root, but directly through /var/run/run/avahi-daemon/socket. Inside the container we will need it in the same location and not on /host as the nss-mdns Avahi plugin configures that in compile time.

I have not tested this approach in practice yet, we should do that before releasing the code. Also we will need to document somewhere how the socket could be used inside a container and maybe add somewhere a sample repository.

majorz commented 2 years ago

As a further note here is an example project that demonstrates on how to enable currently .local hostname resolution within containers: https://github.com/balena-io-examples/balena-avahi

Hades32 commented 2 years ago

Maybe this can be solved on the OS level: https://superuser.com/questions/1459467/update-dnsmasq-with-information-from-avahi

Timple commented 1 year ago

Is there any update on this? We need the exact same feature. All of our containers require mdns. Thus currently they all have a avahi-daemon. Which is a waste as the balenaOS also has one.

Timple commented 12 months ago

Please vote here if you require this feature: https://roadmap.balena.io/posts/94/expose-avahi-socket-to-containers