Hacker News new | past | comments | ask | show | jobs | submit login

Nowadays, creating a raw chroot is far from simple. Last time I tried, I had to handle the special mount points like /proc and /sys. I can't remember the details, but I believe there were other problems.

In my experience, systemd-nspawn provides a nice alternative. It's mainly a chroot that abstracts the low-level details, and it fixes some security concerns (with cgroups, etc) and adds some nice features: e.g. networking, or `systemctl status` from the host that will display the sub-tree for the processes of the sub-host.




Last time I tried to recover an ubuntu system by booting from a live sub, mounting the drive and chrooting into the target device i was surprised to find out that systemd refuses to work if it detects being run in a chroot.

I was left puzzled.


If you're talking about what happens when you mount the root filesystem, chroot into it, and run systemctl then you're essentially asking to break out of the chroot and communicate to the service manager outside the chroot which almost always doesn't make sense.

The only time this is reasonable is when a container needs to manage services on the host a la what Portainer does for Docker.

You have a lot of options for accomplishing what you want.

* To run a service with a given root filesystem add RootFilesystem=/path to your unit file.

* Run a service from an image of a root filesystem use systemd portable services.

* To run your service using the init system in your root filesystem (could be systemd but doesn't have to be) use systemd-nspawn --boot.


you know, I just wanted to run services from within the chroot, like you could do in the pre-systemd era.

I mean, as long as you have /proc, /sys and etc bind-mounted you should be okay, right ?


Right, but what you're describing as running a pre-systemd "service" is really just "run a shell script that sources some environment files and then double forks".

Running a systemd service means talking to the /org/freedesktop/systemd1 object on the system bus typically listening on /run/dbus/system_bus_socket and asking it to start your service. This is all that systemctl really does.

    mkdir ./rootfs
    curl -O  https://cloud-images.ubuntu.com/minimal/releases/bionic/release/ubuntu-18.04-minimal-cloudimg-amd64-root.tar.xz | tar -xJPC ./rootfs
    mount -o bind /proc ./rootfs/proc
    mount -o bind /sys ./rootfs/sys
    mkdir ./rootfs/run/dbus
    mkdir ./rootfs/run/systemd
    mount -o bind /run/dbus ./rootfs/dbus
    mount -o bind /run/systemd ./rootfs/systemd
    chroot ./rootfs bash
    # See that it works just by sending dbus messages.
    dbus-send --system --print-reply --type=method_call --dest=org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager.ListUnits
    # Now do the same with systemctl.
    export SYSTEMD_IGNORE_CHROOT=true
    systemctl list-units
THIS IS ALMOST CERTAINLY NOT WHAT YOU WANT. You're just talking to the host systemd. You won't see any of the services in your chroot since how could systemd know about them? Your chrooted root is also now just root on the host. Just use systemd-nspawn.

    # undo all the bind mount junk.
    chroot ./rootfs bash
    useradd ubuntu -G sudo
    passwd ubuntu
    exit
    cd ./rootfs
    systemd-nspawn -x --private-network --boot
    # login
    sudo systemctl list-units


This was very informative, thank you.


Nothing a shell script wrapper can't setup for you -- arch linux provides an arch-chroot which handles exactly that.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: