Default container registry revisited

Antonio Murdaca
cri-o
Published in
4 min readAug 3, 2017

The feedback that I’ve received from users of CRI-O (Container Runtime Initiative using the Open container initiative) project is the kpod tool was very useful but at times hard on the fingers.
That’s due to needing to type out fully specified image names for images that were not on the docker.io registry. The users requested a way to set a default registry that could be used instead of docker.io as they generally pulled images from their own private registries. However, it would also still be good to be able to still pull from docker.io if the image was not in the default private registry.

To illustrate this further, people who have used the upstream docker CLI are used to pulling containers images by just specifying its name. For example with kpod pull this would look like:

$ kpod pull fedora:rawhide

By omitting the hostname of the container registry, tools that pull images have downloaded them from docker.io. We call these images unqualified images. This is a nice convenience since docker.io has a huge amount of container images and people think of it as the default namespace for container images.

However, there are certain cases where pulling images without the hostname from an public registry isn’t allowed.
Enterprise organizations tend to have this requirement. They often block the installation of software from the internet and require users to use internal private container registries. Administrators would still like the convenience of pulling images without fully qualifying them with their internal hostname.

Let’s look at this example:

  • Company XYZ has an internal private registry at registry.example.xyz
  • Developers and Ops don’t want to hardcode the registry hostname when referring to a particular container image on this registry, e.g. registry.example.xyz/fedora:25

As of today, they’re required to specify registry.example.xyz when referring to the fedora:25 image. Our users goal is the ability to replace the default registry of docker.io with one their own local registry, or even allow the tool to search a list of registries for the specified image.

By replacing the default docker.io registry with their own, the users at Company XYZ could then use the following command:

$ kpod pull fedora:25

to download fedora:25 from the internal registry registry.example.xyz

I’m happy to announce that we’ve added this customizable registries feature to CRI-O (and kpod).

How does it work?

Users can specify a comma separated list of registries in CRI-O’s configuration file, /etc/crio/crio.conf. This list will be used when pulling an unqualified image (e.g. fedora:rawhide).

The configuration file is in TOML format and the registries lines look like:

# registries is used to specify a comma separated list of registries to be used
# when pulling an unqualified image (e.g. fedora:rawhide).
registries = []

With this configuration, only fully qualified images are allowed to be pulled, including from docker.io.
A fully qualified image means the image must include the registry hostname:

registry.example.xyz/fedora:25

If you try to pull just fedora:25, you’ll get an error.

Let’s modify the configuration to add registry.example.xyz:

# registries is used to specify a comma separated list of registries to be used
# when pulling an unqualified image (e.g. fedora:rawhide).
registries = [
“registry.example.xyz”,
]

To put these changes into play, just restart CRI-O: systemctl restart crio. You can now reference images without the registry hostname in your Kubernetes pods yaml(s). The above makes CRI-O prepend the registry to the image name before actually pulling it. The result is, of course, an image downloaded from registry.example.xyz.

Why would I specify multiple registries?

Let’s see what happens if we modify the configuration to the one below and pull an unqualified image:

# registries is used to specify a comma separated list of registries to be used
# when pulling an unqualified image (e.g. fedora:rawhide).
registries = [
“registry.example.xyz”,
“registry.fedoraproject.org”
]

Let’s say you’re trying to pull the image alpine:3.7 and registry.example.xyz doesn’t have it.

CRI-O will loop through the list of registries in the configuration file until an image is found in one of the specified registries. If the image is not found in any registry, an error will be returned.

This lets anyone safely add the docker.io registry last if they trust it within their organization.

# registries is used to specify a comma separated list of registries to be used
# when pulling an unqualified image (e.g. fedora:rawhide).
registries = [
“registry.example.xyz”,
“registry.fedoraproject.org”,
“docker.io”
]

We know alpine:3.7 is on docker.io, so CRI-O will eventually download alpine:3.7 from docker.io once it has tried all previous registries.

This is a valuable feature for many companies that don’t want to risk having devs and ops pulling untrusted images from public registries.

Please send feedback and suggestions, don’t be shy and reach out to us on Github, Freenode #cri-o, or directly email me :) Grazie mille!

--

--

Antonio Murdaca
cri-o
Writer for

Senior Engineer at Red Hat Inc. RHCE. Fedora Ambassador. Open source maintainer. Working on all things containers. One of the CRI-O guys. Я говорю по-русски.