]> git.ipfire.org Git - thirdparty/systemd.git/blame - docs/PORTABLE_SERVICES.md
resolved: only attempt non-answer SOA RRs if they are parents of our query
[thirdparty/systemd.git] / docs / PORTABLE_SERVICES.md
CommitLineData
44d565ed
LP
1# Portable Services Introduction
2
3This systemd version includes a preview of the "portable service"
4concept. "Portable Services" are supposed to be an incremental improvement over
5traditional system services, making two specific facets of container management
6available to system services more readily. Specifically:
7
81. The bundling of applications, i.e. packing up multiple services, their
9 binaries and all their dependencies in a single image, and running them
10 directly from it.
11
122. Stricter default security policies, i.e. sand-boxing of applications.
13
14The primary tool for interfacing with "portable services" is the new
15"portablectl" program. It's currently shipped in /usr/lib/systemd/portablectl
16(i.e. not in the `$PATH`), since it's not yet considered part of the officially
17supported systemd interfaces — it's a preview still after all.
18
19Portable services don't bring anything inherently new to the table. All they do
20is put together known concepts in a slightly nicer way to cover a specific set
21of use-cases in a nicer way.
22
991b4350 23## So, what *is* a "Portable Service"?
44d565ed
LP
24
25A portable service is ultimately just an OS tree, either inside of a directory
26tree, or inside a raw disk image containing a Linux file system. This tree is
27called the "image". It can be "attached" or "detached" from the system. When
28"attached" specific systemd units from the image are made available on the host
29system, then behaving pretty much exactly like locally installed system
30services. When "detached" these units are removed again from the host, leaving
31no artifacts around (except maybe messages they might have logged).
32
33The OS tree/image can be created with any tool of your choice. For example, you
34can use `dnf --installroot=` if you like, or `debootstrap`, the image format is
35entirely generic, and doesn't have to carry any specific metadata beyond what
36distribution images carry anyway. Or to say this differently: the image format
37doesn't define any new metadata as unit files and OS tree directories or disk
38images are already sufficient, and pretty universally available these days. One
39particularly nice tool for creating suitable images is
40[mkosi](https://github.com/systemd/mkosi), but many other existing tools will
41do too.
42
43If you so will, "Portable Services" are a nicer way to manage chroot()
44environments, with better security, tooling and behavior.
45
991b4350 46## Where's the difference to a "Container"?
44d565ed
LP
47
48"Container" is a very vague term, after all it is used for
49systemd-nspawn/LXC-type OS containers, for Docker/rkt-like micro service
50containers, and even certain 'lightweight' VM runtimes.
51
52The "portable service" concept ultimately will not provide a fully isolated
53environment to the payload, like containers mostly intend to. Instead they are
54from the beginning more alike regular system services, can be controlled with
55the same tools, are exposed the same way in all infrastructure and so on. Their
56main difference is that the use a different root directory than the rest of the
57system. Hence, the intention is not to run code in a different, isolated world
58from the host — like most containers would do it —, but to run it in the same
59world, but with stricter access controls on what the service can see and do.
60
61As one point of differentiation: as programs run as "portable services" are
62pretty much regular system services, they won't run as PID 1 (like Docker would
63do it), but as normal process. A corollary of that is that they aren't supposed
64to manage anything in their own environment (such as the network) as the
65execution environment is mostly shared with the rest of the system.
66
67The primary focus use-case of "portable services" is to extend the host system
68with encapsulated extensions, but provide almost full integration with the rest
69of the system, though possibly restricted by effective security knobs. This
70focus includes system extensions otherwise sometimes called "super-privileged
71containers".
72
73Note that portable services are only available for system services, not for
74user services. i.e. the functionality cannot be used for the stuff
75bubblewrap/flatpak is focusing on.
76
991b4350 77## Mode of Operation
44d565ed
LP
78
79If you have portable service image, maybe in a raw disk image called
80`foobar_0.7.23.raw`, then attaching the services to the host is as easy as:
81
82```
83# /usr/lib/systemd/portablectl attach foobar_0.7.23.raw
84```
85
86This command does the following:
87
881. It dissects the image, checks and validates the `/etc/os-release` data of
89 the image, and looks for all included unit files.
90
912. It copies out all unit files with a suffix of `.service`, `.socket`,
92 `.target`, `.timer` and `.path`. whose name begins with the image's name
93 (with the .raw removed), truncated at the first underscore (if there is
94 one). This prefix name generated from the image name must be followed by a
95 ".", "-" or "@" character in the unit name. Or in other words, given the
96 image name of `foobar_0.7.23.raw` all unit files matching
97 `foobar-*.{service|socket|target|timer|path}`,
98 `foobar@.{service|socket|target|timer|path}` as well as
99 `foobar.*.{service|socket|target|timer|path}` and
100 `foobar.{service|socket|target|timer|path}` are copied out. These unit files
83f72cd6
LP
101 are placed in `/etc/systemd/system.attached/` (which is part of the normal
102 unit file search path of PID 1, and thus loaded exactly like regular unit
103 files). Within the images the unit files are looked for at the usual
104 locations, i.e. in `/usr/lib/systemd/system/` and `/etc/systemd/system/` and
105 so on, relative to the image's root.
44d565ed
LP
106
1073. For each such unit file a drop-in file is created. Let's say
108 `foobar-waldo.service` was one of the unit files copied to
83f72cd6
LP
109 `/etc/systemd/system.attached/`, then a drop-in file
110 `/etc/systemd/system.attached/foobar-waldo.service.d/20-portable.conf` is
111 created, containing a few lines of additional configuration:
44d565ed
LP
112
113 ```
114 [Service]
115 RootImage=/path/to/foobar.raw
116 Environment=PORTABLE=foobar
117 LogExtraFields=PORTABLE=foobar
118 ```
119
1204. For each such unit a "profile" drop-in is linked in. This "profile" drop-in
121 generally contains security options that lock down the service. By default
122 the `default` profile is used, which provides a medium level of
123 security. There's also `trusted` which runs the service at the highest
b99bfb13 124 privileges, i.e. host's root and everything. The `strict` profile comes with
44d565ed
LP
125 the toughest security restrictions. Finally, `nonetwork` is like `default`
126 but without network access. Users may define their own profiles too (or
127 modify the existing ones)
128
129And that's already it.
130
131Note that the images need to stay around (and the same location) as long as the
132portable service is attached. If an image is moved, the `RootImage=` line
133written to the unit drop-in would point to an non-existing place, and break the
134logic.
135
136The `portablectl detach` command executes the reverse operation: it looks for
137the drop-ins and the unit files associated with the image, and removes them
138again.
139
140Note that `portable attach` won't enable or start any of the units it copies
141out. This still has to take place in a second, separate step. (That said We
142might add options to do this automatically later on.).
143
991b4350 144## Requirements on Images
44d565ed
LP
145
146Note that portable services don't introduce any new image format, but most OS
147images should just work the way they are. Specifically, the following
148requirements are made for an image that can be attached/detached with
149`portablectl`.
150
1511. It must contain a binary (and its dependencies) that shall be invoked,
152 including all its dependencies. If binary code, the code needs to be
153 compiled for an architecture compatible with the host.
154
1552. The image must either be a plain sub-directory (or btrfs subvolume)
156 containing the binaries and its dependencies in a classic Linux OS tree, or
157 must be a raw disk image either containing only one, naked file system, or
158 an image with a partition table understood by the Linux kernel with only a
159 single partition defined, or alternatively, a GPT partition table with a set
160 of properly marked partitions following the [Discoverable Partitions
161 Specification](https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/).
162
1633. The image must at least contain one matching unit file, with the right name
164 prefix and suffix (see above). The unit file is searched in the usual paths,
165 i.e. primarily /etc/systemd/system/ and /usr/lib/systemd/system/ within the
166 image. (The implementation will check a couple of other paths too, but it's
167 recommended to use these two paths.)
168
1694. The image must contain an os-release file, either in /etc/os-release or
170 /usr/lib/os-release. The file should follow the standard format.
171
172Note that generally images created by tools such as `debootstrap`, `dnf
173--installroot=` or `mkosi` qualify for all of the above in one way or
174another. If you wonder what the most minimal image would be that complies with
175the requirements above, it could consist of this:
176
177```
178/usr/bin/minimald # a statically compiled binary
179/usr/lib/systemd/minimal-test.service # the unit file for the service, with ExecStart=/usr/bin/minimald
180/usr/lib/os-release # an os-release file explaining what this is
181```
182
183And that's it.
184
185Note that qualifying images do not have to contain an init system of their
186own. If they do, it's fine, it will be ignored by the portable service logic,
187but they generally don't have to, and it might make sense to avoid any, to keep
188images minimal.
189
190Note that as no new image format or metadata is defined, it's very
191straight-forward to define images than can be made use of it a number of
192different ways. For example, by using `mkosi -b` you can trivially build a
193single, unified image that:
194
1951. Can be attached as portable service, to run any container services natively
196 on the host.
197
1982. Can be run as OS container, using `systemd-nspawn`, by booting the image
199 with `systemd-nspawn -i -b`.
200
2013. Can be booted directly as VM image, using a generic VM executor such as
202 `virtualbox`/`qemu`/`kvm`
203
2044. Can be booted directly on bare-metal systems.
205
206Of course, to facilitate 2, 3 and 4 you need to include an init system in the
207image. To facility 3 and 4 you also need to include a boot loader in the
208image. As mentioned `mkosi -b` takes care of all of that for you, but any other
209image generator should work too.
210
991b4350 211## Execution Environment
44d565ed
LP
212
213Note that the code in portable service images is run exactly like regular
214services. Hence there's no new execution environment to consider. Oh, unlike
215Docker would do it, as these are regular system services they aren't run as PID
2161 either, but with regular PID values.
217
991b4350 218## Access to host resources
44d565ed
LP
219
220If services shipped with this mechanism shall be able to access host resources
221(such as files or AF_UNIX sockets for IPC), use the normal `BindPaths=` and
222`BindReadOnlyPaths=` settings in unit files to mount them in. In fact the
223`default` profile mentioned above makes use of this to ensure
224`/etc/resolv.conf`, the D-Bus system bus socket or write access to the logging
225subsystem are available to the service.
226
991b4350 227## Instantiation
44d565ed
LP
228
229Sometimes it makes sense to instantiate the same set of services multiple
230times. The portable service concept does not introduce a new logic for this. It
231is recommended to use the regular unit templating of systemd for this, i.e. to
232include template units such as `foobar@.service`, so that instantiation is as
233simple as:
234
235```
236# /usr/lib/systemd/portablectl attach foobar_0.7.23.raw
237# systemctl enable --now foobar@instancea.service
238# systemctl enable --now foobar@instanceb.service
239
240```
241
242The benefit of this approach is that templating works exactly the same for
243units shipped with the OS itself as for attached portable services.
244
991b4350 245## Immutable images with local data
44d565ed
LP
246
247It's a good idea to keep portable service images read-only during normal
248operation. In fact all but the `trusted` profile will default to this kind of
249behaviour, by setting the `ProtectSystem=strict` option. In this case writable
250service data may be placed on the host file system. Use `StateDirectory=` in
251the unit files to enable such behaviour and add a local data directory to the
252services copied onto the host.