Skip to content

Commit dd09f47

Browse files
authored
Merge pull request #503 from cgwalters/doc-container-layers
docs: Add some description of container storage
2 parents 649c5eb + 79b1bc3 commit dd09f47

File tree

3 files changed

+97
-0
lines changed

3 files changed

+97
-0
lines changed

docs/book.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,9 @@ language = "en"
44
multilingual = false
55
src = "src"
66
title = "bootc"
7+
8+
[preprocessor.mermaid]
9+
command = "mdbook-mermaid"
10+
11+
[output.html]
12+
additional-js = ["mermaid.min.js", "mermaid-init.js"]

docs/src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
- [Image layout](bootc-images.md)
4040
- [Filesystem](filesystem.md)
4141
- [Filesystem: sysroot](filesystem-sysroot.md)
42+
- [Container storage](filesystem-storage.md)
4243

4344
# More information
4445

docs/src/filesystem-storage.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Container storage
2+
3+
The bootc project uses [ostree](https://github.com/ostreedev/ostree/) and specifically
4+
the [ostree-rs-ext](https://github.com/ostreedev/ostree-rs-ext/) Rust library
5+
which handles storage of container images on top of an ostree-based system.
6+
7+
## Architecture
8+
9+
```mermaid
10+
flowchart TD
11+
bootc --- ostree-rs-ext --- ostree-rs --- ostree
12+
ostree-rs-ext --- containers-image-proxy-rs --- skopeo --- containers/image
13+
```
14+
15+
There were two high level goals that drove the design of the current system
16+
architecture:
17+
18+
- Support seamless in-place migrations from existing ostree systems
19+
- Avoid requiring deep changes to the podman stack
20+
21+
A simple way to explain the current architecture is that podman uses
22+
two Go libraries:
23+
24+
- <https://github.com/containers/image>
25+
- <https://github.com/containers/storage>
26+
27+
Whereas ostree uses a custom container storage, not `containers/storage`.
28+
29+
## Mapping container images to ostree
30+
31+
[OCI images](https://github.com/opencontainers/image-spec) are effectively
32+
just a standardized format of tarballs wrapped with JSON - specifically
33+
"layers" of tarballs.
34+
35+
The ostree-rs-ext project maps layers to OSTree commits. Each layer
36+
is stored separately, under an ostree "ref" (like a git branch)
37+
under the `ostree/container/` namespace:
38+
39+
```
40+
$ ostree refs ostree/container
41+
```
42+
43+
### Layers
44+
45+
The `ostree/container/blob` namespace tracks storage of a container layer
46+
identified by its blob ID (sha256 digest).
47+
48+
### Images
49+
50+
At the current time, ostree always boots into a "flattened" filesystem
51+
tree. This is generated as both a hardlinked checkout as well as
52+
a composefs image.
53+
54+
The flattened tree is constructed and committed into the
55+
`ostree/container/image` namespace. The commit metadata also includes
56+
the OCI manifest and config objects.
57+
58+
This is implmented in the [ostree-rs-ext/container module](https://docs.rs/ostree-ext/latest/ostree_ext/container/index.html).
59+
60+
### SELinux labeling
61+
62+
A major wrinkle is supporting SELinux labeling. The labeling configuration
63+
is defined as regular expressions included in `/etc/selinux/$policy/contexts/`.
64+
65+
The current implementation relies on the fact that SELinux labels for
66+
base images were pre-computed. The first step is to check out the "ostree base"
67+
layers for the base image.
68+
69+
All derived layers have labels computed from the base image policy. This
70+
causes a known bug where derived layers can't include custom policy:
71+
<https://github.com/ostreedev/ostree-rs-ext/issues/510>
72+
73+
### Origin files
74+
75+
ostree has the concept of an `origin` file which defines the source
76+
of truth for upgrades. The container image reference for each deployment
77+
is included in its origin.
78+
79+
## Booting
80+
81+
A core aspect of this entire design is that once a container image is
82+
fetched into the ostree storage, from there on it just appears as
83+
an "ostree commit", and so all code built on top can work with it.
84+
85+
For example, the `ostree-prepare-root.service` which runs in
86+
the initramfs is currently agnostic to whether the filesystem tree originated
87+
from an OCI image or some other mechanism; it just targets a
88+
prepared flattened filesystem tree.
89+
90+
This is what is referenced by the `ostree=` kernel commandline.

0 commit comments

Comments
 (0)