Google Container Registry and Portainer
**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:
And, I got to thinking, I should be able to access GCR through Portainer.
And, you can:
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:
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:
Then click “Add registry”.
All being well, the GCR registry should now be listed:
You may add as many as you need.
You may now pull images directly from your GCR repositories using Portainer:
And/or create containers directly from GCR repositories:
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}
:
- 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}
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
Use the registry as you wish.