Resolve systemd-nspawn containers with nss-mymachines
You will make local systemd-nspawn container names resolvable through the normal GNU Name Service Switch path, then verify the result with getent. This is useful when a host should reach a container by its machine name instead of a copied address. Allow about 15 minutes if the container already exists, or longer if you also need to create and boot one.
The route
Jump straight to the step you need, or tick off Done means at the end.
This guide uses the installed Ubuntu package libnss-mymachines version 255.4-1ubuntu8.17, from systemd 255. The local manual describes the behaviour available on that installation. You need a local machine managed by systemd-machined, and elevated privileges only for package installation, container management or editing /etc/nsswitch.conf.
1. Check the module and machine manager
Start with read-only checks. The module is a glibc NSS plug-in, not a command that you run directly. It resolves names of locally running containers registered with systemd-machined.service.
$ command -v machinectl
/usr/bin/machinectl
$ dpkg-query -W -f='${Package} ${Version}\n' libnss-mymachines:amd64 systemd
libnss-mymachines 255.4-1ubuntu8.17
systemd 255.4-1ubuntu8.17
$ dpkg -L libnss-mymachines:amd64 | grep 'libnss_mymachines.so.2'
/usr/lib/x86_64-linux-gnu/libnss_mymachines.so.2
On another distribution, use its package query tool and check that libnss_mymachines.so.2 is installed. Do not infer availability from the presence of machinectl; the NSS module is a separate package.
2. Inspect the containers that can be resolved
List machines before changing resolver configuration:
$ machinectl list --no-pager
No machines.
The output above is the result on this host, so there is no name to test here. On a host with a running container, record the exact value in the MACHINE column. Use that registered machine name, not necessarily the hostname shown inside the container. The module only covers containers immediately below the current system context. A host can resolve its child containers, while a container cannot use this module to resolve its siblings or the host's containers.
For a real test, a container must be running with network namespacing. A typical systemd-nspawn launch uses --network-veth, but starting a container is an administrative action that can consume resources and expose services. Do it only when you own the image and have a maintenance plan:
# systemd-nspawn -M CONTAINER_NAME --boot --network-veth --private-users=pick
Replace CONTAINER_NAME with the intended registered name. The command above needs root and changes system state. Stop it using your normal machine-management procedure when finished; do not kill an unrelated container just to reproduce this test.
3. Put mymachines in the hosts lookup order
Read the current hosts: entry first:
$ awk '$1 == "hosts:" {print}' /etc/nsswitch.conf
hosts: files dns mymachines
Add mymachines if it is absent. The manual recommends placing it before resolve or dns, so local container mappings win over an unrelated DNS answer. Preserve the existing actions and sources instead of replacing the whole file. For example, a suitable line is:
hosts: mymachines resolve [!UNAVAIL=return] files dns
Your system may use a different resolver stack. Keep entries such as myhostname if your host already relies on them. Before editing this root-owned file, make a backup and then use an editor:
$ sudo cp -a /etc/nsswitch.conf /etc/nsswitch.conf.before-mymachines
$ sudoedit /etc/nsswitch.conf
Checkpoint: confirm that exactly one active hosts: line contains mymachines, in the position you intended:
$ awk '$1 == "hosts:" {print}' /etc/nsswitch.conf
hosts: mymachines resolve [!UNAVAIL=return] files dns
Changing NSS affects name lookups for programs using glibc on this host. If lookups break, restore the backup only after checking that nobody else has edited the file: sudo cp -a /etc/nsswitch.conf.before-mymachines /etc/nsswitch.conf. That restore can discard later edits, so merge manually when the file is shared by other administration work.
4. Verify the name through NSS
Use getent, which exercises the configured NSS databases. Substitute the exact machine name recorded in step 2:
$ getent ahosts CONTAINER_NAME
169.254.40.164 STREAM CONTAINER_NAME
169.254.40.164 DGRAM
169.254.40.164 RAW
The address and number of lines vary. The useful result is a successful lookup with an address belonging to that container. The installed manual's example also shows IPv6 link-local output, sometimes with an interface scope, so do not require IPv4 specifically. To inspect the addresses known to machinectl:
$ machinectl --max-addresses=3
MACHINE CLASS SERVICE OS VERSION ADDRESSES
CONTAINER_NAME container systemd-nspawn ...
Do not paste the example address into a configuration file. Container addresses can change when the container is restarted.
5. Diagnose a missing result
If getent ahosts CONTAINER_NAME prints nothing, check these boundaries in order:
- Registration:
machinectl list --no-pagermust show the machine as running. A directory under/var/lib/machinesis not, by itself, a registered running machine. - Name: use the
MACHINEcolumn or the name passed tosystemd-nspawn -M. The internal hostname can differ. - Network namespace: nss-mymachines applies only to containers using network namespacing. A container sharing the host network does not gain a separate address through this module.
- Scope: test from the host for its immediate child containers. A nested container sees its own immediate children, not host siblings.
- Lookup order: check the active
hosts:line and query withgetent, not a tool that bypasses glibc NSS.
A name can still fail after configuration if the container is stopped, has no usable network interface, or is outside the module's scope. Adding DNS records or changing firewall rules will not repair an NSS scope mistake. Fix the machine or lookup order first.
Done means
libnss_mymachines.so.2is installed and its systemd package version is known.- The target container is running, registered with
systemd-machined, and uses network namespacing. mymachinesappears once in the intended position on thehosts:line.getent ahosts CONTAINER_NAMEreturns the container's current address.- You understand that the registered machine name, container scope and network namespace determine what can resolve.