mirror of
https://github.com/systemd/systemd.git
synced 2024-11-23 10:13:34 +08:00
docs/BUILDING_IMAGES: format text
This commit is contained in:
parent
e9a55babcd
commit
59652fff30
@ -9,12 +9,14 @@ SPDX-License-Identifier: LGPL-2.1-or-later
|
|||||||
|
|
||||||
In many scenarios OS installations are shipped as pre-built images, that
|
In many scenarios OS installations are shipped as pre-built images, that
|
||||||
require no further installation process beyond simple `dd`-ing the image to
|
require no further installation process beyond simple `dd`-ing the image to
|
||||||
disk and booting it up. When building such "golden" OS images for
|
disk and booting it up.
|
||||||
|
When building such "golden" OS images for
|
||||||
`systemd`-based OSes a few points should be taken into account.
|
`systemd`-based OSes a few points should be taken into account.
|
||||||
|
|
||||||
Most of the points described here are implemented by the
|
Most of the points described here are implemented by the
|
||||||
[`mkosi`](https://github.com/systemd/mkosi) OS image builder developed and
|
[`mkosi`](https://github.com/systemd/mkosi) OS image builder developed and
|
||||||
maintained by the systemd project. If you are using or working on another image
|
maintained by the systemd project.
|
||||||
|
If you are using or working on another image
|
||||||
builder it's recommended to keep the following concepts and recommendations in
|
builder it's recommended to keep the following concepts and recommendations in
|
||||||
mind.
|
mind.
|
||||||
|
|
||||||
@ -24,28 +26,25 @@ Typically the same OS image shall be deployable in multiple instances, and each
|
|||||||
instance should automatically acquire its own identifying credentials on first
|
instance should automatically acquire its own identifying credentials on first
|
||||||
boot. For that it's essential to:
|
boot. For that it's essential to:
|
||||||
|
|
||||||
1. Remove the
|
1. Remove the [`/etc/machine-id`](https://www.freedesktop.org/software/systemd/man/machine-id.html)
|
||||||
[`/etc/machine-id`](https://www.freedesktop.org/software/systemd/man/machine-id.html)
|
file or write the string `uninitialized\n` into it.
|
||||||
file or write the string `uninitialized\n` into it. This file is supposed to
|
This file is supposed to carry a 128-bit identifier unique to the system.
|
||||||
carry a 128-bit identifier unique to the system. Only when it is reset it
|
Only when it is reset it will be auto-generated on first boot and thus be truly unique.
|
||||||
will be auto-generated on first boot and thus be truly unique. If this file
|
If this file is not reset, and carries a valid ID every instance of the system will come
|
||||||
is not reset, and carries a valid ID every instance of the system will come
|
|
||||||
up with the same ID and that will likely lead to problems sooner or later,
|
up with the same ID and that will likely lead to problems sooner or later,
|
||||||
as many network-visible identifiers are commonly derived from the machine
|
as many network-visible identifiers are commonly derived from the machine ID,
|
||||||
ID, for example, IPv6 addresses or transient MAC addresses.
|
for example, IPv6 addresses or transient MAC addresses.
|
||||||
|
|
||||||
2. Remove the `/var/lib/systemd/random-seed` file (see
|
2. Remove the `/var/lib/systemd/random-seed` file(see
|
||||||
[`systemd-random-seed(8)`](https://www.freedesktop.org/software/systemd/man/systemd-random-seed.service.html)),
|
[`systemd-random-seed(8)`](https://www.freedesktop.org/software/systemd/man/systemd-random-seed.service.html)),
|
||||||
which is used to seed the kernel's random pool on boot. If this file is
|
which is used to seed the kernel's random pool on boot.
|
||||||
shipped pre-initialized, every instance will seed its random pool with the
|
If this file is shipped pre-initialized, every instance will seed its random pool with the
|
||||||
same random data that is included in the image, and thus possibly generate
|
same random data that is included in the image, and thus possibly generate
|
||||||
random data that is more similar to other instances booted off the same
|
random data that is more similar to other instances booted off the same image than advisable.
|
||||||
image than advisable.
|
|
||||||
|
|
||||||
3. Remove the `/loader/random-seed` file (see
|
3. Remove the `/loader/random-seed` file (see
|
||||||
[`systemd-boot(7)`](https://www.freedesktop.org/software/systemd/man/systemd-boot.html))
|
[`systemd-boot(7)`](https://www.freedesktop.org/software/systemd/man/systemd-boot.html))
|
||||||
from the UEFI System Partition (ESP), in case the `systemd-boot` boot loader
|
from the UEFI System Partition (ESP), in case the `systemd-boot` boot loader is used in the image.
|
||||||
is used in the image.
|
|
||||||
|
|
||||||
4. It might also make sense to remove
|
4. It might also make sense to remove
|
||||||
[`/etc/hostname`](https://www.freedesktop.org/software/systemd/man/hostname.html)
|
[`/etc/hostname`](https://www.freedesktop.org/software/systemd/man/hostname.html)
|
||||||
@ -69,24 +68,25 @@ The
|
|||||||
logic used to generate
|
logic used to generate
|
||||||
[Boot Loader Specification Type #1](https://uapi-group.org/specifications/specs/boot_loader_specification/#type-1-boot-loader-specification-entries)
|
[Boot Loader Specification Type #1](https://uapi-group.org/specifications/specs/boot_loader_specification/#type-1-boot-loader-specification-entries)
|
||||||
entries by default uses the machine ID as stored in `/etc/machine-id` for
|
entries by default uses the machine ID as stored in `/etc/machine-id` for
|
||||||
naming boot menu entries and the directories in the ESP to place kernel images
|
naming boot menu entries and the directories in the ESP to place kernel images in.
|
||||||
in. This is done in order to allow multiple installations of the same OS on the
|
This is done in order to allow multiple installations of the same OS on the
|
||||||
same system without conflicts. However, this is problematic if the machine ID
|
same system without conflicts. However, this is problematic if the machine ID
|
||||||
shall be generated automatically on first boot: if the ID is not known before
|
shall be generated automatically on first boot: if the ID is not known before
|
||||||
the first boot it cannot be used to name the most basic resources required for
|
the first boot it cannot be used to name the most basic resources required for
|
||||||
the boot process to complete.
|
the boot process to complete.
|
||||||
|
|
||||||
Thus, for images that shall acquire their identity on first boot only, it is
|
Thus, for images that shall acquire their identity on first boot only, it is
|
||||||
required to use a different identifier for naming boot menu entries. To allow
|
required to use a different identifier for naming boot menu entries.
|
||||||
this the `kernel-install` logic knows the generalized *entry* *token* concept,
|
To allow this the `kernel-install` logic knows the generalized *entry* *token* concept,
|
||||||
which can be a freely chosen string to use for identifying the boot menu
|
which can be a freely chosen string to use for identifying the boot menu
|
||||||
resources of the OS. If not configured explicitly it defaults to the machine
|
resources of the OS.
|
||||||
ID. The file `/etc/kernel/entry-token` may be used to configure this string
|
If not configured explicitly it defaults to the machineID.
|
||||||
explicitly. Thus, golden image builders should write a suitable identifier into
|
The file `/etc/kernel/entry-token` may be used to configure this string explicitly.
|
||||||
|
Thus, golden image builders should write a suitable identifier into
|
||||||
this file, for example, the `IMAGE_ID=` or `ID=` field from
|
this file, for example, the `IMAGE_ID=` or `ID=` field from
|
||||||
[`/etc/os-release`](https://www.freedesktop.org/software/systemd/man/os-release.html)
|
[`/etc/os-release`](https://www.freedesktop.org/software/systemd/man/os-release.html)
|
||||||
(also see below). It is recommended to do this before the `kernel-install`
|
(also see below).
|
||||||
functionality is invoked (i.e. before the package manager is used to install
|
It is recommended to do this before the `kernel-install` functionality is invoked (i.e. before the package manager is used to install
|
||||||
packages into the OS tree being prepared), so that the selected string is
|
packages into the OS tree being prepared), so that the selected string is
|
||||||
automatically used for all entries to be generated.
|
automatically used for all entries to be generated.
|
||||||
|
|
||||||
@ -94,16 +94,16 @@ automatically used for all entries to be generated.
|
|||||||
|
|
||||||
`systemd` is designed to be able to come up safely and robustly if the `/var/`
|
`systemd` is designed to be able to come up safely and robustly if the `/var/`
|
||||||
file system or even the entire root file system (with exception of `/usr/`,
|
file system or even the entire root file system (with exception of `/usr/`,
|
||||||
i.e. the vendor OS resources) is empty (i.e. "unpopulated"). With this in mind
|
i.e. the vendor OS resources) is empty (i.e. "unpopulated").
|
||||||
it's relatively easy to build images that only ship a `/usr/` tree, and
|
With this in mind it's relatively easy to build images that only ship a `/usr/` tree, and
|
||||||
otherwise carry no other data, populating the rest of the directory hierarchy
|
otherwise carry no other data, populating the rest of the directory hierarchy
|
||||||
on first boot as needed.
|
on first boot as needed.
|
||||||
|
|
||||||
Specifically, the following mechanisms are in place:
|
Specifically, the following mechanisms are in place:
|
||||||
|
|
||||||
1. The `switch-root` logic in systemd, that is used to switch from the initrd
|
1. The `switch-root` logic in systemd, that is used to switch from the initrd
|
||||||
phase to the host will create the basic OS hierarchy skeleton if missing. It
|
phase to the host will create the basic OS hierarchy skeleton if missing.
|
||||||
will create a couple of directories strictly necessary to boot up
|
It will create a couple of directories strictly necessary to boot up
|
||||||
successfully, plus essential symlinks (such as those necessary for the
|
successfully, plus essential symlinks (such as those necessary for the
|
||||||
dynamic loader `ld.so` to function).
|
dynamic loader `ld.so` to function).
|
||||||
|
|
||||||
@ -136,14 +136,18 @@ Specifically, the following mechanisms are in place:
|
|||||||
remains resolvable, even without `/etc/hosts` around.
|
remains resolvable, even without `/etc/hosts` around.
|
||||||
|
|
||||||
With these mechanisms the hierarchies below `/var/` and `/etc/` can be safely
|
With these mechanisms the hierarchies below `/var/` and `/etc/` can be safely
|
||||||
and robustly populated on first boot, so that the OS can safely boot up. Note
|
and robustly populated on first boot, so that the OS can safely boot up.
|
||||||
that some auxiliary package are not prepared to operate correctly if their
|
Note that some auxiliary package are not prepared to operate correctly if their
|
||||||
configuration data in `/etc/` or their state directories in `/var/` are
|
configuration data in `/etc/` or their state directories in `/var/` are
|
||||||
missing. This can typically be addressed via `systemd-tmpfiles` lines that
|
missing.
|
||||||
ensure the missing files and directories are created if missing. In particular,
|
|
||||||
configuration files that are necessary for operation can be automatically
|
This can typically be addressed via `systemd-tmpfiles` lines that
|
||||||
|
ensure the missing files and directories are created if missing.
|
||||||
|
In particular, configuration files that are necessary for operation can be automatically
|
||||||
copied or symlinked from the `/usr/share/factory/etc/` tree via the `C` or `L`
|
copied or symlinked from the `/usr/share/factory/etc/` tree via the `C` or `L`
|
||||||
line types. That said, we recommend that all packages safely fall back to
|
line types.
|
||||||
|
|
||||||
|
That said, we recommend that all packages safely fall back to
|
||||||
internal defaults if their configuration is missing, making such additional
|
internal defaults if their configuration is missing, making such additional
|
||||||
steps unnecessary.
|
steps unnecessary.
|
||||||
|
|
||||||
@ -156,17 +160,17 @@ manual work might be required to make this scenario work.
|
|||||||
|
|
||||||
Typically, if an image is `dd`-ed onto a target disk it will be minimal:
|
Typically, if an image is `dd`-ed onto a target disk it will be minimal:
|
||||||
i.e. only consist of necessary vendor data, and lack "payload" data, that shall
|
i.e. only consist of necessary vendor data, and lack "payload" data, that shall
|
||||||
be individual to the system, and dependent on host parameters. On first boot,
|
be individual to the system, and dependent on host parameters.
|
||||||
the OS should take possession of the backing storage as necessary, dynamically
|
On first boot, the OS should take possession of the backing storage as necessary, dynamically
|
||||||
using available space. Specifically:
|
using available space. Specifically:
|
||||||
|
|
||||||
1. Additional partitions should be created, that make no sense to ship
|
1. Additional partitions should be created, that make no sense to ship
|
||||||
pre-built in the image. For example, `/tmp/` or `/home/` partitions, or even
|
pre-built in the image.
|
||||||
`/var/` or the root file system (see above).
|
For example, `/tmp/` or `/home/` partitions, or even `/var/` or the root file system (see above).
|
||||||
|
|
||||||
2. Additional partitions should be created that shall function as A/B
|
2. Additional partitions should be created that shall function as A/B
|
||||||
secondaries for partitions shipped in the original image. In other words: if
|
secondaries for partitions shipped in the original image.
|
||||||
the `/usr/` file system shall be updated in an A/B fashion it typically
|
In other words: if the `/usr/` file system shall be updated in an A/B fashion it typically
|
||||||
makes sense to ship the original A file system in the deployed image, but
|
makes sense to ship the original A file system in the deployed image, but
|
||||||
create the B partition on first boot.
|
create the B partition on first boot.
|
||||||
|
|
||||||
@ -191,10 +195,10 @@ it, then format it.
|
|||||||
1. The
|
1. The
|
||||||
[`systemd-repart(8)`](https://www.freedesktop.org/software/systemd/man/systemd-repart.service.html)
|
[`systemd-repart(8)`](https://www.freedesktop.org/software/systemd/man/systemd-repart.service.html)
|
||||||
component may manipulate GPT partition tables automatically on boot, growing
|
component may manipulate GPT partition tables automatically on boot, growing
|
||||||
partitions or adding in partitions taking the backing storage size into
|
partitions or adding in partitions taking the backing storage size into account.
|
||||||
account. It can also encrypt partitions automatically it creates (even bind
|
It can also encrypt partitions automatically it creates (even bind
|
||||||
to TPM2, automatically) and populate partitions from various sources. It
|
to TPM2, automatically) and populate partitions from various sources.
|
||||||
does this all in a robust fashion so that aborted invocations will not leave
|
It does this all in a robust fashion so that aborted invocations will not leave
|
||||||
incompletely set up partitions around.
|
incompletely set up partitions around.
|
||||||
|
|
||||||
2. The
|
2. The
|
||||||
@ -215,8 +219,8 @@ it, then format it.
|
|||||||
|
|
||||||
While a lot of work has gone into ensuring `systemd` systems can safely boot
|
While a lot of work has gone into ensuring `systemd` systems can safely boot
|
||||||
with unpopulated `/etc/` trees, it sometimes is desirable to set a couple of
|
with unpopulated `/etc/` trees, it sometimes is desirable to set a couple of
|
||||||
basic settings *after* `dd`-ing the image to disk, but *before* first boot. For
|
basic settings *after* `dd`-ing the image to disk, but *before* first boot.
|
||||||
this the tool
|
For this the tool
|
||||||
[`systemd-firstboot(1)`](https://www.freedesktop.org/software/systemd/man/systemd-firstboot.html)
|
[`systemd-firstboot(1)`](https://www.freedesktop.org/software/systemd/man/systemd-firstboot.html)
|
||||||
can be useful, with its `--image=` switch. It may be used to set very basic
|
can be useful, with its `--image=` switch. It may be used to set very basic
|
||||||
settings, such as the root password or hostname on an OS disk image or
|
settings, such as the root password or hostname on an OS disk image or
|
||||||
@ -225,36 +229,33 @@ installed block device.
|
|||||||
## Distinguishing First Boot
|
## Distinguishing First Boot
|
||||||
|
|
||||||
For various purposes it's useful to be able to distinguish the first boot-up of
|
For various purposes it's useful to be able to distinguish the first boot-up of
|
||||||
the system from later boot-ups (for example, to set up TPM hardware
|
the system from later boot-ups (for example, to set up TPM hardware specifically, or register a system somewhere).
|
||||||
specifically, or register a system somewhere). `systemd` provides mechanisms to
|
`systemd` provides mechanisms to implement that.
|
||||||
implement that. Specifically, the `ConditionFirstBoot=` and `AssertFirstBoot=`
|
Specifically, the `ConditionFirstBoot=` and `AssertFirstBoot=` settings may be used to conditionalize units to only run on first boot.
|
||||||
settings may be used to conditionalize units to only run on first boot. See
|
See [`systemd.unit(5)`](https://www.freedesktop.org/software/systemd/man/systemd.unit.html#ConditionFirstBoot=)
|
||||||
[`systemd.unit(5)`](https://www.freedesktop.org/software/systemd/man/systemd.unit.html#ConditionFirstBoot=)
|
|
||||||
for details.
|
for details.
|
||||||
|
|
||||||
A special target unit `first-boot-complete.target` may be used as milestone to
|
A special target unit `first-boot-complete.target` may be used as milestone to
|
||||||
safely handle first boots where the system is powered off too early: if the
|
safely handle first boots where the system is powered off too early:
|
||||||
first boot process is aborted before this target is reached, the following boot
|
if the first boot process is aborted before this target is reached, the following boot
|
||||||
process will be considered a first boot, too. Once the target is reached,
|
process will be considered a first boot, too.
|
||||||
subsequent boots will not be considered first boots anymore, even if the boot
|
Once the target is reached, subsequent boots will not be considered first boots anymore, even if the boot
|
||||||
process is aborted immediately after. Thus, services that must complete fully
|
process is aborted immediately after.
|
||||||
before a system shall be considered fully past the first boot should be ordered
|
Thus, services that must complete fully before a system shall be considered fully past the first boot should be ordered before this target unit.
|
||||||
before this target unit.
|
|
||||||
|
|
||||||
Whether a system will come up in first boot state or not is derived from the
|
Whether a system will come up in first boot state or not is derived from the
|
||||||
initialization status of `/etc/machine-id`: if the file already carries a valid
|
initialization status of `/etc/machine-id`:
|
||||||
ID the system is already past the first boot. If it is not initialized yet it
|
if the file already carries a valid ID the system is already past the first boot.
|
||||||
is still considered in the first boot state. For details see
|
If it is not initialized yet it is still considered in the first boot state.
|
||||||
[`machine-id(5)`](https://www.freedesktop.org/software/systemd/man/machine-id.html).
|
For details see [`machine-id(5)`](https://www.freedesktop.org/software/systemd/man/machine-id.html).
|
||||||
|
|
||||||
## Image Metadata
|
## Image Metadata
|
||||||
|
|
||||||
Typically, when operating with golden disk images it is useful to be able to
|
Typically, when operating with golden disk images it is useful to be able to
|
||||||
identify them and their version. For this the two fields `IMAGE_ID=` and
|
identify them and their version.
|
||||||
`IMAGE_VERSION=` have been defined in
|
For this the two fields `IMAGE_ID=` and `IMAGE_VERSION=` have been defined in
|
||||||
[`os-release(5)`](https://www.freedesktop.org/software/systemd/man/os-release.html). These
|
[`os-release(5)`](https://www.freedesktop.org/software/systemd/man/os-release.html).
|
||||||
fields may be accessed from unit files and similar via the `%M` and `%A`
|
These fields may be accessed from unit files and similar via the `%M` and `%A` specifiers.
|
||||||
specifiers.
|
|
||||||
|
|
||||||
Depending on how the images are put together it might make sense to leave the
|
Depending on how the images are put together it might make sense to leave the
|
||||||
OS distribution's `os-release` file as is in `/usr/lib/os-release` but to
|
OS distribution's `os-release` file as is in `/usr/lib/os-release` but to
|
||||||
|
Loading…
Reference in New Issue
Block a user