systemd-machined is actually a surprisingly effective way to manage containers and VMs without needing to learn a whole new, specialized toolchain.
Let’s see it in action. Imagine you’ve got a small LXC container running. You can interact with it using familiar systemd commands, as if it were just another service on your host.
# List all managed machines (containers/VMs)
sudo machinectl list
# Show details about a specific machine (e.g., my-container)
sudo machinectl show my-container
# Start a machine
sudo machinectl start my-container
# Stop a machine
sudo machinectl stop my-container
# Enter a machine's shell
sudo machinectl shell my-container
# Mount a machine's root filesystem on the host
sudo machinectl mount my-container
# This will output something like:
# Mount point: /run/machine/my-container
# Unmount the machine's root filesystem
sudo machinectl umount my-container
The core problem systemd-machined solves is providing a unified, system-level interface for ephemeral compute resources like containers and VMs. Instead of juggling docker, lxc-attach, virsh, and various cloud provider CLIs, you get a single point of control that integrates directly with the rest of your system’s service management. It leverages existing systemd units and concepts, making it feel much more natural if you’re already familiar with systemd.
Internally, systemd-machined works by registering and managing machines as special types of systemd units. When you start a container or VM, machined creates corresponding machinectl units. These units are responsible for managing the lifecycle of the machine, including its network namespace, storage mounts, and execution environment. It uses systemd-run and systemd-nspawn under the hood for many operations, abstracting away the direct nspawn commands.
The key levers you control are the machinectl commands themselves, which map directly to actions on the managed machines. You can start, stop, list, and inspect them. Crucially, machined also handles network configuration by setting up virtual network interfaces and routing rules, often creating a private network for your machines by default. It can also manage storage, allowing you to mount machine filesystems directly on the host for inspection or modification.
One of the most powerful, yet often overlooked, aspects of systemd-machined is its integration with systemd-networkd and systemd-resolved. When a machine is started, machined can automatically configure networking for it. This often involves creating a bridge interface on the host and assigning an IP address to the machine from a private subnet managed by machined. If systemd-resolved is active, machined can also ensure that DNS resolution works correctly within the container or VM, often by passing through the host’s DNS configuration or setting up a dedicated DNS stub. This seamless network integration means containers and VMs can often communicate with each other and the outside world with minimal manual setup, relying on the host’s existing network stack and systemd’s network management capabilities.
The next concept you’ll likely encounter is how to integrate these managed machines into your existing systemd service dependencies, making them part of your boot process or dependent on other host services.