Use of an OCI Container Registry¶
What is an OCI Container Registry?¶
An OCI Container registry is an evolution of a docker container registry where layers which make up containers can be housed as individual data files, and then be retrieved to be reconstructed into a running container. OCI is short for “Open Container Initiative”, and you can learn more about about OCI at opencontainers.org.
Container registries are evolving to support housing other data files, and the focus in this context is the evolution to support those additional files to be housed in and served by a container registry.
Warning
This feature should be considered experimental.
Overview¶
A recent addition to Ironic is the ability to retrieve artifacts from an OCI Container Registry. This support is modeled such that it can be used by an Ironic deployment for both disk images, and underlying artifacts used for deployment, such as kernels and ramdisks. Different rules apply and as such, please review the next several sections carefully.
At present, this functionality is only available for users who are directly interacting with Ironic. Nova’s data model is only compatible with usage Glance at this present time, but that may change in the future.
How it works¶
An OCI registry has a layered data model which can be divided into three conceptual layers.
Artifact Index - Higher level list which points to manifests and contains information like annotations, platform, architecture.
Manifest - The intermediate structural location which contains the lower level details related to the blob (Binary Large OBject) data as well as the information where to find the blob data. When a container image is being referenced, this Manifest contains information on multiple “layers” which comprise a container.
Blob data - The actual artifact, which can only be retrieved using the data provided in the manifest.
Ironic has a separate image service client which translates an an OCI
style container URL in an image_source
value, formatted such as
oci://host/user/container:tag
. When just a tag has been defined,
which can be thought of as specific “tagged” view containing many
artifacts, which Ironic will search through to find the best match.
Matching is performed with an attempt to weigh preference to file type
based upon the configured image_download_source
, where as with a local
value, qcow2
disk images are preferred. Otherwise raw
is preferred.
This uses the disktype
annotation where qcow2
and qemu
are
considered QCOW2 format images. A disktype
annotation on the manifests
of raw
or applehv
, are considered raw disk images.
Once file types have been appropriately weighted, the code attempts to match
the baremetal node’s CPU architecture to the listed platform architecture
in the remote registry. Once the file identification process has been
completed, Ironic automatically updates the image_source
value to the
matching artifact in the remote container registry.
Note
The code automatically attempts to handle differences in architecture
naming which has been observed, where x86_64
is sometimes referred to
as amd64
, and aarch64
is sometimes referred to as arm64
.
Warning
An image_download_source
of swift
is incompatible
with this image service. Only local
and http
are supported.
When a URL is specific and pointing to a specific manifest, for example
oci://host/user/container@sha256:f00b...
, Ironic is only able to
retrieve that specific file from the the container registry. Due to the
data model, we also cannot learn additional details about that image
such as annotations, as annotations are part of the structural data
which points to manifests in the first place.
An added advantage to the use of container registries, is that the checksum is confirmed in transit based upon the supplied metadata from the container registry. For example, when you use a manifest URL, the digest portion of the URL is used to checksum the returned contents, and that manifests then contains the digest values for artifacts which also supplies sufficient information to identify the URL where to download the artifacts from.
Authentication¶
Authentication is an important topic for users of an OCI Image Registry.
While some public registries are fairly friendly to providing download access, other registries may have aggressive quotas in place which require users to be authenticated to download artifacts. Furthermore, private image registries may require authentication for any access.
As such, there are three available paths for providing configuration:
A node
instance_info
value ofimage_pull_secret
. This value may be utilized to retrieve an image artifact, but is not intended for pulling other artifacts like kernels or ramdisks used as part of a deployment process. As with all otherinstance_info
field values, this value is deleted once the node has been unprovisioned.A node
driver_info
value ofimage_pull_secret
. This setting is similar to theinstance_info
setting, but may be utilized by an administrator of a baremetal node to define the specific registry credential to utilize for the node.The
oci.authentication_config
which allows for a conductor process wide pre-shared secret configuration. This configuration value can be set to a file which parses the common auth configuration format used for container tooling in regards to the secret to utilize for container registry authentication. This value is only consulted if a specific secret has not been defined to utilize, and is intended to be compaitble with the the format used by dockerconfig.json
to store authentication detail.
An example of the configuration file looks something like the following example.
{
"auths": {
"quay.io": {
"auth": "<secret_here>",
},
"private-registry.tld": {
"auth": "<secret_here>",
}
}
}
Note
The image_pull_secret
values are not visible in the API surface
due Ironic’s secret value santiization, which prevents sensitive
values from being visible, and are instead returned as ‘**’.
Available URL Formats¶
The following URL formats are available for use to download a disk image artifact. When a non-precise manifest URL is supplied, Ironic will attempt to identify and match the artifact. URLs for artifacts which are not disk images are required to be specific and point to a specific manifest.
Note
If no tag is defined, the tag latest
will be attempted,
however, if that is not found in the list of available tags returned
by the container registry, an ImageNotFound error will be raised in
Ironic.
oci://host/path/container - Ironic assumes ‘latest’ is the desired tag in this case.
oci://host/path/container:tag - Ironic discoveres artifacts based upon the view provided by the defined tag.
oci://host/path/container@sha256:f00f - This is a URL which defines a specific manifest. Should this be a container, this would be a manifest file with many layers to make a container, but for an artifact only a single file is represented by this manifest, and we retrieve this specific file.
Warning
The use of tag values to access an artifact, for example, deploy_kernel
or deploy_ramdisk
, is not possible. This is an intentional limitation
which may addressed in a future version of Ironic.
Known Limitations¶
For usage with disk images, only whole-disk images are supported. Ironic does not intend to support Partition images with this image service.
IPA is unaware of remote container registries, as well as authentication to a remote registry. This is expected to be addressed in a future release of Ironic.
Some artifacts may be compressed using Zstandard. Only disk images or artifacts which transit through the conductor may be appropriately decompressed. Unfortunately IPA won’t be able to decompress such artifacts dynamically while streaming content.
Authentication to container image registries is only available through the use of pre-shared token secrets.
Use of tags may not be viable on some OCI Compliant image registries. This may result as an ImageNotFound error being raised when attempting to resolve a tag.
User authentication is presently limited to use of a bearer token, under the model only supporting a “pull secret” style of authentication. If Basic authentication is required, please file a bug in Ironic Launchpad.
How do I upload files to my own registry?¶
While there are several different ways to do this, the easiest path is to
leverage a tool called ORAS
. You can learn more about ORAS at
https://oras.land
The ORAS utility is able to upload arbitrary artifacts to a Container Registry along with the required manifest and then associates a tag for easy human reference. While the OCI data model does happily support a model of one tag in front of many manifests, ORAS does not. In the ORAS model, one tag is associated with one artifact.
In the examples below, you can see how this is achieved. Please be careful that these examples are not commands you can just cut and paste, but are intended to demonstrate the required step and share the concept of how to construct the URL for the artifact.
Note
These examples command lines may differ slightly based upon your remote registry, and underlying configuration, and as such leave out credential settings.
As a first step, we will demonstrate uploading an IPA Ramdisk kernel.
$ export HOST=my-container-host.domain.tld
$ export CONTAINER=my-project/my-container
$ oras push ${HOST}/${CONTAINER}:ipa_kernel tinyipa-master.vmlinuz
✓ Exists tinyipa-master.vmlinuz 5.65/5.65 MB 100.00% 0s
└─ sha256:15ed5220a397e6960a9ac6f770a07e3cc209c6870c42cbf8f388aa409d11ea71
✓ Exists application/vnd.oci.empty.v1+json 2/2 B 100.00% 0s
└─ sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a
✓ Uploaded application/vnd.oci.image.manifest.v1+json 606/606 B 100.00% 0s
└─ sha256:2d408348dd6ff2e26efc1de03616ca91d76936a27028061bc314289cecdc895f
Pushed [registry] my-container-host.domain.tld/my-project/my-container:ipa_kernel
ArtifactType: application/vnd.unknown.artifact.v1
Digest: sha256:2d408348dd6ff2e26efc1de03616ca91d76936a27028061bc314289cecdc895f
$
$ export MY_IPA_KERNEL=oci://${HOST}/${CONTAINER}:@sha256:2d408348dd6ff2e26efc1de03616ca91d76936a27028061bc314289cecdc895f
As you can see from this example, we’ve executed the command, and uploaded the file. The important aspect to highlight is the digest reported at the end. This is the manifest digest which you can utilize to generate your URL.
Warning
When constructing environment variables for your own use, specifically with digest values, please be mindful that you will need to utilize the digest value from your own upload, and not from the example.
$ oras push ${HOST}/${CONTAINER}:ipa_ramdisk tinyipa-master.gz
✓ Exists tinyipa-master.gz 91.9/91.9 MB 100.00% 0s
└─ sha256:0d92eeb98483f06111a352b673d588b1aab3efc03690c1553ef8fd8acdde15fc
✓ Exists application/vnd.oci.empty.v1+json 2/2 B 100.00% 0s
└─ sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a
✓ Uploaded application/vnd.oci.image.manifest.v1+json 602/602 B 100.00% 0s
└─ sha256:b17e53ff83539dd6d49e714b09eeb3bd0a9bb7eee2ba8716f6819f2f6ceaad13
Pushed [registry] my-container-host.domain.tld/my-project/my-container:ipa_ramdisk
ArtifactType: application/vnd.unknown.artifact.v1
Digest: sha256:b17e53ff83539dd6d49e714b09eeb3bd0a9bb7eee2ba8716f6819f2f6ceaad13
$
$ export MY_IPA_RAMDISK=oci://${HOST}/${CONTAINER}:@sha256:b17e53ff83539dd6d49e714b09eeb3bd0a9bb7eee2ba8716f6819f2f6ceaad13
As a reminder, please remember to utilize different tags with ORAS.
For example, you can view the current tags in the remote registry by existing the following command.
$ oras repo tags --insecure $HOST/project/container
ipa_kernel
ipa_ramdisk
unrelated_item
$
Now that you have successfully uploaded an IPA kernel and ramdisk, the only item remaining is a disk image. In this example below, we’re generating a container tag based URL as well as direct manifest digest URL.
Note
The example below sets a manifest annotation of disktype
and
artifact platform. While not explicitly required, these are recommended
should you allow Ironic to resolve the disk image utilizing the container
tag as opposed to a digest URL.
$ oras push -a disktype=qcow2 --artifact-platform linux/x86_64 $HOST/$CONTAINER:cirros-0.6.3 ./cirros-0.6.3-x86_64-disk.img
✓ Exists cirros-0.6.3-x86_64-disk.img 20.7/20.7 MB 100.00% 0s
└─ sha256:7d6355852aeb6dbcd191bcda7cd74f1536cfe5cbf8a10495a7283a8396e4b75b
✓ Uploaded application/vnd.oci.image.config.v1+json 38/38 B 100.00% 43ms
└─ sha256:369358945e345b86304b802b704a7809f98ccbda56b0a459a269077169a0ac5a
✓ Uploaded application/vnd.oci.image.manifest.v1+json 626/626 B 100.00% 0s
└─ sha256:0a175cf13c651f44750d6a5cf0cf2f75d933bd591315d77e19105e5446b73a86
Pushed [registry] my-container-host.domain.tld/my-project/my-container:cirros-0.6.3
ArtifactType: application/vnd.unknown.artifact.v1
Digest: sha256:0a175cf13c651f44750d6a5cf0cf2f75d933bd591315d77e19105e5446b73a86
$ export MY_DISK_IMAGE_TAG_URL=oci://${HOST}/${CONTAINER}:cirros-0.6.3
$ export MY_DISK_IMAGE_DIGEST_URL=oci://${HOST}/${CONTAINER}@sha256:0a175cf13c651f44750d6a5cf0cf2f75d933bd591315d77e19105e5446b73a86