Google Container Registry and Portainer

Daz Wilkin
Google Cloud - Community
4 min readMar 8, 2018

**2018–03–08 Update: A Google Engineer provided a better solution to this problem. Rather than use a short-lived token as I show below, he suggested the more elegant solution of using a Service Account’s credentials. This requires slightly more work but is documented by Google (link) and works; I just confirmed it. I recommend that you follow this path (Service Account | JSON key) rather than the access-token that I describe below. If you would like complete instructions, please scroll to the end of this post and “Using a Service Account”.

I blogged recently about Google Container Registry (GCR) and explained (from Google’s documentation) one way that you can easily configure Docker’s CLI to access GCR (gcr.io) instead of docker.io.

Well, I really like Portainer as a way to manage my local Docker images, containers, networks etc. Check it out for yourself:

docker run \
--detach \
--publish=9000:9000 \
--volume=/var/run/docker.sock:/var/run/docker.sock \
--volume=portainer_data:/data \
portainer/portainer

and then http://localhost:9000

It’s a really neat tool:

Portainer

And, I got to thinking, I should be able to access GCR through Portainer.

And, you can:

Portainer configured to use GCR

First, grab an access-token for your currently authenticated User account:

gcloud auth application-default print-access-token

The result will begin ya29.

Then, in the Poirtainer UI, create a new, custom registry:

Portainer: Custom Registry

Name the registry, perhaps after your GCP Project ID, the registry URL will be of the form gcr.io/[[YOUR-PROJECT-ID]] and slide the authentication slider. For the username, you can use the placeholder oauth2accesstoken and for the password, copy in the value of the access-token including the ya29.

Like so:

Portainer: GCR Configuration

Then click “Add registry”.

All being well, the GCR registry should now be listed:

Portainer: Registries including GCR

You may add as many as you need.

You may now pull images directly from your GCR repositories using Portainer:

Pull images from GCR repos

And/or create containers directly from GCR repositories:

Create containers directly from GCR repos

Conclusion

Portainer is a useful tool. Portainer combined with Google Container Registry is even more useful.

Using a Service Account

A Google Engineer confirmed a more elegant solution to this problem using a Service Account (JSON) key rather than a short-lived access-token.

Assuming a project called ${PROJECT} and a GCR Repository named gcr.io/${PROJECT}:

  1. Create a Service Account (called portainer) exclusively for use by Portainer for this repo:
ROBOT="portainer"gcloud iam service-accounts create ${ROBOT} \
--display-name=${ROBOT} \
--project=${PROJECT}

2. Generate a JSON key for this Service Account called portainer.key.json:

gcloud iam service-accounts keys create ./${ROBOT}.key.json \
--iam-account=${ROBOT}@${PROJECT}.iam.gserviceaccount.com \
--project=${PROJECT}

3. Grant the Service Account “objectViewer” (can read) permission to the Google Cloud Storage (GCS) bucket that backs the GCR repository. This is documented here.

gsutil iam ch serviceAccount:${ROBOT}@${PROJECT}.iam.gserviceaccount.com:objectViewer gs://artifacts.${PROJECT}.appspot.com

You can confirm this change (and if you’d prefer, you could make this change) using the GCS Browser:

https://console.cloud.google.com/storage/browser?project=${PROJECT}

GCS Browser: “Storage Object Viewer”

NB The “Storage Object Viewer” member is our Service Account.

4. Create a “custom registry” in Portainer:

  • Name: gcr.io/${PROJECT}
  • Registry URL: gcr.io/${PROJECT}
  • Username: _json_key
  • Password -- copy and paste the contents of ${ROBOT}.key.json here
  • Click add registry
Portainer “custom registry”

Use the registry as you wish.

--

--