Skip to content

Commit

Permalink
docs: add documentation for Image Factory
Browse files Browse the repository at this point in the history
Document Image Factory in general, and also provide specific examples
for boot assets.

Secure Boot section is not covered, as we don't have Secure Boot support
(yet) in the Image Factory.

Signed-off-by: Andrey Smirnov <[email protected]>
  • Loading branch information
smira committed Nov 2, 2023
1 parent 2e78513 commit eb94468
Show file tree
Hide file tree
Showing 4 changed files with 610 additions and 8 deletions.
177 changes: 177 additions & 0 deletions website/content/v1.5/learn-more/image-factory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
---
title: "Image Factory"
weight: 55
description: "Image Factory generates customized Talos Linux images based on configured schematics."
---

The Image Factory provides a way to download Talos Linux artifacts.
Artifacts can be generated with customizations defined by a "schematic".
A schematic can be applied to any of the versions of Talos Linux offered by the Image Factory to produce a "model".

The following assets are provided:

* ISO
* `kernel`, `initramfs`, and kernel command line
* UKI
* disk images in various formats (e.g. AWS, GCP, VMware, etc.)
* installer container images

The supported frontends are:

* HTTP
* PXE
* Container Registry

The official instance of Image Factory is available at https://factory.talos.dev.

See [Boot Assets]({{< relref "../talos-guides/install/boot-assets#image-factory" >}}) for an example of how to use the Image Factory to boot and upgrade Talos on different platforms.
Full API documentation for the Image Factory is available at [GitHub](https://github.com/siderolabs/image-factory#readme).

## Schematics

Schematics are YAML files that define customizations to be applied to a Talos Linux image.
Schematics can be applied to any of the versions of Talos Linux offered by the Image Factory to produce a "model", which is a Talos Linux image with the customizations applied.

Schematics are content-addressable, that is, the content of the schematic is used to generate a unique ID.
The schematic should be uploaded to the Image Factory first, and then the ID can be used to reference the schematic in a model.

Schematics can be generated using the [Image Factory UI](#ui), or using the Image Factory API:

```yaml
customization:
extraKernelArgs: # optional
- vga=791
meta: # optional, allows to set initial Talos META
- key: 0xa
value: "{}"
systemExtensions: # optional
officialExtensions: # optional
- siderolabs/gvisor
- siderolabs/amd-ucode
```
The "vanilla" schematic is:
```yaml
customization:
```
and has an ID of `376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba`.

The schematic can be applied by uploading it to the Image Factory:

```shell
curl -X POST --data-binary @schematic.yaml https://factory.talos.dev/schematics
```

As the schematic is content-addressable, the same schematic can be uploaded multiple times, and the Image Factory will return the same ID.

## Models

Models are Talos Linux images with customizations applied.
The inputs to generate a model are:

* schematic ID
* Talos Linux version
* model type (e.g. ISO, UKI, etc.)
* architecture (e.g. amd64, arm64)
* various model type specific options (e.g. disk image format, disk image size, etc.)

## Frontends

Image Factory provides several frontends to retrieve models:

* HTTP frontend to download models (e.g. download an ISO or a disk image)
* PXE frontend to boot bare-metal machines (PXE script references kernel/initramfs from HTTP frontend)
* Registry frontend to fetch customized `installer` images (for initial Talos Linux installation and upgrades)

The links to different models are available in the [Image Factory UI](#ui), and a full list of possible models is documented at [GitHub](https://github.com/siderolabs/image-factory#readme).

In this guide we will provide a list of examples:

* amd64 ISO (for Talos {{< release >}}, "vanilla" schematic) [https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/{{< release >}}/metal-amd64.iso](https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/{{< release >}}/metal-amd64.iso)
* arm64 AWS image (for Talos {{< release >}}, "vanilla" schematic) [https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/{{< release >}}/aws-arm64.raw.xz](https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/{{< release >}}/aws-arm64.raw.xz)
* amd64 PXE boot script (for Talos {{< release >}}, "vanilla" schematic) [https://factory.talos.dev/pxe/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/{{< release >}}/metal-amd64](https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/{{< release >}}/metal-amd64)
* Talos `installer` image (for Talos {{< release >}}, "vanilla" schematic, architecture is detected automatically): `factory.talos.dev/installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:{{< release >}}`

The `installer` image can be used to install Talos Linux on a bare-metal machine, or to upgrade an existing Talos Linux installation.
As the Talos version and schematic ID can be changed, via an upgrade process, the `installer` image can be used to upgrade to any version of Talos Linux, or replace a set of installed system extensions.

## UI

The Image Factory UI is available at https://factory.talos.dev.
The UI provides a way to list supported Talos Linux versions, list of system extensions available for each release, and a way to generate schematic based on the selected system extensions.

The UI operations are equivalent to API operations.

## Find Schematic ID from Talos Installation

Image Factory always appends "virtual" system extension with the version matching schematic ID used to generate the model.
So, for any running Talos Linux instance the schematic ID can be found by looking at the list of system extensions:

```shell
$ talosctl get extensions
NAMESPACE TYPE ID VERSION NAME VERSION
runtime ExtensionStatus 0 1 schematic 376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba
```

## Restrictions

Some models don't include every customization of the schematic:

* `installer` and `initramfs` images only support system extensions (kernel args and META are ignored)
* `kernel` assets don't depend on the schematic

Other models have full support for all customizations:

* any disk image format
* ISO, PXE boot script

When installing Talos Linux using ISO/PXE boot, Talos will be installed on the disk using the `installer` image, so the `installer` image in the machine configuration
should be using the same schematic as the ISO/PXE boot image.

Some system extensions are not available for all Talos Linux versions, so an attempt to generate a model with an unsupported system extension will fail.
List of supported Talos versions and supported system extensions for each version is available in the [Image Factory UI](#ui) and [API](https://github.com/siderolabs/image-factory#readme).

## Under the Hood

Image Factory is based on the Talos `imager` container which provides both the Talos base boot assets, and the ability to generate custom assets based on a configuration.
Image Factory manages a set of `imager` container images to acquire base Talos Linux boot assets (`kernel`, `initramfs`), a set of Talos Linux system extension images, and a set of schematics.
When a model is requested, Image Factory uses the `imager` container to generate the requested assets based on the schematic and the Talos Linux version.

## Security

Image Factory verifies signatures of all source container images fetched:

* `imager` container images (base boot assets)
* `extensions` system extensions catalogs
* `installer` contianer images (base installer layer)
* Talos Linux system extension images

Internally, Image Factory caches generated boot assets and signs all cached images using a private key.
Image Factory verifies the signature of the cached images before serving them to clients.

Image Factory signs generated `installer` images, and verifies the signature of the `installer` images before serving them to clients.

Image Factory does not provide a way to list all schematics, as schematics may contain sensitive information (e.g. private kernel boot arguments).
As the schematic ID is content-addressable, it is not possible to guess the ID of a schematic without knowing the content of the schematic.

## Running your own Image Factory

Image Factory can be deployed on-premises to provide in-house asset generation.

Image Factory requires following components:

* an OCI registry to store schematics (private)
* an OCI registry to store cached assets (private)
* an OCI registry to store `installer` images (should allow public read-only access)
* a container image signing key: ECDSA P-256 private key in PEM format

Image Factory is configured using command line flags, use `--help` to see a list of available flags.
Image Factory should be configured to use proper authentication to push to the OCI registries:

* by mounting proper credentials via `~/.docker/config.json`
* by supplying `GITHUB_TOKEN` (for `ghcr.io`)

Image Factory performs HTTP redirects to the public registry endpoint for `installer` images, so the public endpoint
should be available to Talos Linux machines to pull the `installer` images.
132 changes: 128 additions & 4 deletions website/content/v1.5/talos-guides/install/boot-assets.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,132 @@ can be customized further for a specific use case:

* adding [system extensions]({{< relref "../configuration/system-extensions" >}})
* updating [kernel command line arguments]({{< relref "../../reference/kernel" >}})
* using custom `META` contents, e.g. for [metal network configuration]({{< relref "../../advanced/metal-network-configuration" >}})
* generating [SecureBoot]({{< relref "../install/bare-metal-platforms/secureboot" >}}) images signed with a custom key

There are two ways to generate Talos boot assets:

* using [Image Factory]({{< relref "#image-factory" >}}) service (recommended)
* manually using [imager]({{< relref "#imager" >}}) container image (advanced)

Image Factory is easier to use, but it only produces images for official Talos Linux releases and official Talos Linux system extensions.
The `imager` container can be used to generate images from `main` branch, with local changes, or with custom system extensions.

## Image Factory

[Image Factory]({{< relref "../../learn-more/image-factory" >}}) is a service that generates Talos boot assets on-demand.
Image Factory allows to generate boot assets for the official Talos Linux releases and official Talos Linux system extensions.

The main concept of the Image Factory is a *schematic* which defines the customization of the boot asset.
Once the schematic is configured, Image Factory can be used to pull various Talos Linux images, ISOs, installer images, PXE booting bare-metal machines across different architectures,
versions of Talos and platforms.

Sidero Labs maintains a public Image Factory instance at [https://factory.talos.dev](https://factory.talos.dev).
Image Factory provides a simple [UI](https://factory.talos.dev) to prepare schematics and retrieve asset links.

### Example: Bare-metal with Image Factory

Let's assume we want to boot Talos on a bare-metal machine with Intel CPU and add a `gvisor` container runtime to the image.
Also we want to disable predictable network interface names with `net.ifnames=0` kernel argument.

First, let's create the schematic file `bare-metal.yaml`:

```yaml
# bare-metal.yaml
customization:
extraKernelArgs:
- net.ifnames=0
systemExtensions:
officialExtensions:
- siderolabs/gvisor
- siderolabs/intel-ucode
```
> The schematic doesn't contain system extension versions, Image Factory will pick the correct version matching Talos Linux release.
And now we can upload the schematic to the Image Factory to retrieve its ID:
```shell
$ curl -X POST --data-binary @bare-metal.yaml https://factory.talos.dev/schematics
{"id":"b8e8fbbe1b520989e6c52c8dc8303070cb42095997e76e812fa8892393e1d176"}
```

The returned schematic ID `b8e8fbbe1b520989e6c52c8dc8303070cb42095997e76e812fa8892393e1d176` we will use to generate the boot assets.

> The schematic ID is based on the schematic contents, so uploading the same schematic will return the same ID.
Now we have two options to boot our bare-metal machine:

* using ISO image: https://factory.talos.dev/image/b8e8fbbe1b520989e6c52c8dc8303070cb42095997e76e812fa8892393e1d176/{{< release >}}/metal-amd64.iso (download it and burn to a CD/DVD or USB stick)
* PXE booting via iPXE script: https://factory.talos.dev/pxe/b8e8fbbe1b520989e6c52c8dc8303070cb42095997e76e812fa8892393e1d176/{{< release >}}/metal-amd64

> The Image Factory URL contains both schematic ID and Talos version, and both can be changed to generate different boot assets.
Once the bare-metal machine is booted up for the first time, it will require Talos Linux `installer` image to be installed on the disk.
The `installer` image will be produced by the Image Factory as well:

```yaml
# Talos machine configuration patch
machine:
install:
image: factory.talos.dev/installer/b8e8fbbe1b520989e6c52c8dc8303070cb42095997e76e812fa8892393e1d176:{{< release >}}
```
Once installed, the machine can be upgraded to a new version of Talos by referencing new installer image:
```shell
talosctl upgrade --image factory.talos.dev/installer/b8e8fbbe1b520989e6c52c8dc8303070cb42095997e76e812fa8892393e1d176:<new_version>
```

Same way upgrade process can be used to transition to a new set of system extensions: generate new schematic with the new set of system extensions, and upgrade the machine to the new schematic ID:

```shell
talosctl upgrade --image factory.talos.dev/installer/<new_schematic_id>:{{< release >}}
```

### Example: AWS with Image Factory

Talos Linux is installed on AWS from a disk image (AWS AMI), so only a single boot asset is required.
Let's assume we want to boot Talos on AWS with `gvisor` container runtime system extension.

First, let's create the schematic file `aws.yaml`:

```yaml
# aws.yaml
customization:
systemExtensions:
officialExtensions:
- siderolabs/gvisor
```
And now we can upload the schematic to the Image Factory to retrieve its ID:
```shell
$ curl -X POST --data-binary @aws.yaml https://factory.talos.dev/schematics
{"id":"d9ff89777e246792e7642abd3220a616afb4e49822382e4213a2e528ab826fe5"}
```

The returned schematic ID `d9ff89777e246792e7642abd3220a616afb4e49822382e4213a2e528ab826fe5` we will use to generate the boot assets.

Now we can download the AWS disk image from the Image Factory:

```shell
curl -LO https://factory.talos.dev/image/d9ff89777e246792e7642abd3220a616afb4e49822382e4213a2e528ab826fe5/{{< release >}}/aws-amd64.raw.xz
```

Now the `aws-amd64.raw.xz` file contains the customized Talos AWS disk image which can be uploaded as an AMI to the [AWS]({{< relref "../install/cloud-platforms/aws" >}}).

Once the AWS VM is created from the AMI, it can be upgraded to a different Talos version or a different schematic using `talosctl upgrade`:

```shell
# upgrade to a new Talos version
talosctl upgrade --image factory.talos.dev/installer/d9ff89777e246792e7642abd3220a616afb4e49822382e4213a2e528ab826fe5:<new_version>
# upgrade to a new schematic
talosctl upgrade --image factory.talos.dev/installer/<new_schematic_id>:{{< release >}}
```

## Imager

A custom disk image, boot asset can be generated by using the Talos Linux `imager` container: `ghcr.io/siderolabs/imager:{{< release >}}`.
The `imager` container image can be checked by [verifying its signature]({{< relref "../../advanced/verifying-images" >}}).

Expand Down Expand Up @@ -44,7 +168,7 @@ The base profile can be customized with the additional flags to the imager:
* `--extra-kernel-arg` allows to customize the kernel command line arguments
* `--system-extension-image` allows to install a system extension into the image

## Example: Bare-metal
### Example: Bare-metal with Imager

Let's assume we want to boot Talos on a bare-metal machine with Intel CPU and add a `gvisor` container runtime to the image.
Also we want to disable predictable network interface names with `net.ifnames=0` kernel argument.
Expand All @@ -64,7 +188,7 @@ profile ready:
arch: amd64
platform: metal
secureboot: false
version: v1.5.0-alpha.3-35-ge0f383598-dirty
version: {{ < release > }}
customization:
extraKernelArgs:
- net.ifnames=0
Expand All @@ -74,7 +198,7 @@ input:
initramfs:
path: /usr/install/amd64/initramfs.xz
baseInstaller:
imageRef: ghcr.io/siderolabs/installer:v1.5.0-alpha.3-35-ge0f383598-dirty
imageRef: ghcr.io/siderolabs/installer:{{< release >}}
systemExtensions:
- imageRef: ghcr.io/siderolabs/gvisor:20231214.0-v1.5.0-beta.0
- imageRef: ghcr.io/siderolabs/intel-ucode:20230613
Expand Down Expand Up @@ -119,7 +243,7 @@ Now we can use the customized `installer` image to install Talos on the bare-met
When it's time to upgrade a machine, a new `installer` image can be generated using the new version of `imager`, and updating the system extension images to the matching versions.
The custom `installer` image can now be used to upgrade Talos machine.

## Example: AWS
### Example: AWS with Imager

Talos is installed on AWS from a disk image (AWS AMI), so only a single boot asset is required.

Expand Down
Loading

0 comments on commit eb94468

Please sign in to comment.