> ## Documentation Index
> Fetch the complete documentation index at: https://docs.siderolabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Image Cache

> How to enable and configure Talos image cache feature.

export const release_v1_13 = 'v1.13.1';

export const VersionWarningBanner = () => {
  const latestVersion = "v1.13";
  const [latestUrl, setLatestUrl] = useState(null);
  const [currentVersion, setCurrentVersion] = useState(null);
  const [isBeta, setIsBeta] = useState(false);
  const parseVersion = v => v.replace("v", "").split(".").map(Number);
  const isGreaterVersion = (a, b) => {
    const [aMajor, aMinor] = parseVersion(a);
    const [bMajor, bMinor] = parseVersion(b);
    if (aMajor > bMajor) return true;
    if (aMajor === bMajor && aMinor > bMinor) return true;
    return false;
  };
  useEffect(() => {
    if (typeof window === "undefined") return;
    const {pathname, hash, search} = window.location;
    const match = pathname.match(/\/talos\/(v\d+\.\d+)\//);
    if (!match) return;
    const detectedVersion = match[1];
    if (detectedVersion === latestVersion) return;
    setCurrentVersion(detectedVersion);
    if (isGreaterVersion(detectedVersion, latestVersion)) {
      setIsBeta(true);
    }
    const newPath = pathname.replace(`/talos/${detectedVersion}/`, `/talos/${latestVersion}/`);
    setLatestUrl(`${newPath}${search}${hash}`);
  }, []);
  if (!latestUrl || !currentVersion) return null;
  return <div className="not-prose sticky top-6 z-50 my-6">
      <div className="border border-yellow-500/30 bg-yellow-500/10 px-4 py-3 rounded-xl">
        <div className="text-sm">
          {isBeta ? <>
              ⚠️ You are viewing a <strong>beta version</strong> of Talos ({currentVersion}).
              This version may be unstable.
              <a href={latestUrl} className="ml-2 underline text-yellow-400 hover:text-yellow-300 font-medium">
                View latest stable version {latestVersion} →
              </a>
            </> : <>
              ⚠️ You are viewing an older version of Talos ({currentVersion}).
              <a href={latestUrl} className="ml-2 underline text-yellow-400 hover:text-yellow-300 font-medium">
                View the latest version {latestVersion} →
              </a>
            </>}
        </div>
      </div>
    </div>;
};

<VersionWarningBanner />

The Image Cache feature allows nodes to access container images without needing to pull them from the Internet.
This is especially useful in environments with limited or no Internet connectivity.

<iframe
  width="560"
  height="315"
  src="https://www.youtube.com/embed/Ir2m11Cijas"
  title="Cache Kubernetes images with Talos Linux"
  frameborder="0"
  allow="accelerometer;
autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
  referrerpolicy="strict-origin-when-cross-origin"
  allowfullscreen
/>

The cache is local to each machine and is automatically managed by Talos when enabled.

## Preparing image cache

First, build a list of image references that need to be cached.
The `talosctl images k8s-bundle` might be used as a starting point, but it should be customized to include additional images (e.g. custom CNI, workload images, etc.)

```bash theme={null}
talosctl images k8s-bundle > images.txt
cat extra-images.txt >> images.txt
```

### Air-gapped environments

If you are preparing for an air-gapped environment, you will need to cache the talos images as well.

Starting with Talos 1.12 you can get a list of images needed from talosctl.

<CodeBlock lang="sh">
  {`
    talosctl images talos-bundle ${release_v1_13} >> images.txt
    `}
</CodeBlock>

or deploy an [Image Factory](../../../../omni/self-hosted/run-image-factory-on-prem) to host Talos images internally.

<Warning>Including all talos-bundle images will significantly increase the size of your installation media. The minimum images to install Talos include the `installer` and `installer-base` images.</Warning>

Next, prepare an OCI image which contains all cached images:

```bash theme={null}
cat images.txt | talosctl images cache-create --image-cache-path ./image-cache.oci --images=-
```

> Note: The `cache-create` supports a `--layer-cache` flag to additionally cache the pulled images layers on the filesystem.
> This is useful to speed up repeated calls for `cache-create` with the same images.

The OCI image cache directory might be used directly (`./image-cache.oci`) or pushed itself to a container registry of your choice (e.g. with `crane push`).

Example of pushing the OCI image cache directory to a container registry:

```bash theme={null}
crane push ./image-cache.oci my.registry/image-cache:my-cache
```

## Build boot assets

The image cache is provided to Talos via the boot assets.
There are two supported boot asset types for the Image Cache: ISO and disk image.

### ISO

In case of ISO, the image cache is bundled with a Talos ISO image, it will be available for the initial install and (if configured) copied to the
disk during the installation process.

The ISO image can built with the [imager](../../platform-specific-installations/boot-assets#imager) by passing an additional `--image-cache` flag:

<CodeBlock lang="sh">
  {`
    mkdir -p _out/
    docker run --rm -t -v $PWD/_out:/secureboot:ro -v $PWD/_out:/out -v $PWD/image-cache.oci:/image-cache.oci:ro ghcr.io/siderolabs/imager:${release_v1_13} iso --image-cache /image-cache.oci
    `}
</CodeBlock>

> Note: If the image cache was pushed to a container registry, the `--image-cache` flag should point to the image reference.
> SecureBoot ISO is supported as well.

The ISO image can be utilized in the following ways (which allows both booting Talos and using the image cache):

* Using a physical or virtual CD/DVD drive.
* Copying the ISO image to a USB drive using `dd`.
* Copying the contents of the ISO image to a FAT-formatted USB drive with a volume label that starts with `TALOS_`, such as `TALOS_1` (only for UEFI systems).

> Note: Third-party boot loaders, such as Ventoy, are not supported as Talos will not be able to access the image cache.

### Disk image

In case of disk image, the image cache is included in the disk image itself, and on boot it would be used immediately by the Talos.

The disk image can be built with the [imager](../../platform-specific-installations/boot-assets#imager) by passing an additional `--image-cache` flag:

<CodeBlock lang="sh">
  {`
    mkdir -p _out/
    docker run --rm -t -v $PWD/_out:/secureboot:ro -v $PWD/_out:/out -v $PWD/image-cache.oci:/image-cache.oci:ro ghcr.io/siderolabs/imager:${release_v1_13} metal --image-cache /image-cache.oci
    `}
</CodeBlock>

> Note: If the image cache was pushed to a container registry, the `--image-cache` flag should point to the image reference.

For a disk image, the `IMAGECACHE` partition will be created with the size of `--image-cache` directory with a 20% overhead rounded off to the next MiB.

Upon boot, Talos will expand the disk image to utilize the full disk size.

## Configuration

The image cache feature (for security reasons) should be explicitly enabled in the Talos configuration:

```yaml theme={null}
machine:
  features:
    imageCache:
      localEnabled: true
```

Once enabled, Talos Linux will automatically look for the image cache contents either on the disk or in the ISO image.

If the image cache is bundled with the ISO, the disk volume size for the image cache should be configured to copy the image cache to the disk during the installation process:

```yaml theme={null}
apiVersion: v1alpha1
kind: VolumeConfig
name: IMAGECACHE
provisioning:
  diskSelector:
    match: 'system_disk'
  minSize: 2GB
  maxSize: 2GB
```

The default settings for the `IMAGECACHE` volume are as follows (note that a configuration should still be provided to enable the image cache volume provisioning):

* `minSize: 500MB`
* `maxSize: 1GB`
* `diskSelector: match: system_disk`

In this example, image cache volume is provisioned on the system disk with a fixed size of 2GB.
The size of the volume should be adjusted to fit the image cache.
You can see the size of your cache by looking at the size of the image-cache.oci folder with `du -sh image-cache.oci`.

If the disk image is used, the `IMAGECACHE` volume doesn't need to be configured, as the image cache volume is already present in the disk image.

See [System Volumes](../storage-and-disk-management/disk-management/system) for more information on volume configuration.

## Update the image cache

The image cache is initially populated during installation from the boot media (ISO or disk image) and stored on disk.
Over time, you may want to update or refresh the cached images without reinstalling the node.

To update the image cache on a live node, attach a new cache media as a secondary device.

You can create this media by bundling your updated image cache into a new ISO or disk image, as explained in the [Bundling Boot Assets section](#building-boot-assets) of this documentation.

Once attached, Talos mounts the media under `/system/imagecache/iso/imagecache` and copies its contents into the on-disk `IMAGECACHE` partition.

After the copy is complete, the new images are immediately available on the node and can be pulled directly from the cache.

This process allows you to refresh cached images without rebuilding or reinstalling the node.

> **Note:** You can update the image cache using any medium described in the documentation for building boot assets. The media does not need to have Talos installed or be bootable itself, it only needs to provide the cache contents.

### Limitations of live image cache updates

Only images baked into the ISO or USB are copied. There is no way to push arbitrary new images directly into the cache on a running system.

For dynamic updates or for caching non-container artifacts (e.g., Helm charts, FluxCD manifests), use a dedicated registry mirror (`registry:2`, Harbor, Quay, Zarf, etc.), since the Talos cache is not exposed as a network-accessible registry.

## Troubleshooting

When the image cache is enabled, Talos will block on boot waiting for the image cache to be available:

```text theme={null}
task install (1/1): waiting for the image cache
```

After the initial install from an ISO, the image cache will be copied to the disk and will be available for the subsequent boots:

```text theme={null}
task install (1/1): waiting for the image cache copy
copying image cache {"component": "controller-runtime", "controller": "cri.ImageCacheConfigController", "source": "/system/imagecache/iso/imagecache", "target": "/system/imagecache/disk"}
image cache copied {"component": "controller-runtime", "controller": "cri.ImageCacheConfigController", "size": "414 MiB"}
```

The current status of the image cache can be checked via the `ImageCacheConfig` resource:

```yaml theme={null}
# talosctl get imagecacheconfig -o yaml
spec:
  status: ready
  copyStatus: ready
  roots:
    - /system/imagecache/disk
    - /system/imagecache/iso/imagecache
```

The `status` field indicates the readiness of the image cache, and the `copyStatus` field indicates the readiness of the image cache copy.
The `roots` field contains the paths to the image cache contents, in this example both on-disk and ISO caches are available.
Image cache roots are used in order they are listed.

You can get logs from the registry to see if images are being "hit" (a.k.a. cached) or "missed" (a.k.a. pulled from upstream).

```bash theme={null}
talosctl logs registryd
```
