Migrate a QuayEcosystem deployment to QuayRegistry
Migrate a QuayEcosystem deployment to QuayRegistry, review supported configurations, and revert if needed.
Migrating QuayEcosystem to QuayRegistry
To migrate an existing QuayEcosystem to a QuayRegistry managed by the Project Quay Operator, add the migration label to the QuayEcosystem custom resource and wait for the new QuayRegistry to start. You can then verify the migration and delete the old QuayEcosystem.
-
Add
"quay-operator/migrate": "true"to themetadata.labelsof theQuayEcosystem.$ oc edit quayecosystem <quayecosystem_name>metadata: labels: quay-operator/migrate: "true" -
Wait for a
QuayRegistryCR to be created with the samemetadata.nameas yourQuayEcosystem. TheQuayEcosystemCR is marked with the label"quay-operator/migration-complete": "true". -
After the
status.registryEndpointof the newQuayRegistryis set, access Project Quay and confirm that all data and settings were migrated successfully. -
If everything works correctly, you can delete the
QuayEcosystem. Kubernetes garbage collection cleans up all old resources.
Supported QuayEcosystem configurations for migration
The Project Quay Operator reports errors in its logs and in status.conditions if migrating a QuayEcosystem component fails or is unsupported.
All unmanaged components should migrate successfully because no Kubernetes resources need to be adopted and all the necessary values are already provided in Project Quay’s config.yaml file.
- Database
-
Ephemeral database not supported (
volumeSizefield must be set). - Redis
-
Nothing special needed.
- External Access
-
Only passthrough
Routeaccess is supported for automatic migration. Manual migration required for other methods.-
LoadBalancerwithout custom hostname: After theQuayEcosystemis marked with label"quay-operator/migration-complete": "true", delete themetadata.ownerReferencesfield from existingServicebefore deleting theQuayEcosystemto prevent Kubernetes from garbage collecting theServiceand removing the load balancer. A newServicewill be created withmetadata.nameformat<QuayEcosystem-name>-quay-app. Edit thespec.selectorof the existingServiceto match thespec.selectorof the newServiceso traffic to the old load balancer endpoint will now be directed to the new pods. You are now responsible for the oldService; the Quay Operator will not manage it. -
LoadBalancer/NodePort/Ingresswith custom hostname: A newServiceof typeLoadBalancerwill be created withmetadata.nameformat<QuayEcosystem-name>-quay-app. Change your DNS settings to point to thestatus.loadBalancerendpoint provided by the newService.
-
- Clair
-
Nothing special needed.
- Object Storage
-
QuayEcosystemdid not have a managed object storage component, so object storage will always be marked as unmanaged. Local storage is not supported. - Repository Mirroring
-
Nothing special needed.
Reverting QuayEcosystem migration
To revert to the QuayEcosystem when migration to QuayRegistry fails or causes issues, delete the QuayRegistry and restore the Route to the original Service. You can then use the Project Quay deployment managed by the QuayEcosystem.
|
Note
|
If your |
-
Delete the
QuayRegistryusing either the UI orkubectl:$ kubectl delete -n <namespace> quayregistry <quayecosystem-name> -
If external access was provided using a
Route, change theRouteto point back to the originalServiceusing the UI orkubectl.
Migrate a standalone Red Hat Quay deployment to the Operator
Back up a standalone Red Hat Quay deployment and migrate registry content to Red Hat Quay on OpenShift Container Platform.
Backing up a standalone deployment of Project Quay
To back up a standalone Project Quay deployment before Operator migration, you can copy config.yaml, dump the database, and sync object storage blobs.
-
Back up the
config.yamlof your standalone Project Quay deployment:$ mkdir /tmp/quay-backup $ cp /path/to/Quay/config/directory/config.yaml /tmp/quay-backup -
Create a backup of the database that your standalone Project Quay deployment is using:
$ pg_dump -h DB_HOST -p 5432 -d QUAY_DATABASE_NAME -U QUAY_DATABASE_USER -W -O > /tmp/quay-backup/quay-database-backup.sql -
Install the AWS CLI if you do not have it already.
-
Create an
~/.aws/directory:$ mkdir ~/.aws/ -
Obtain the
access_keyandsecret_keyfrom theconfig.yamlof your standalone deployment:$ grep -i DISTRIBUTED_STORAGE_CONFIG -A10 /tmp/quay-backup/config.yamlExample output:DISTRIBUTED_STORAGE_CONFIG: minio-1: - RadosGWStorage - access_key: ########## bucket_name: quay hostname: 172.24.10.50 is_secure: false port: "9000" secret_key: ########## storage_path: /datastorage/registry -
Store the
access_keyandsecret_keyfrom theconfig.yamlfile in your~/.awsdirectory:$ touch ~/.aws/credentials -
Optional: Check that your
access_keyandsecret_keyare stored:$ cat > ~/.aws/credentials << EOF [default] aws_access_key_id = ACCESS_KEY_FROM_QUAY_CONFIG aws_secret_access_key = SECRET_KEY_FROM_QUAY_CONFIG EOFExample output:aws_access_key_id = ACCESS_KEY_FROM_QUAY_CONFIG aws_secret_access_key = SECRET_KEY_FROM_QUAY_CONFIGNoteIf the AWS CLI does not automatically collect the
access_keyandsecret_keyfrom the~/.aws/credentialsfile, you can configure these by runningaws configureand manually entering the credentials. -
In your
quay-backupdirectory, create abucket_backupdirectory:$ mkdir /tmp/quay-backup/bucket-backup -
Back up all blobs from the S3 storage:
$ aws s3 sync --no-verify-ssl --endpoint-url https://PUBLIC_S3_ENDPOINT:PORT s3://QUAY_BUCKET/ /tmp/quay-backup/bucket-backup/NoteThe
PUBLIC_S3_ENDPOINTcan be read from the Project Quayconfig.yamlfile underhostnamein theDISTRIBUTED_STORAGE_CONFIG. If the endpoint is insecure, usehttpinstead ofhttpsin the endpoint URL.
Using backed up standalone content to migrate to OpenShift Container Platform
To migrate backed-up standalone Project Quay content to OpenShift Container Platform, you can restore the database, apply a custom configuration bundle, and sync blobs to Object Bucket storage.
-
Your standalone Project Quay data, blobs, database, and
config.yamlhave been backed up. -
Project Quay is deployed on OpenShift Container Platform using the Project Quay Operator.
-
A
QuayRegistrywith all components set tomanaged.
|
Note
|
The procedure in this document uses the following namespace: |
-
Scale down the Project Quay Operator:
$ oc scale --replicas=0 deployment quay-operator.v3.6.2 -n openshift-operators -
Scale down the application and mirror deployments:
$ oc scale --replicas=0 deployment QUAY_MAIN_APP_DEPLOYMENT QUAY_MIRROR_DEPLOYMENT -
Copy the database SQL backup to the
QuayPostgreSQL database instance:$ oc cp /tmp/user/quay-backup/quay-database-backup.sql quay-enterprise/quayregistry-quay-database-54956cdd54-p7b2w:/var/lib/pgsql/data/userdata -
Obtain the database password from the Operator-created
config.yamlfile:$ oc get deployment quay-quay-app -o json | jq '.spec.template.spec.volumes[].projected.sources' | grep -i config-secretExample output:"name": "QUAY_CONFIG_SECRET_NAME"$ oc get secret quay-quay-config-secret-9t77hb84tb -o json | jq '.data."config.yaml"' | cut -d '"' -f2 | base64 -d -w0 > /tmp/quay-backup/operator-quay-config-yaml-backup.yaml$ cat /tmp/quay-backup/operator-quay-config-yaml-backup.yaml | grep -i DB_URIExample output:postgresql://QUAY_DATABASE_OWNER:PASSWORD@DATABASE_HOST/QUAY_DATABASE_NAME
-
Execute a shell inside of the database pod:
# oc exec -it quay-postgresql-database-pod -- /bin/bash -
Enter psql:
bash-4.4$ psql -
Drop the database:
postgres=# DROP DATABASE "example-restore-registry-quay-database";Example output:DROP DATABASE
-
Create a new database and set the owner as the same name:
postgres=# CREATE DATABASE "example-restore-registry-quay-database" OWNER "example-restore-registry-quay-database";Example output:CREATE DATABASE
-
Connect to the database:
postgres=# \c "example-restore-registry-quay-database";Example output:You are now connected to database "example-restore-registry-quay-database" as user "postgres". -
Create a
pg_trgmextension of yourQuaydatabase:example-restore-registry-quay-database=# CREATE EXTENSION IF NOT EXISTS pg_trgm ;Example output:CREATE EXTENSION -
Exit the postgres CLI to re-enter bash-4.4:
\q -
Set the password for your PostgreSQL deployment:
bash-4.4$ psql -h localhost -d "QUAY_DATABASE_NAME" -U QUAY_DATABASE_OWNER -W < /var/lib/pgsql/data/userdata/quay-database-backup.sqlExample output:SET SET SET SET SET
-
Exit bash mode:
bash-4.4$ exit -
Create a new configuration bundle for the Project Quay Operator.
$ touch config-bundle.yaml -
In your new
config-bundle.yaml, include all of the information that the registry requires, such as LDAP configuration, keys, and other modifications that your old registry had. Run the following command to move thesecret_keyto yourconfig-bundle.yaml:$ cat /tmp/quay-backup/config.yaml | grep SECRET_KEY > /tmp/quay-backup/config-bundle.yamlNoteYou must manually copy all the LDAP, OIDC, and other information and add it to the
/tmp/quay-backup/config-bundle.yamlfile. -
Create a configuration bundle secret inside of your OpenShift cluster:
$ oc create secret generic new-custom-config-bundle --from-file=config.yaml=/tmp/quay-backup/config-bundle.yaml -
Scale up the
Quaypods:$ oc scale --replicas=1 deployment quayregistry-quay-appExample output:deployment.apps/quayregistry-quay-app scaled -
Scale up the mirror pods:
$ oc scale --replicas=1 deployment quayregistry-quay-mirrorExample output:deployment.apps/quayregistry-quay-mirror scaled -
Patch the
QuayRegistryCRD so that it contains the reference to the new custom configuration bundle:$ oc patch quayregistry QUAY_REGISTRY_NAME --type=merge -p '{"spec":{"configBundleSecret":"new-custom-config-bundle"}}'NoteIf Project Quay returns a
500internal server error, you might have to update thelocationof yourDISTRIBUTED_STORAGE_CONFIGtodefault. -
Create a new AWS
credentials.yamlin your/.aws/directory and include theaccess_keyandsecret_keyfrom the Operator-createdconfig.yamlfile:$ touch credentials.yaml$ grep -i DISTRIBUTED_STORAGE_CONFIG -A10 /tmp/quay-backup/operator-quay-config-yaml-backup.yaml$ cat > ~/.aws/credentials << EOF [default] aws_access_key_id = ACCESS_KEY_FROM_QUAY_CONFIG aws_secret_access_key = SECRET_KEY_FROM_QUAY_CONFIG EOFNoteIf the AWS CLI does not automatically collect the
access_keyandsecret_keyfrom the~/.aws/credentialsfile, you can configure these by runningaws configureand manually entering the credentials. -
Record the NooBaa’s publicly available endpoint:
$ oc get route s3 -n openshift-storage -o yaml -o jsonpath="{.spec.host}{'\n'}" -
Sync the backup data to the NooBaa backend storage:
$ aws s3 sync --no-verify-ssl --endpoint-url https://NOOBAA_PUBLIC_S3_ROUTE /tmp/quay-backup/bucket-backup/* s3://QUAY_DATASTORE_BUCKET_NAME -
Scale the Operator back up to 1 pod:
$ oc scale --replicas=1 deployment quay-operator.v3.6.4 -n openshift-operatorsThe Operator uses the custom configuration bundle provided and reconciles all secrets and deployments. Your new Project Quay deployment on OpenShift Container Platform contains all of the information that the old deployment had. You can pull all images.
Migrate Microsoft Entra ID OIDC from v1.0 to v2.0
Migrate Microsoft Entra ID OIDC from v1.0 to v2.0 using a dual-issuer cutover and multi-issuer configuration.
Dual-issuer cutover from Entra ID v1.0 to v2.0
To migrate from Microsoft Entra ID v1.0 to v2.0 without interrupting clients in Project Quay, you can set the v2.0 discovery endpoint and temporarily list both issuers in OIDC_ISSUERS.
-
Set
OIDC_SERVERto the v2.0 endpoint (https://login.microsoftonline.com/<tenant-id>/v2.0/). -
Add both issuer URLs to
OIDC_ISSUERS:OIDC_ISSUERS: - https://sts.windows.net/<tenant-id>/ - https://login.microsoftonline.com/<tenant-id>/v2.0 -
Update upstream clients to v2.0 tokens.
-
After all clients use v2.0, remove the v1.0 issuer from
OIDC_ISSUERS.
Configuring Microsoft Entra ID v2 and multi-issuer OIDC
To accept Microsoft Entra ID v2.0 tokens and On-Behalf-Of API flows in Project Quay, you can configure multi-issuer and multi-audience settings in your OIDC *_LOGIN_CONFIG block. This support enables Microsoft Entra ID v2.0 access tokens, dual v1.0 and v2.0 acceptance during migration, and On-Behalf-Of (OBO) API flows used by integrations such as Red Hat Developer Hub (RHDH).
-
You have an Entra ID app registration for Project Quay with a client secret and redirect URIs for your Project Quay hostname.
-
You can edit the Project Quay
config.yamlfile or OperatorconfigBundleSecretresource.
-
In the Azure Portal, open your Project Quay app registration and set
requestedAccessTokenVersionto2in the app manifest. The field might appear asapi.requestedAccessTokenVersion.For OBO flows, expose an API on the Project Quay app registration, for example
api://quay-api, and grant the upstream application permission to that scope. -
Update your
*_LOGIN_CONFIGblock with the v2.0 discovery endpoint and multi-issuer settings. For example:AUTHENTICATION_TYPE: OIDC # ... AZURE_LOGIN_CONFIG: CLIENT_ID: <quay_app_client_id> CLIENT_SECRET: <quay_app_client_secret> OIDC_SERVER: https://login.microsoftonline.com/<tenant-id>/v2.0/ SERVICE_NAME: Microsoft Entra ID OIDC_DISABLE_USER_ENDPOINT: true OIDC_ISSUERS: - https://sts.windows.net/<tenant-id>/ - https://login.microsoftonline.com/<tenant-id>/v2.0 OIDC_AUDIENCES: - <quay_app_client_id> - api://quay-api OIDC_ALLOWED_CLIENTS: - <quay_app_client_id> - <upstream_app_client_id> USE_PKCE: true PKCE_METHOD: "S256" PUBLIC_CLIENT: true # ... -
Restart your Project Quay deployment or reconcile the Operator so the updated configuration is applied.
Note-
Set
OIDC_SERVERto the v2.0 endpoint. The v2.0 JWKS endpoint includes v1.0 signing keys, so one discovery URL supports both token versions. -
If you set
OIDC_ALLOWED_CLIENTS, include your Project Quay application’s ownCLIENT_ID. Direct user logins setazpto the application’s client ID. OmitOIDC_ALLOWED_CLIENTSif you do not need to restrict OBO clients. -
Do not request Microsoft Graph scopes such as
openid profile emailwhen you need tokens with a custom audience. Use application-specific scopes such asapi://quay-api/registry.accessinstead.
-