📜 ⬆️ ⬇️

Systemd and Containers: Introduction to systemd-nspawn

PR-1505-3

Containerization today is one of the most relevant topics. The number of publications about such popular tools as LXC or Docker is estimated in thousands, if not tens of thousands.
In this article, we would like to discuss another solution, about which there are so far few publications in Russian. It is about systemd-nspawn - a tool for creating isolated environments, which is one of the components of systemd. And fixing systemd as a standard in the Linux world is already a fait accompli. In light of this fact, there is every reason to believe that in the near future the scope of systemd-nspawn will expand significantly, and it is worth getting to know this tool more closely now.


Systemd-nspawn: general information


')
The name systemd-nspawn is short for namespaces spawn. Already from this name it follows that systemd-nspawn manages only the isolation of processes, but at the same time cannot isolate resources (however this can be done by means of systemd itself, which is discussed below).

Using systemd-nspawn, you can create a completely isolated environment in which pseudo-file systems / proc and / sys will be automatically mounted, as well as an isolated loopback interface and a separate namespace for process identifiers (PID), within which you can run an OS based on Linux kernel.

There is no special repository of images, as in Docker, in systemd-nspawn. To create and download images, you can use any third-party tools. The formats tar, raw, qcow2 and dkr are supported (dkr are images for Docker; in the systemd-nspawn documentation, this is not explicitly written about this, and its authors diligently avoid the word Docker). Work with images is carried out on the basis of the file system BTRFS .

Run in a Debian container



Introduction to systemd-nspawn will begin with a simple but illustrative practical example. On the server running the Fedora OS, we will create an isolated environment in which the Debian OS will be running. All command examples below are for Fedora 22 with systemd version 219; other Linux distributions and other systemd versions may have different commands.

Let's start by installing the necessary dependencies:

sudo dnf install debootstrap bridge-utils 


Then create a file system for the future container:

 sudo debootstrap --arch=amd64 jessie /var/lib/machines/container1/ 


Upon completion of all preparatory work, you can proceed to launch the container:

 sudo systemd-nspawn -D /var/lib/machines/container1/ --machine test_container 


The guest operating system prompt appears on the console:

 root@test_container 


Set the root password for it:

 passwd Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully 


Exit the container by pressing the key combination Ctrl +]]], and then execute the following command:

 sudo systemd-nspawn -D /var/lib/machines/container1/ --machine test_container -b 


It contains the -b (or −−boot) flag, which indicates that when you start an instance of the operating system in a container, you need to execute init with the launch of all daemons. This flag can only be used if a systemd system is running in the container. Otherwise, system booting is not guaranteed.

Upon completion of all specified operations, the system will offer to enter a login and password.
So, a full-fledged OS in an isolated environment is running. Now we need to set up a network for it, Exit the container and create a bridge through which it will connect to the interface on the main host:

 sudo brctl addbr cont-bridge 


Assign an IP address to this bridge:

 ip aa [IP-] dev cont-bridge 


After that execute the command:

 sudo systemd-nspawn -D /var/lib/machines/container1/ --machine test_container --network-bridge=cont-bridge -b 


To configure the network, you can also use the −− network-ipvlan option, which will connect the container with the specified interface on the main host using ipvlan:

 sudo systemd-nspawn -D /var/lib/machines/container1/ --machine test_container -b --network-ipvlan=[ ] 


We start the container as a service



With the help of systemd, you can configure the automatic launch of containers when the system boots. To do this, add the following configuration file to the / etc / systemd / system directory:

 [Unit] Description=Test Container [Service] LimitNOFILE=100000 ExecStart=/usr/bin/systemd-nspawn --machine=test_container --directory=/var/lib/machines/container1/ -b --network-ipvlan=[ ] Restart=always [Install] Also=dbus.service 


Let's comment on the given fragment. In the [Description] section, we simply specify the name of the container. In the [Service] section, we first set a limit on the number of open files in the container (LimitNOFILE), then specify the command to start the container with the necessary options (ExecStart). Specifying Restart = always means that the container needs to be restarted in the event of a “crash”. In the [Install] section, an additional unit is specified that should be added to the autorun on the host (in our case, this is the D-Bus interprocess communication system).

Save the changes in the configuration file and execute the command:

 sudo systecmctl start test_container 


You can start the container as a service in another, simpler way. In systemd there is a configuration file for automatic launch of containers placed in the / var / lib / machines directory. You can activate the launch based on this stub by using the following commands:

 sudo systemctl enable machine.target mv ~/test_container /var/lib/machines/test_container sudo systemctl enable systemd-nspawn@test_container.service 


Container management: machinectl utility



Containers can be managed using the machinectl utility. A brief look at its main options.

List all containers available in the system:

 sudo machinectl list 


View information about the status of the container:

 sudo machinectl status test_container 


Enter container:

 sudo machinectl login test_container 


Reload container:

 sudo machinectl reboot test_container 


Stop container:

 sudo machinectl poweroff test_container 


The last command will work if the systemd OS compatible with the systemd is installed in the container. For operating systems using sysvinit, you need to use the terminate option.
We only talked about the most basic features of the machinectl utility; detailed instructions for its use can be found, for example, here .

Loading images



We have already said that using systemd-nspawn, you can run images of any other formats. However, there is one important condition: working with images is possible only on the basis of the BTRFS file system, which must be mounted to the / var / lib / machines directory:

 sudo dnf install btrfs-progs mkfs.btrs /dev/sdb mount /dev/sdb /var/lib/machines mount | grep btrfs dev/sdb on /var/lib/machines type btrfs (rw,relatime,seclabel,space_cache) 


If there is no free disk, BTRFS can be made in the file.
In newer versions of systemd, the ability to load images is supported out of the box, and BTRFS does not need to be mounted.

Let's try to download the Docker image:

 sudo machinectl pull-dkr --verify=no library/redis --dkr-index-url=https://index.docker.io 


Running a container based on a loaded image is easy:

 sudo systemd-nspawn --machine redis 


View container logs



Information about all events occurring inside containers is recorded in logs. Logging settings can be set directly when creating a container using the option
−−link-journal, for example:

 sudo systemd-nspawn -D /var/lib/machines/container1/ --machine test_container -b --link-journal=host 


The above command indicates that the container logs will be stored on the main host in the / var / log / journal / machine-id directory. If the −−link-journal = guest option is set, all the logs will be stored in a container in the / var / log / journal / machine-id directory, and a symbolic link will be created on the main host in a directory with the same address. The option −−link-journal will only work if a systemd system is running in a container. Otherwise, correct logging is not guaranteed.

You can view information about the container starts and stops using the journalctl utility, which we already wrote about in one of the previous publications :

  journalctl -u test_container.service 


The journalctl provides the ability to view event logs inside the container.
To do this, use the -M option (here is a small piece of output):

 journalctl -M test_container Sep 18 11:50:21 octavia.localdomain systemd-journal[16]: Runtime journal is using 8.0M (max allowed 197.6M, trying to leave 296.4M free of 1.9G available <E2><86><92> current limit 197.6M). Sep 18 11:50:21 octavia.localdomain systemd-journal[16]: Runtime journal is using 8.0M (max allowed 197.6M, trying to leave 296.4M free of 1.9G available <E2><86><92> current limit 197.6M). Sep 18 11:50:21 octavia.localdomain systemd-journal[16]: Journal started Sep 18 11:50:21 octavia.localdomain systemd[1]: Starting Slices. Sep 18 11:50:21 octavia.localdomain systemd[1]: Reached target Slices. Sep 18 11:50:21 octavia.localdomain systemd[1]: Starting Remount Root and Kernel File Systems... Sep 18 11:50:21 octavia.localdomain systemd[1]: Started Remount Root and Kernel File Systems. Sep 18 11:50:21 octavia.localdomain systemd[1]: Started Various fixups to make systemd work better on Debian. 


Resource allocation



The main features of systemd-nspawn we reviewed. There remains one important point: the allocation of resources to containers. As noted above, systemd-nspawn does not isolate resources. You can limit the resource consumption for the container using systemctl, for example:

 sudo systemctl set-property [ ] CPUShares=200 CPUQuota=30% MemoryLimit=500M 


Resource limits for the container can be specified in the unit file, in the [Slice] section.

Conclusion



Systemd-nspawn is an interesting and promising tool. Among its undoubted advantages worth highlighting:



Of course, it’s too early to talk about the full use of systemd-nspawn in production: the tool is still in the “raw” state and is only suitable for testing and experiments. However, as systemd continues to spread, it’s worth waiting for systemd-nspawn improvements.

Naturally, within the framework of the review article it is impossible to tell absolutely everything. Comments are welcome any questions, comments and additions.
If we missed some details or did not tell us about some interesting systemd-nspawn features - write us and we will definitely complete our review.
And if any of you use systemd-nspawn, we invite you to share your experience.

Readers who for one reason or another can not leave comments here are invited to our blog .

Source: https://habr.com/ru/post/271957/


All Articles