Ok, so, for what it's worth, the following was successful for me:
sudo systemd-nspawn -bxD/
Practically identical to yours, except I don't give the machine
a name and I get an -x
ephemeral btrfs snapshot of my /
for the container's root.
That brought up the container's getty
on my terminal's pty and I logged in to login
and all.
I confess I was a bit stumped for a little while, but after a little poking at systemctl
in the container w/ zsh
<tab> completion I came up with (run from within the container):
systemctl stop console-getty.service
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to manage system services or other units.
Authenticating as: mikeserv
Password:
==== AUTHENTICATION COMPLETE ===
Which got the machine to surrender its terminal control. The only thing is, I started that with sudo
- which also gets its own layer of terminal control to authenticate in the first place. This left me with a blank terminal, and no amount of kill -CONT "$(pgrep ksh)"
was doing me any good. And so I was again stumped for a moment or two, but (in another terminal)...
sudo fuser -v /dev/pts/*
USER PID ACCESS COMMAND
/dev/pts/0: mikeserv 8347 F.... zsh
root 18003 F.... sudo
/dev/pts/13: mikeserv 9553 F.... zsh
mikeserv 16838 F.... ksh
root 17657 F.... sudo
root 17658 F.... systemd-nspawn
/dev/pts/14: root 17675 F.... systemd
Gave me the above list, and so I thought - what the hell?
sudo kill -STOP 17657
And - lo and behold - I had ksh
back in the original terminal. To wrap it up, I needed to verify I could still access the machine
, though, of course, else it would be useless:
machinectl -l
MACHINE CLASS SERVICE
localhost-35ceaa76b1306897 container nspawn
Ok...
sudo machinectl login localhost-35ceaa76b1306897
Connected to machine localhost-35ceaa76b1306897.
Press ^] three times within 1s to exit session.
Arch Linux 4.0.7-2-ARCH (pts/0)
localhost-35ceaa76b1306897 login:
And I got another getty
on another terminal!
systemd-nspawn
handles permissions for devices through cgroups. By default, any container is granted with permissions only for common devices like /dev/null
, /dev/zero
, etc, and additionally to any device passed directly to --bind
argument like --bind=/dev/vcs
. This won't work with USB because /dev/bus/usb
is a directory.
To grant permission for currently running container named my_container
(supposedly you started it with systemd-nspawn
directly from command line) execute as root:
$ echo 'c 189:* rwm' > \
/sys/fs/cgroup/devices/machine.slice/machine-my_container/devices.allow
c 189:* rwm
means read write modify permissions for any character device with type (identificator) 189 and any subtype. You can find type and subtype of device with file
:
$ file /dev/bus/usb/002/002
This permission will only last while container is running.
If you are using systemd-nspawn@.service
or want to persist permissions with it, create
/etc/systemd/system/systemd-nspawn@.service.d/override.conf
or
/etc/systemd/system/systemd-nspawn@my_container.service.d/override.conf
(depending on whether you want access to USB from any systemd-nspawn
container or only from my_container
correspondingly) with the following content:
[Service]
DeviceAllow=char-usb_device rwm
usb_device
is an alias. You can find other in /proc/devices
.
Best Answer
The problem is Fedora's firewalld. It seems nspawn was never integrated with firewalld. (nspawn isn't correctly integrated with Fedora's SELinux policy either).
As mentioned in the question, libvirt is working fine :). We can use the same trick people discovered for running containers with LXC on Fedora.
Update: the workaround stopped working after I upgraded to Fedora 30.
Run systemd-nspawn with the option
--network-bridge virbr0
. Instead of relying onsystemd-networkd
, this leverageslibvirtd.service
. The latter service is already started by default on Fedora. In the guest, set up your preferred DHCP client as usual.DNS resolution when using systemd-networkd as DHCP client
Using
systemd-networkd
as a DHCP client might accidentally work on its own, if you may have a left-over/etc/resolv.conf
from a previous container boot. But you can't rely on this working in general. It's really designed to be run together withsystemd-resolved.service
.In turn, systemd-resolved is intended to be used with
nss-resolve
. However this is not essential AIUI.