Migrate container images from a third-party registry

If you pull some container images directly from third-party registries todeploy to Google Cloud environments such as Google Kubernetes Engine or Cloud Run,then rate limits on image pulls or third-party outages can disrupt your builds anddeployments. This page describes how to identify and copy those images toArtifact Registry for consolidated, consistent container image management.

Artifact Registry doesn't monitor third-party registries for updates toimages you copy to Artifact Registry. If you want to incorporate a newerversion of an image into your pipeline, then you must push it toArtifact Registry.

Migration overview

Migration of your container images includes the following steps:

  1. Set upprerequisites.
  2. Identify images to migrate.
    • Search your Dockerfile files and deployment manifests for references tothird-party registries
    • Determine pull frequency of images from third-party registries usingCloud Logging and BigQuery.
  3. Copy identified images to Artifact Registry.
  4. Verify thatpermissions to the registry are correctlyconfigured, particularly if Artifact Registry and your Google Clouddeployment environment are in different projects.
  5. Updatemanifests for your deployments.
  6. Re-deploy your workloads.

Before you begin

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.

  3. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  4. Toinitialize the gcloud CLI, run the following command:

    gcloudinit
  5. Create or select a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.create permission.Learn how to grant roles.
    Note: If you don't plan to keep the resources that you create in this procedure, create a project instead of selecting an existing project. After you finish these steps, you can delete the project, removing all resources associated with the project.
    • Create a Google Cloud project:

      gcloud projects createPROJECT_ID

      ReplacePROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set projectPROJECT_ID

      ReplacePROJECT_ID with your Google Cloud project name.

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Artifact Registry API:

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enable permission.Learn how to grant roles.

    gcloudservicesenableartifactregistry.googleapis.com
  8. Install the Google Cloud CLI.

  9. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  10. Toinitialize the gcloud CLI, run the following command:

    gcloudinit
  11. Create or select a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.create permission.Learn how to grant roles.
    Note: If you don't plan to keep the resources that you create in this procedure, create a project instead of selecting an existing project. After you finish these steps, you can delete the project, removing all resources associated with the project.
    • Create a Google Cloud project:

      gcloud projects createPROJECT_ID

      ReplacePROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set projectPROJECT_ID

      ReplacePROJECT_ID with your Google Cloud project name.

  12. Verify that billing is enabled for your Google Cloud project.

  13. Enable the Artifact Registry API:

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enable permission.Learn how to grant roles.

    gcloudservicesenableartifactregistry.googleapis.com
  14. If you don't have a Artifact Registry repository, thencreate a repository andconfigure authentication for third-party clients that require access to the repository.
  15. Verify your permissions. You must have theOwner or Editor IAM role on the projects where you are migrating images to Artifact Registry.
  16. Export the following environment variables:
    exportPROJECT=$(gcloudconfigget-valueproject)
  17. Verify that Go version 1.13 or newer is installed.
    goversion
    If you need to install or update Go, see the Goinstallation documentation.

Costs

This guide uses the following billable components of Google Cloud:

Identify images to migrate

Search the files you use to build and deploy your container images forreferences to third-party registries, then check how often you pull the images.

Identify references in Dockerfiles

Perform this step in a location where your Dockerfiles are stored. This mightbe where your code is locally checked out or in Cloud Shell if the files areavailable in a VM.

In the directory with your Dockerfiles, run the command:

grep-inr-H--includeDockerfile\*"FROM".|grep-i-v-E'docker.pkg.dev|gcr.io'

The output looks like the following example:

./code/build/baseimage/Dockerfile:1:FROM debian:stretch./code/build/ubuntubase/Dockerfile:1:FROM ubuntu:latest./code/build/pythonbase/Dockerfile:1:FROM python:3.5-buster

This command searches all the Dockerfiles in your directory and identifies the"FROM" line. Adjust the command as needed to match the way you store yourDockerfiles.

Identify references in manifests

Perform these steps in a location where your GKE orCloud Run manifests are stored. This might be where your codeis locally checked out or in Cloud Shell if the files areavailable in a VM.
  1. In the directory with your GKE or Cloud Run manifests run the following command:
    grep-inr-H--include\*.yaml"image:".|grep-i-v-E'docker.pkg.dev|gcr.io'
    The output resembles the following:
        ./code/deploy/k8s/ubuntu16-04.yaml:63: image: busybox:1.31.1-uclibc    ./code/deploy/k8s/master.yaml:26:      image: kubernetes/redis:v1
    This command looks at all YAML files in your directory and identifies theimage: line. Adjust the command as needed to work with how your manifests are stored
  2. To list images running on a cluster run the following command:
    kubectlgetall--all-namespaces-oyaml|grepimage:|grep-i-v-E'docker.pkg.dev|gcr.io'
    This command returns all objects running in the selected Kubernetes cluster and gets their image names. The output resembles the following:
        - image: nginx      image: nginx:latest        - image: nginx        - image: nginx

Run the previous commands for all GKE clusters across allGoogle Cloud projects for total coverage.

Identify pull frequency from a third-party registry

In projects that pull from third-party registries, use information about imagepull frequency to determine if you usage is near or over any rate limits thatthe third-party registry enforces.

Collect log data

Create a log sink to export data to BigQuery. A log sink includesa destination and a query that selects the log entries to export. You can createa sink by querying individual projects, or you can use a script to collect dataacross projects.

To create a sink for a single project:

  1. In the Google Cloud console, go to theLogs Explorer page:

    Go toLogs Explorer

    If you use the search bar to find this page, then select the result whose subheading isLogging.

  2. Choose a Google Cloud project.

  3. On theQuery builder tab, enter the following query:

    resource.type="k8s_pod"jsonPayload.reason="Pulling"
  4. Change history filter fromLast 1 hour toLast 7 Days.image

  5. ClickRun Query.

  6. After verifying that results show up correctly, clickActions >Create Sink.

  7. In theSink details dialog, complete the following:

    1. In theSink Name field, enterimage_pull_logs.
    2. In theSink description, enter a description of the sink.
  8. ClickNext.

  9. In theSink destination dialog, select the following values:

    1. In theSelect Sink service field, selectBigQuery dataset.
    2. In theSelect BigQuery dataset field, selectCreate a new BigQuery dataset and complete the required informationin the dialog that opens. For more information on how tocreate a BigQuery dataset, seeCreate datasets.
    3. ClickCreate dataset.
  10. ClickNext.

    In theChoose logs to include in sink section, the query matches thequery you ran in theQuery builder tab.

  11. ClickNext.

  12. Optional: Choose logs to filter out of the sink. For more information onhow to query and filter Cloud Logging data, seeLogging query language.

  13. ClickCreate Sink.

    Your log sink is created.

To create a sink for multiple projects:

  1. Open Cloud Shell.

  2. Run the following commands in Cloud Shell:

    PROJECTS="PROJECT-LIST"DESTINATION_PROJECT="DATASET-PROJECT"DATASET="DATASET-NAME"forsource_projectin$PROJECTSdogcloudlogging--project="${source_project}"sinkscreateimage_pull_logsbigquery.googleapis.com/projects/${DESTINATION_PROJECT}/datasets/${DATASET}--log-filter='resource.type="k8s_pod" jsonPayload.reason="Pulling"'done

    where

    • PROJECT-LIST is a list of Google Cloud project IDs,separated with spaces. For exampleproject1 project2 project3.
    • DATASET-PROJECT is the project where you want to store yourdataset.
    • DATASET-NAME is the name for the dataset, for exampleimage_pull_logs.

After you create a sink, it takes time for data to flow toBigQuery tables, depending on how frequently images are pulled.

Query for pull frequency

Once you have a representative sample of image pulls that your builds make,run a query for pull frequency.

  1. Go to the BigQuery console.

  2. Run the following query:

    SELECTREGEXP_EXTRACT(jsonPayload.message,r'"(.*?)"')ASimageName,COUNT(*)ASnumberOfPullsFROM`DATASET-PROJECT.DATASET-NAME.events_*`GROUPBYimageNameORDERBYnumberOfPullsDESC

    where

    • DATASET-PROJECT is the project that contains your dataset.
    • DATASET-NAME is the name of the dataset.
The following example shows output from the query. In theimageNamecolumn, you can review the pull frequency for images that aren't stored inArtifact Registry.

image

Copy images to Artifact Registry

After you have identified images from third-party registries, you are ready tocopy them to Artifact Registry. Thegcrane tool helps you withthe copying process.

  1. Create a text fileimages.txt with the names of theimages you identified. For example:

    ubuntu:18.04debian:busterhello-world:latestredis:busterjupyter/tensorflow-notebook
  2. Downloadgcrane.

    GO111MODULE=ongogetgithub.com/google/go-containerregistry/cmd/gcrane
  3. Create a script namedcopy_images.sh to copy your list of files.

    #!/bin/bashimages=$(catimages.txt)if[-z"${AR_PROJECT}"]thenechoERROR:AR_PROJECTmustbesetbeforerunningthisexit1fiforimgin${images}dogcranecp${img}LOCATION-docker.pkg.dev/${AR_PROJECT}/${img}done

    ReplaceLOCATION with the regional or multi-regionallocation of the repository.

    Make the script executable:

    chmod+xcopy_images.sh
  4. Run the script to copy the files:

    AR_PROJECT=${PROJECT}./copy_images.sh

Verify permissions

Make sure that permissions are configured correctly before you update andre-deploy your workloads.

For more information, see theaccess controldocumentation.

Update manifests to reference Artifact Registry

Update your Dockerfiles and your manifests to refer to Artifact Registryinstead of the third-party registry.

The following example shows manifest referencing a third-party registry:

apiVersion:apps/v1kind:Deploymentmetadata:name:nginx-deploymentspec:selector:matchLabels:app:nginxreplicas:2template:metadata:labels:app:nginxspec:containers:-name:nginximage:nginx:1.14.2ports:-containerPort:80

This updated version of the manifest points to an image onus-docker.pkg.dev.

apiVersion:apps/v1kind:Deploymentmetadata:name:nginx-deploymentspec:selector:matchLabels:app:nginxreplicas:2template:metadata:labels:app:nginxspec:containers:-name:nginximage:us-docker.pkg.dev/<AR_PROJECT>/nginx:1.14.2ports:-containerPort:80

For a large number of manifests, usesedor another tool that can handle updates across many text files.

Re-deploy workloads

Re-deploy workloads with your updated manifests.

Keep track of new image pulls by running the following query in theBigQuery console:

SELECT`FORMAT_TIMESTAMP("%D %R",timestamp)astimeOfImagePull,REGEXP_EXTRACT(jsonPayload.message,r'"(.*?)"')ASimageName,COUNT(*)ASnumberOfPullsFROM`image_pull_logs.events_*`GROUPBYtimeOfImagePull,imageNameORDERBYtimeOfImagePullDESC,numberOfPullsDESC

All new image pulls should be from Artifact Registry and contain the stringdocker.pkg.dev.

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2026-02-19 UTC.