Configure Image Registry on GCP
This guide explains how the OpenShift image registry works on GCP hosted clusters, how to verify it is functioning, and how to configure or disable it.
Overview
GCP hosted clusters use Workload Identity Federation (WIF) to grant the image registry operator access to a Google Cloud Storage (GCS) bucket for storing container images. No long-lived credentials are stored — the operator uses short-lived tokens issued by the hosted cluster's OIDC provider.
| Component | Name / Location | Purpose |
|---|---|---|
| GCP Service Account | <infra-id>-image-registry@<project-id>.iam.gserviceaccount.com |
Identity that GCS bucket operations run as |
| WIF credential secret | installer-cloud-credentials in openshift-image-registry |
Federated credential JSON consumed by the registry operator |
| Kubernetes service account | cluster-image-registry-operator in openshift-image-registry |
Issues OIDC tokens exchanged for GCP access tokens |
| GCS bucket | Auto-created by the registry operator | Stores container image layers and manifests |
Prerequisites
- A running GCP hosted cluster with
ocaccess to the guest cluster - The
image-registryGCP service account created during IAM setup (see Create GCP IAM Resources) - The
--image-registry-service-accountflag provided when the cluster was created (see Create a GCP Hosted Cluster)
Default Behavior
When a GCP hosted cluster starts up, the image registry is enabled automatically through a three-step flow:
-
Credential propagation — The HyperShift control plane reads the
image-registryGSA email from theHostedControlPlanespec and generates a WIF credential JSON. This credential is written to theinstaller-cloud-credentialssecret in theopenshift-image-registrynamespace on the guest cluster. -
Bucket creation — The cluster image registry operator reads the WIF credentials and creates a GCS bucket. The bucket name is chosen automatically based on the cluster's infrastructure ID and region.
-
Registry available — Once the bucket exists and the credentials are valid, the registry operator reports
Available=Trueand the internal registry endpoint becomes active atimage-registry.openshift-image-registry.svc:5000.
No manual configuration is required when the cluster is created with the --image-registry-service-account flag.
Verification
Check ClusterOperator Status
Verify the image registry operator is available:
KUBECONFIG=hosted-kubeconfig oc get clusteroperator image-registry
Expected output:
NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE MESSAGE
image-registry 4.18.0 True False False 5m
Check Registry Configuration
Inspect the registry operator configuration to see the GCS bucket that was created:
KUBECONFIG=hosted-kubeconfig oc get configs.imageregistry.operator.openshift.io cluster -o jsonpath='{.spec.storage}'
Expected output shows the GCS bucket:
{"gcs":{"bucket":"<auto-generated-bucket-name>","region":"<region>"}}
Check WIF Credentials
Verify the WIF credential secret was propagated to the guest cluster:
KUBECONFIG=hosted-kubeconfig oc get secret installer-cloud-credentials \
-n openshift-image-registry -o jsonpath='{.data.service_account\.json}' | base64 -d | python3 -m json.tool
The decoded JSON should contain "type": "external_account" and reference your WIF pool and provider IDs, confirming that short-lived federated tokens are used rather than a service account key.
Advanced Configuration
Custom Bucket Name
To use a specific GCS bucket name instead of the auto-generated one, patch the registry operator configuration after cluster creation:
KUBECONFIG=hosted-kubeconfig oc patch configs.imageregistry.operator.openshift.io cluster \
--type=merge \
--patch='{"spec":{"storage":{"gcs":{"bucket":"<your-bucket-name>","region":"<region>"}}}}'
Bucket must exist
The bucket must already exist and the image-registry GSA must have Storage Admin permissions on it. The registry operator will not create a bucket when one is explicitly specified.
Using a Pre-Existing Bucket
If your organization requires using a pre-existing GCS bucket (for example, to apply custom lifecycle policies or retention rules):
-
Create the bucket in the hosted cluster GCP project:
gsutil mb -p <project-id> -l <region> gs://<your-bucket-name> -
Grant the
image-registryGSAStorage Adminaccess:gsutil iam ch \ serviceAccount:<infra-id>-image-registry@<project-id>.iam.gserviceaccount.com:roles/storage.admin \ gs://<your-bucket-name> -
Configure the registry operator to use the bucket:
KUBECONFIG=hosted-kubeconfig oc patch configs.imageregistry.operator.openshift.io cluster \ --type=merge \ --patch='{"spec":{"storage":{"gcs":{"bucket":"<your-bucket-name>","region":"<region>"}}}}'
Disabling the Image Registry
The image registry can be disabled via the ImageRegistry capability on the HostedCluster. When disabled, the registry operator is not deployed and no GCS bucket is created.
To disable the image registry at cluster creation time, add --capabilities-disabled=ImageRegistry to the hypershift create cluster gcp command (refer to Create a GCP Hosted Cluster for the full command).
To disable the registry on a running cluster, patch the HostedCluster resource on the management cluster:
oc patch hostedcluster <cluster-name> -n <namespace> \
--type=merge \
--patch='{"spec":{"capabilities":{"disabled":["ImageRegistry"]}}}'
Note
This merge patch replaces the entire spec.capabilities.disabled list. If your cluster already has other capabilities disabled, include them in the patch to avoid re-enabling them.
Data loss
Disabling the image registry does not delete the GCS bucket or its contents. However, any images stored in the registry will become inaccessible to the cluster while the registry is disabled.
Troubleshooting
Registry Operator Not Available
If oc get clusteroperator image-registry shows Available=False:
-
Check the registry operator logs:
KUBECONFIG=hosted-kubeconfig oc logs -n openshift-image-registry \ deployment/cluster-image-registry-operator -
Check the
installer-cloud-credentialssecret exists:KUBECONFIG=hosted-kubeconfig oc get secret installer-cloud-credentials \ -n openshift-image-registryIf the secret is missing, check the control plane namespace on the management cluster:
oc get events -n <namespace>-<cluster-name> | grep image-registry
GCS Bucket Creation Fails (403 Forbidden)
A 403 error on bucket creation means the image-registry GSA does not have sufficient permissions.
Check that the GSA has the Storage Admin role:
gcloud projects get-iam-policy <project-id> \
--flatten="bindings[].members" \
--filter="bindings.members:<infra-id>-image-registry@<project-id>.iam.gserviceaccount.com" \
--format="table(bindings.role)"
The output should include roles/storage.admin. If it does not, recreate the IAM resources using hypershift create iam gcp or grant the role manually:
gcloud projects add-iam-policy-binding <project-id> \
--member="serviceAccount:<infra-id>-image-registry@<project-id>.iam.gserviceaccount.com" \
--role="roles/storage.admin"
WIF Authentication Errors
If the registry operator logs show token exchange errors (e.g., invalid_grant or audience mismatch):
-
Verify the WIF credential references the correct pool and provider:
KUBECONFIG=hosted-kubeconfig oc get secret installer-cloud-credentials \ -n openshift-image-registry -o jsonpath='{.data.service_account\.json}' | base64 -dConfirm the
audiencefield matches the WIF provider URL://iam.googleapis.com/projects/<project-number>/locations/global/workloadIdentityPools/<pool-id>/providers/<provider-id> -
Verify the WIF provider trust configuration allows the Kubernetes service account:
gcloud iam workload-identity-pools providers describe <provider-id> \ --workload-identity-pool=<pool-id> \ --project=<project-id> \ --location=global
Bucket Already Exists (409 Conflict)
GCS bucket names are globally unique. If the auto-generated name conflicts with an existing bucket, the registry operator will log a 409 error.
Configure the registry to use a different bucket name:
KUBECONFIG=hosted-kubeconfig oc patch configs.imageregistry.operator.openshift.io cluster \
--type=merge \
--patch='{"spec":{"storage":{"gcs":{"bucket":"<unique-bucket-name>","region":"<region>"}}}}'
Then create the bucket and grant permissions as described in Using a Pre-Existing Bucket.
Storage Quota Exceeded
If the GCP project has a storage quota that limits GCS bucket creation or capacity, check current quota usage in the GCP Console Cloud Storage quotas page and request an increase if needed, or contact your GCP administrator.
Related Documentation
- Create GCP IAM Resources — Create the
image-registryGSA and WIF bindings - Create a GCP Hosted Cluster — Full cluster creation with the
--image-registry-service-accountflag - GCP Workload Identity Federation — Upstream GCP WIF documentation
- OpenShift Image Registry Operator — Upstream registry operator documentation