Chapter 3. Configuring Quay before deployment
The Operator can manage all the Red Hat Quay components when deploying on OpenShift, and this is the default configuration. Alternatively, you can manage one or more components externally yourself, where you want more control over the set up, and then allow the Operator to manage the remaining components.
The standard pattern for configuring unmanaged components is:
-
Create a
config.yamlconfiguration file with the appropriate settings Create a Secret using the configuration file
oc create secret generic --from-file config.yaml=./config.yaml config-bundle-secret
$ oc create secret generic --from-file config.yaml=./config.yaml config-bundle-secretCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a QuayRegistry YAML file
quayregistry.yaml, identifying the unmanaged components and also referencing the created Secret, for example:quayregistry.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Deploy the registry using the YAML file:
oc create -f quayregistry.yaml
oc create -f quayregistry.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
3.1. Pre-configuring Quay for automation Copy linkLink copied to clipboard!
Quay has a number of configuration options that support automation. These options can be set before deployment, to minimize the need to interact with the user interface.
3.1.1. Allowing the API to create the first user Copy linkLink copied to clipboard!
Set the config option FEATURE_USER_INITIALIZE to true, so that you can use the API /api/v1/user/initialize to create the first user. This API endpoint does not require authentication, unlike all other registry API calls which require an OAuth token which is generated by an OAuth application in an existing organization.
Once you have deployed Quay, you can use the API to create a user, for example, quayadmin, provided no other users have already been created. For more information, see the section on Creating the first user using the API
3.1.2. Enabling general API access Copy linkLink copied to clipboard!
Set the config option BROWSER_API_CALLS_XHR_ONLY to false, to allow general access to the Quay registry API.
3.1.3. Adding a super user Copy linkLink copied to clipboard!
While you cannot create a user until after deployment, it is convenient to ensure that first user is an administrator with full permissions. It is easier to configure this in advance, using the SUPER_USER configuration object.
3.1.4. Restricting user creation Copy linkLink copied to clipboard!
Once you have configured a super user, you can restrict the ability to create new users to the super user group. Set the FEATURE_USER_CREATION to false to restrict user creation.
3.1.5. Suggested configuration for automation Copy linkLink copied to clipboard!
Create a config.yaml configuration file that includes the appropriate settings:
config.yaml
3.1.6. Deploying the Operator using the initial configuration Copy linkLink copied to clipboard!
Create a Secret using the configuration file
oc create secret generic --from-file config.yaml=./config.yaml init-config-bundle-secret
$ oc create secret generic --from-file config.yaml=./config.yaml init-config-bundle-secretCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a QuayRegistry YAML file
quayregistry.yaml, identifying the unmanaged components and also referencing the created Secret, for example:quayregistry.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Deploy the registry:
oc create -f quayregistry.yaml
$ oc create -f quayregistry.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow -
Create the first user,
quayadmin, using the API
3.2. Configuring object storage Copy linkLink copied to clipboard!
You need to configure object storage before installing Red Hat Quay, irrespective of whether you are allowing the Operator to manage the storage or managing it yourself.
If you want the Operator to be responsible for managing storage, see the section on Managed storage for information on installing and configuring the NooBaa / RHOCS Operator.
If you are using a separate storage solution, set objectstorage as unmanaged when configuring the Operator. See the following section. Unmanaged storage, for details of configuring existing storage.
3.2.1. Unmanaged storage Copy linkLink copied to clipboard!
Some configuration examples for unmanaged storage are provided in this section for convenience. See the Red Hat Quay configuration guide for full details for setting up object storage.
3.2.1.1. AWS S3 storage Copy linkLink copied to clipboard!
3.2.1.2. Google cloud storage Copy linkLink copied to clipboard!
3.2.1.3. Azure storage Copy linkLink copied to clipboard!
3.2.1.4. NooBaa unmanaged storage Copy linkLink copied to clipboard!
-
Create a NooBaa Object Bucket Claim in the console at Storage
Object Bucket Claims. - Retrieve the Object Bucket Claim Data details including the Access Key, Bucket Name, Endpoint (hostname) and Secret Key.
Create a
config.yamlconfiguration file, using the information for the Object Bucket Claim:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
3.2.2. Managed storage Copy linkLink copied to clipboard!
If you want the Operator to manage object storage for Quay, your cluster needs to be capable of providing object storage via the ObjectBucketClaim API. Using the Red Hat OpenShift Data Foundation (ODF) Operator, there are two supported options available:
A standalone instance of the Multi-Cloud Object Gateway backed by a local Kubernetes
PersistentVolumestorage- Not highly available
- Included in the Quay subscription
- Does not require a separate subscription for ODF
A production deployment of ODF with scale-out Object Service and Ceph
- Highly available
- Requires a separate subscription for ODF
To use the standalone instance option, continue reading below. For production deployment of ODF, please refer to the official documentation.
Object storage disk space is allocated automatically by the Operator with 50 GiB. This number represents a usable amount of storage for most small to medium Red Hat Quay installations but may not be sufficient for your use cases. Resizing the RHOCS volume is currently not handled by the Operator. See the section below on resizing managed storage for more details.
3.2.2.1. About The Standalone Object Gateway Copy linkLink copied to clipboard!
As part of a Red Hat Quay subscription, users are entitled to use the Multi-Cloud Object Gateway (MCG) component of the Red Hat OpenShift Data Foundation Operator (formerly known as OpenShift Container Storage Operator). This gateway component allows you to provide an S3-compatible object storage interface to Quay backed by Kubernetes PersistentVolume-based block storage. The usage is limited to a Quay deployment managed by the Operator and to the exact specifications of the MCG instance as documented below.
Since Red Hat Quay does not support local filesystem storage, users can leverage the gateway in combination with Kubernetes PersistentVolume storage instead, to provide a supported deployment. A PersistentVolume is directly mounted on the gateway instance as a backing store for object storage and any block-based StorageClass is supported.
By the nature of PersistentVolume, this is not a scale-out, highly available solution and does not replace a scale-out storage system like Red Hat OpenShift Data Foundation (ODF). Only a single instance of the gateway is running. If the pod running the gateway becomes unavailable due to rescheduling, updates or unplanned downtime, this will cause temporary degradation of the connected Quay instances.
3.2.2.1.1. Create A Standalone Object Gateway Copy linkLink copied to clipboard!
To install the ODF (formerly known as OpenShift Container Storage) Operator and configure a single instance Multi-Cloud Gateway service, follow these steps:
-
Open the OpenShift console and select Operators
OperatorHub, then select the OpenShift Data Foundation Operator. - Select Install. Accept all default options and select Install again.
Within a minute, the Operator will install and create a namespace
openshift-storage. You can confirm it has completed when theStatuscolumn is markedSucceeded.When the installation of the ODF Operator is complete, you are prompted to create a storage system. Do not follow this instruction. Instead, create NooBaa object storage as outlined the following steps.
When the installation of the ODF Operator is complete, you are prompted to create a storage system. Do not follow this instruction. Instead, create NooBaa object storage as outlined the following steps.Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create NooBaa object storage. Save the following YAML to a file called
noobaa.yaml.Copy to Clipboard Copied! Toggle word wrap Toggle overflow This will create a single instance deployment of the Multi-cloud Object Gateway.
Apply the configuration with the following command:
oc create -n openshift-storage -f noobaa.yaml
$ oc create -n openshift-storage -f noobaa.yaml noobaa.noobaa.io/noobaa createdCopy to Clipboard Copied! Toggle word wrap Toggle overflow After a couple of minutes, you should see that the MCG instance has finished provisioning (
PHASEcolumn will be set toReady):oc get -n openshift-storage noobaas noobaa -w
$ oc get -n openshift-storage noobaas noobaa -w NAME MGMT-ENDPOINTS S3-ENDPOINTS IMAGE PHASE AGE noobaa [https://10.0.32.3:30318] [https://10.0.32.3:31958] registry.redhat.io/ocs4/mcg-core-rhel8@sha256:56624aa7dd4ca178c1887343c7445a9425a841600b1309f6deace37ce6b8678d Ready 3d18hCopy to Clipboard Copied! Toggle word wrap Toggle overflow Next, configure a backing store for the gateway. Save the following YAML to a file called
noobaa-pv-backing-store.yaml.noobaa-pv-backing-store.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Apply the configuration with the following command:
oc create -f noobaa-pv-backing-store.yaml
$ oc create -f noobaa-pv-backing-store.yaml backingstore.noobaa.io/noobaa-pv-backing-store createdCopy to Clipboard Copied! Toggle word wrap Toggle overflow This creates the backing store configuration for the gateway. All images in Quay will be stored as objects through the gateway in a
PersistentVolumecreated by the above configuration.Finally, run the following command to make the
PersistentVolumebacking store the default for allObjectBucketClaimsissued by the Operator.oc patch bucketclass noobaa-default-bucket-class --patch '{"spec":{"placementPolicy":{"tiers":[{"backingStores":["noobaa-pv-backing-store"]}]}}}' --type merge -n openshift-storage$ oc patch bucketclass noobaa-default-bucket-class --patch '{"spec":{"placementPolicy":{"tiers":[{"backingStores":["noobaa-pv-backing-store"]}]}}}' --type merge -n openshift-storageCopy to Clipboard Copied! Toggle word wrap Toggle overflow
This concludes the setup of the Multi-Cloud Object Gateway instance for Red Hat Quay. Note that this configuration cannot be run in parallel on a cluster with Red Hat OpenShift Data Foundation installed.
3.3. Configuring the database Copy linkLink copied to clipboard!
3.3.1. Using an existing Postgres database Copy linkLink copied to clipboard!
Create a configuration file
config.yamlwith the necessary database fields:config.yaml:
DB_URI: postgresql://test-quay-database:postgres@test-quay-database:5432/test-quay-database
DB_URI: postgresql://test-quay-database:postgres@test-quay-database:5432/test-quay-databaseCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a Secret using the configuration file:
kubectl create secret generic --from-file config.yaml=./config.yaml config-bundle-secret
$ kubectl create secret generic --from-file config.yaml=./config.yaml config-bundle-secretCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a QuayRegistry YAML file
quayregistry.yamlwhich marks thepostgrescomponent as unmanaged and references the created Secret:quayregistry.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - Deploy the registry as detailed in the following sections.
3.3.2. Database configuration Copy linkLink copied to clipboard!
You configure the connection to the database using the required DB_URI field and optional connection arguments in the DB_CONNECTION_ARGS structure. Some key-value pairs defined under DB_CONNECTION_ARGS are generic while others are database-specific. In particular, SSL configuration depends on the database you are deploying, and examples for PostgreSQL and MySQL are given below.
3.3.2.1. Database URI Copy linkLink copied to clipboard!
| Field | Type | Description |
|---|---|---|
|
DB_URI | String | The URI for accessing the database, including any credentials |
Example:
postgresql://quayuser:quaypass@quay-server.example.com:5432/quay
postgresql://quayuser:quaypass@quay-server.example.com:5432/quay
3.3.2.2. Database connection arguments Copy linkLink copied to clipboard!
| Field | Type | Description |
|---|---|---|
| DB_CONNECTION_ARGS | Object | Optional connection arguments for the database, such as timeouts and SSL |
| .autorollback | Boolean |
Whether to use thread-local connections |
| .threadlocals | Boolean |
Whether to use auto-rollback connections |
3.3.2.2.1. PostgreSQL SSL connection arguments Copy linkLink copied to clipboard!
A sample PostgreSQL SSL configuration is given below:
DB_CONNECTION_ARGS: sslmode: verify-ca sslrootcert: /path/to/cacert
DB_CONNECTION_ARGS:
sslmode: verify-ca
sslrootcert: /path/to/cacert
The sslmode option determines whether or with what priority a secure SSL TCP/IP connection will be negotiated with the server. There are six modes:
- disable: only try a non-SSL connection
- allow: first try a non-SSL connection; if that fails, try an SSL connection
- prefer: (default) first try an SSL connection; if that fails, try a non-SSL connection
- require: only try an SSL connection. If a root CA file is present, verify the certificate in the same way as if verify-ca was specified
- verify-ca: only try an SSL connection, and verify that the server certificate is issued by a trusted certificate authority (CA)
- verify-full: only try an SSL connection, verify that the server certificate is issued by a trusted CA and that the requested server host name matches that in the certificate
More information on the valid arguments for PostgreSQL is available at https://www.postgresql.org/docs/current/libpq-connect.html.
3.3.2.2.2. MySQL SSL connection arguments Copy linkLink copied to clipboard!
A sample MySQL SSL configuration follows:
DB_CONNECTION_ARGS:
ssl:
ca: /path/to/cacert
DB_CONNECTION_ARGS:
ssl:
ca: /path/to/cacert
Information on the valid connection arguments for MySQL is available at https://dev.mysql.com/doc/refman/8.0/en/connecting-using-uri-or-key-value-pairs.html.
3.3.3. Using the managed PostgreSQL Copy linkLink copied to clipboard!
Recommendations:
- Database backups should be performed regularly using either the supplied tools on the Postgres image or your own backup infrastructure. The Operator does not currently ensure the Postgres database is backed up.
-
Restoring the Postgres database from a backup must be done using Postgres tools and procedures. Be aware that your Quay
Podsshould not be running while the database restore is in progress. - Database disk space is allocated automatically by the Operator with 50 GiB. This number represents a usable amount of storage for most small to medium Red Hat Quay installations but may not be sufficient for your use cases. Resizing the database volume is currently not handled by the Operator.
3.4. Configuring TLS and routes Copy linkLink copied to clipboard!
Support for OpenShift Container Platform Edge-Termination Routes has been added by way of a new managed component, tls. This separates the route component from TLS and allows users to configure both separately. EXTERNAL_TLS_TERMINATION: true is the opinionated setting. Managed tls means that the default cluster wildcard cert is used. Unmanaged tls means that the user provided cert/key pair will be injected into the Route.
ssl.cert and ssl.key are now moved to a separate, persistent Secret, which ensures that the cert/key pair is not re-generated upon every reconcile. These are now formatted as edge routes and mounted to the same directory in the Quay container.
Multiple permutations are possible when configuring TLS and Routes, but the following rules apply:
-
If TLS is
managed, then route must also bemanaged -
If TLS is
unmanagedthen you must supply certs, either with the config tool or directly in the config bundle
The following table outlines the valid options:
| Option | Route | TLS | Certs provided | Result |
|---|---|---|---|---|
| My own load balancer handles TLS | Managed | Managed | No | Edge Route with default wildcard cert |
| Red Hat Quay handles TLS | Managed | Unmanaged | Yes | Passthrough route with certs mounted inside the pod |
| Red Hat Quay handles TLS | Unmanaged | Unmanaged | Yes | Certificates are set inside the quay pod but route must be created manually |
Red Hat Quay 3.6 does not support builders when TLS is managed by the Operator.
3.4.1. Creating the config bundle secret with TLS cert, key pair: Copy linkLink copied to clipboard!
To add your own TLS cert and key, include them in the config bundle secret as follows:
oc create secret generic --from-file config.yaml=./config.yaml --from-file ssl.cert=./ssl.cert --from-file ssl.key=./ssl.key config-bundle-secret
$ oc create secret generic --from-file config.yaml=./config.yaml --from-file ssl.cert=./ssl.cert --from-file ssl.key=./ssl.key config-bundle-secret
3.5. Configuring other components Copy linkLink copied to clipboard!
3.5.1. Using external Redis Copy linkLink copied to clipboard!
If you wish to use an external Redis database, set the component as unmanaged in the QuayRegistry instance:
Create a configuration file
config.yamlwith the necessary redis fields:Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a Secret using the configuration file
oc create secret generic --from-file config.yaml=./config.yaml config-bundle-secret
$ oc create secret generic --from-file config.yaml=./config.yaml config-bundle-secretCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a QuayRegistry YAML file
quayregistry.yamlwhich marks redis component as unmanaged and references the created Secret:Copy to Clipboard Copied! Toggle word wrap Toggle overflow - Deploy the registry
3.5.1.1. Redis configuration fields Copy linkLink copied to clipboard!
3.5.1.1.1. Build logs Copy linkLink copied to clipboard!
| Field | Type | Description |
|---|---|---|
|
BUILDLOGS_REDIS | Object | Redis connection details for build logs caching |
|
.host | String |
The hostname at which Redis is accessible |
|
.port | Number |
The port at which Redis is accessible |
| .password | String |
The port at which Redis is accessible |
3.5.1.1.2. User events Copy linkLink copied to clipboard!
| Field | Type | Description |
|---|---|---|
|
USER_EVENTS_REDIS | Object | Redis connection details for user event handling |
|
.host | String |
The hostname at which Redis is accessible |
|
.port | Number |
The port at which Redis is accessible |
| .password | String |
The port at which Redis is accessible |
3.5.1.1.3. Example redis configuration Copy linkLink copied to clipboard!
3.5.2. Disabling the Horizontal Pod Autoscaler Copy linkLink copied to clipboard!
HorizontalPodAutoscalers have been added to the Clair, Quay, and Mirror pods, so that they now automatically scale during load spikes.
As HPA is configured by default to be managed, the number of pods for Quay, Clair and repository mirroring is set to two. This facilitates the avoidance of downtime when updating / reconfiguring Quay via the Operator or during rescheduling events.
If you wish to disable autoscaling or create your own HorizontalPodAutoscaler, simply specify the component as unmanaged in the QuayRegistry instance:
3.5.3. Disabling Route Component Copy linkLink copied to clipboard!
To prevent the Operator from creating a Route:
Mark the component as unmanaged in the
QuayRegistry:Copy to Clipboard Copied! Toggle word wrap Toggle overflow Specify that you want Quay to handle TLS in the configuration, by editing the
config.yamlfile:config.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If you do not configure the unmanaged Route correctly, you will see an error similar to the following:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Disabling the default Route means you are now responsible for creating a Route, Service, or Ingress in order to access the Quay instance and that whatever DNS you use must match the SERVER_HOSTNAME in the Quay config.
3.5.4. Unmanaged monitoring Copy linkLink copied to clipboard!
If you install the Quay Operator in a single namespace, the monitoring component is automatically set to 'unmanaged'. To enable monitoring in this scenario, see the section Section 8.2, “Enabling monitoring when Operator is installed in a single namespace”.
To disable monitoring explicitly:
3.5.5. Unmanaged mirroring Copy linkLink copied to clipboard!
To disable mirroring explicitly: