The Image Factory is a way for you to dynamically create Talos Linux images. There is a public, hosted version of the Image Factory at factory.talos.dev and it can also be run in your environment.
The Image Factory is a critical component of Omni to generate installation media and update Talos nodes, but it is not required to use Omni to use the Image Factory. It is a web interface and API for the imager command which is used to customize Talos from the command line.
Prerequisites
- Container registry (with Talos images)
- Machine to run Image Factory
- Image cache signing key
- Image cache storage (optional)
The official Sidero Labs registry has all of the required Talos installation containers, extensions, and tools.
If you want to run image factory connected to the upstream container registry you can do it with:
openssl ecparam -name prime256v1 -genkey -noout -out signing-key.key
docker run -p 8080:8080 -d \
--name image-factory \
-v $PWD/signing-key.key:/signing-key.key:ro \
ghcr.io/siderolabs/image-factory \
-cache-signing-key-path /signing-key.key
If your system has SELinux enabled you will need to mount the signing key with the :Z option so the image factory has access to the file.
This will run the image factory on your machine on port 8080 and pull container images from Sidero Labs ghcr.io registry. It will also validate image signatures using cosign to validate pulled images.
This will not allow you to create or publish custom system extensions.
To do that you will need to run your own container registry with the necessary images.
Image Cache
There are a variety of image cache locations to store built images. Without an image cache each asset will be built when requested which can consume a high amount of CPU on the image factory machine.
Some supported cache storage options include:
- CDN
- s3 bucket (or compatable API)
Please view the --help output for cache options.
Run Image Factory with Custom Container Registry
Running the image factory in an air airgapped environment has more requirements than running in a connected mode. In addition to the requirements above you will also need.
- Certificates for web frontend and registry
- Cosign image signing key
You will need to run a container registry in your environment. Any OCI compatable registry should work. For example purposes we will run a pull only image registry built into talosctl
This is just an example and should not be used in a production environment. If you want to test locally on your mahcine you can also see the
developer documentation in the repository.
Download Required Container Images
Starting with Talos 1.12 you can get a list of images needed to seed the image factory directly from talosctl.
Get a list of Talos base images needed for the image factory with:
talosctl image source-bundle v1.11.5 > images.txt
This will give you a list of all images and extensions needed to build Talos 1.11.5.
You will need to repeat this command for each version of Talos you want to download images for.
If you don’t need specific extensions you can delete them from the images.txt file.
Serve Container Images
If you already have a container registry available you can use the images.txt file to directly download and upload them to your container registry.
Export your registry to an environment variable.
INTERNAL_REG=<my-registry.com>
If you don’t have a container registry available to push images to you can temporarily run one with the zot container.
This example doesn’t have persistent storage.
docker run -d -p 5000:5000 --name zot \
ghcr.io/project-zot/zot:latest
INTERNAL_REG=127.0.0.1:5000
Replace the registry in each image with your registry or use localhost:5000 if running a registry locally, and push the images.
for SOURCE_IMAGE in $(cat images.txt)
do
IMAGE_WITHOUT_DIGEST=${SOURCE_IMAGE%%@*}
IMAGE_WITH_NEW_REG="${INTERNAL_REG}/${IMAGE_WITHOUT_DIGEST#*/}"
crane copy \
$SOURCE_IMAGE \
$IMAGE_WITH_NEW_REG
done
Sign Container Images
The Image Factory verifies container image signatures when being used. You will need to generate a cosign singing key and sign each container pushed to the registry.
Image factory currently only supports cosign v2 signatures.
Generate a cosign key
docker run --rm -it \
-v $PWD:/keys -w /keys \
-e COSIGN_PASSWORD="" \
--user $(id -u):$(id -g) \
ghcr.io/sigstore/cosign/cosign:v2.6.1 \
generate-key-pair
Now sign each image and tag in your internal registry. This will allow the registry to validate images without reaching out to any external services for key validation.
KEY_FILE="cosign.key"
export COSIGN_PASSWORD="" # Leave empty for empty password
Sign all of the images using the images.txt file as a list.
for IMAGE in $(cat images.txt)
do
NEW_IMAGE="${INTERNAL_REG}/${IMAGE#*/}"
if [[ "$NEW_IMAGE" != *"@sha256:"* ]]; then
NEW_IMAGE="${NEW_IMAGE}@$(crane digest $NEW_IMAGE)"
fi
docker run --rm -it --net=host \
-v $PWD:/keys -w /keys \
-e COSIGN_PASSWORD="" \
-e COSIGN_YES=true \
--user $(id -u):$(id -g) \
ghcr.io/sigstore/cosign/cosign:v2.6.1 \
sign --key /keys/$KEY_FILE \
$NEW_IMAGE
done
Run Image Factory
With a populated container registry and signed images you are ready to run the Image Factory.
If the container registry and image factory are run on the same machine in containers
localhost won’t be reachable unless you run each container with
--net=host which is not recommended. An alternative approach would be to use
private Docker networking to bridge the containers.
docker run -p 8080:8080 -d \
--name image-factory \
-v $PWD/signing-key.key:/signing-key.key:ro \
-v $PWD/cosign.pub:/cosign.pub:ro \
ghcr.io/siderolabs/image-factory \
-image-registry $INTERNAL_REG \
-installer-internal-repository $INTERNAL_REG/siderolabs \
-installer-internal-repository $INTERNAL_REG/siderolabs \
-schematic-service-repository $INTERNAL_REG/siderolabs/image-factory/schematic \
-cache-repository $INTERNAL_REG/siderolabs/cache \
-cache-signing-key-path /signing-key.key \
-container-signature-pubkey /cosign.pub \
-cache-cdn-enabled=false \
-cache-s3-enabled=false
If your image factory does not have certificates or does not have certificates trusted by the image factory you should add the following flags.
-insecure-image-registry \
-insecure-installer-internal-repository \
-insecure-schematic-service-repository
If you are running on a server with SELinux enabled and enforcing then volumes mounted into the container will not be available unless you append :Z to the volume mounts.
If you have an internal, private certificate authority you will need to mount that into the Image Factory image so it can trust the registry certificate. Mount it into the container by adding -v /etc/pki/ca-trust/source/anchors:/etc/ssl/certs:ro to the Image Factory commands.
To generate some image types (e.g. ISO) you will need to mount /dev into the image factory container and allow privileged operations.
Add these flags to your docker command.
-v /dev:/dev --privileged
After the image factory is running you can continue to the Omni documentation for a self-hosted installation.