Red Hat Quay Registry - Overview and Installation

- By: Thomas Jungbauer ( Lastmod: 2022-08-27 ) - 6 min read

Red Hat Quay is an enterprise-quality container registry, which is responsible to build, scan, store and deploy containers. The main features of Quay include:

  • High Availability

  • Security Scanning (with Clair)

  • Registry mirroring

  • Docker v2

  • Continuous integration

and much more.

Quay can be installed as:

  • Standalone single service

  • High Availibility service

  • On OpenShift with an Operator

  • On OpenShift without an Operator.

For the following Quay Tutorial Quay version 3.3 on OpenShift 4.3/4.4 with an Operator is used. Moreover, a local storage is used, to make the deployment easier and independent to a storage provider. In any case, be sure that for a production environment a "real" storage is used.

Further details can be found at the official Red Hat documentation at: Deploy Red Hat Quay on OpenShift with an Operator

Quay Architecture

Several components are used to build Quay

  • Database: used to store metadata (not images)

  • Redis: stores live builder logs

  • Quay container registry: Runs Quay as a service

Two types of storages are supported:

  • Public cloud storage, like Amazon S3, Google Cloud Storage

  • Private cloud storage, S3 compliant Object Store, Like Ceph RADOS or OpenStack Swift.

Since I perform the example setup in a limited lab environment, I used local storage. This is not supported for production installations.

Installation

This example installation, covers the configuration of all credentials, but it ignores the configuration of a storage engine. Instead it is using local storage.

Create a new project and install the Quay Operator

Note: Before you begin create a new project called "quay".

From the OpenShift console goto Operators > OperationHub and search for "Red Hat Quay Operator". Be sure NOT to select the community version. Install the Operator using the following settings:

  • Installation Mode: select the namespace "quay"

  • Leave the other settings as default.

quay operator installation
Figure 1. Operator Installation

Once you select "Subscribe", the installation process will take a few minutes. At the end, the operator pods should run inside your namespace and is ready to bse used.

quay operator running
Figure 2. Operator Running

Configure Quay

To configure Quay the Custom Resource Definition "QuayEcosystem" must be defined. Below example shows a ready to use example to test the deployment. Several secrets are used in this QuayEcosystem which must be created first. If they are not specified in the QuayEcosystem, then default values would be used. However, it always makes sense to specify passwords :)

Create a Pull Secret to pull from Quay.io

Check the article Accessing Red Hat Quay to find the appropriate credentials you need to fetch images from quay.io. Find the section "Red Hat Quay v3 on OpenShift", copy the secret into the file redhat_secret.yaml and create the object in OpenShift:

oc create -f redhat_secret.yaml

Create Quay Superuser Credentials

The Quay superuser will be able to manage other users or projects. Create the secret by defining username, password and e-mail address:

The password must have a minimum length of 8 characters.
oc create secret generic quay-credentials \
   --from-literal=superuser-username=<username> \
   --from-literal=superuser-password=<password> \
   --from-literal=superuser-email=<email>

Create Quay Configuration Credentials

The Quay configuration is done, by a separate pod, with a separate accessible route. To set the password, create the following secret:

The password must have a minimum length of 8 characters.
oc create secret generic quay-config-app \
      --from-literal=config-app-password=<password>

Specify database credentials

As next let’s create the credentials for the database:

oc create secret generic <secret_name> \
    --from-literal=database-username=<username> \
    --from-literal=database-password=<password> \
    --from-literal=database-root-password=<root-password> \
    --from-literal=database-name=<database-name>
It is also possible to use and existing database. To configure this, create the secret as described and add the server parameter, containing the hostname, to the QuayEcosystem definition+

Setting Redis password

By default, the operator would install Redis without any password. To specify a password, create the following secret:

oc create secret generic quay-redis-password \
   --from-literal=password=<password>

Create QuayEcosystem Resource

With all the secrets created above, it is time to create the QuayEcosystem. Once it is defined, the operator will automatically start all required services.

The following is an example, using the different secret names (The names should be self explaining) In addition, the following has been defined:

  • volumeSize = 10GI for the database

  • keepConfigDeployment to false, this will remove the configuration pod after the deployment.

  • hostname: to reach the Quay registry under a defined hostname (otherwise a default name would be created)

  • Clair container scanning is enabled

apiVersion: redhatcop.redhat.io/v1alpha1
kind: QuayEcosystem
metadata:
  name: quayecosystem
spec:
  quay:
    imagePullSecretName: redhat-quay-pull-secret
    superuserCredentialsSecretName: quay-credentials
    configSecretName: quay-config-app
    deploymentStrategy: Recreate
    skipSetup: false
    keepConfigDeployment: false
    externalAccess:
      hostname: quay.apps.ocp.ispworld.at
    database:
      volumeSize: 10Gi
      credentialsSecretName: quay-database-credential
    registryBackends:
      - name: local
        local:
          storagePath: /opt/quayregistry
  redis:
    credentialsSecretName: quay-redis-password
    imagePullSecretName: redhat-quay-pull-secret
  clair:
    enabled: true
    imagePullSecretName: redhat-quay-pull-secret

Quay WebUI

Once the Quay Operator has deployed all containers, you should see one route (or 2 if you kept Configuration Deployment Container) and can access your Quay installation.

quay login
Figure 3. Quay WebUI

Optional: Disable self account creation

Many customers want to disable the "Create Account" link on the login page (see Figure #3), to prevent that anybody could create a new account. To remove this option, the configuration pod must run.

Verify if the Configuration pod is running

If the following does not return anything, then the container is not running:

oc get routes -n quay | grep config

If this is the case, modify the resource QuayEcosystem to enable the Configuration UI.

Edit:

oc edit QuayEcosystem/quayecosystem

and set "KeepConfigDeployment" to true:

  quay:
[...]
    keepConfigDeployment: true

After a few minutes another pod, called "quayecosystem-quay-config" will be started and a new route is created:

oc get routes -n quay | grep config
quayecosystem-quay-config   quayecosystem-quay-config-quay.apps.ocp.ispworld.at          quayecosystem-quay-config   8443   passthrough/Redirect   None

Configure Account Creation and Anonymous Access

Login to the Configuration Web Interface with the credentials you specified during the deployment and scroll down to the section "Access Settings".

quay config
Figure 4. Quay Configuration

There remove the checkbox from:

  • Anonymous Access

  • User Creation

and save and build the configuration.

This will trigger a change on the Quay pod. After it has been recreated (this will take a few minutes), the feature to create a new account is removed from the Login page.


Working with Quay

The following quick steps through Quay are the steps of the Quay tutorial, which can be seen at the Quay WebUI at the "Tutorial" tab.

Login via Docker CLI

To login via docker CLI simply use:

docker login <your selected hostname for quay>
Docker expects a valid certificate. Such certificate could be added to the definition of QuayEcosystem. However, I did not create a certificate for this lab. To allow untrusted certificates, on a Mac, simply download the certificates (For Chrome: you can drag and drop the certificate from the browser to your Desktop, for Firefox, you need to open the Options menu and export the certificates.). After that double click both certificates (the root and the site certificate), which will install them on you local Keychain. Open the Keychain on you Mac, find the appropriate certificates and set both to "Always trust"

Create an example container

The next step to create a new image is to create a container. For this example the busybox base image is used.

docker run busybox echo "fun" > newfile

This will pull the latest image of busybox and create a container:

Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
d9cbbca60e5f: Pulling fs layer
d9cbbca60e5f: Verifying Checksum
d9cbbca60e5f: Download complete
d9cbbca60e5f: Pull complete
Digest: sha256:836945da1f3afe2cfff376d379852bbb82e0237cb2925d53a13f53d6e8a8c48c
Status: Downloaded newer image for busybox:latest

With "docker ps" the running container is shown. Remember the Container ID for further steps. In this case fc3e9bb1e9da.

docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
fc3e9bb1e9da        busybox             "echo fun"          3 minutes ago       Exited (0) 3 minutes ago                       relaxed_proskuriakova

Create the image

Once a container has terminated in Docker, the next step is to commit the container to an image. To do so we will use "docker commit" command. As name for the repository I took superapp.

docker commit fc3e9bb1e9da quay.apps.ocp.ispworld.at/quay/superapp

Push the image to Red Hat Quay

The final step is to push the image to our repository, where it will be stored for future use.

docker push quay.apps.ocp.ispworld.at/quay/superapp
quay repos
Figure 5. Quay Repository

Test Container Security Scanner

Clair is used to scan containers about possible security risks. It imports vulnerability data permanently from a known source and creates a list of threats for an image.

To test such scanning, we pull the "Universal Base Image RHEL 7" from Red Hat. I am using version 7.6 since this is already quite old and we expect some known vulnerabilities for this image.

First you need to login to Red Hat Registry:

docker login registry.redhat.io
Username: <Username>
Password: <Password>
Login Succeeded

Then let’s pull the UBI Image 7.6 (instead of the latest)

docker pull registry.redhat.io/ubi7/ubi:7.6

Before we can push it to our Quay registry, we need to tag it:

docker tag registry.redhat.io/ubi7/ubi:7.6 quay.apps.ocp.ispworld.at/quay/ubi7:7.6

If we now check the local images, we see that there are two UBI images.

docker images

REPOSITORY                                TAG                            IMAGE ID            CREATED             SIZE
quay.apps.ocp.ispworld.at/quay/ubi7       7.6                            247ee58855fd        10 months ago       204MB
registry.redhat.io/ubi7/ubi               7.6                            247ee58855fd        10 months ago       204MB

Now it is possible to push the image to the Quay repository.

docker push quay.apps.ocp.ispworld.at/quay/ubi7:7.6

Finally the image is available inside our Registry and Clair will queue it for a security scan.

Once the scan is finished, possible found issues are shown under the "Repository Tags".

quay clair
Figure 6. Clair Security Scanning

When you click on then, you will see a detailed result page, with all vulnerabilities found:

quay clair results
Figure 7. Clair Security Scanning Result