Today I Learned: Pull Docker Image from GCR (Google Container Registry) in any non-GCP Kubernetes…

Written by imantumorang | Published 2019/06/25
Tech Story Tags: kubernetes | docker | software-development | google-cloud-platform

TLDR A simple guide to help you use GCR as your Container Registry in any non-GCP Kubernetes Cluster. The issue is about authentication to GCR when pulling the private images. The guide explains how to a pull Docker Image from GCR in any other non-Google Cloud Platform Kubernets cluster using GCR. GCR is a bit cheap compared to DockerHub for the private registry. With this method, every pod that will be deployed will use the secret when pulling images.via the TL;DR App

How to a pull Docker Image from GCR in any non-GCP Kubernetes cluster

A simple guide to help you use GCR as your Container Registry in any non-GCP Kubernetes Cluster

I have many side projects, but I deploy it in my Kubernetes Cluster in GCP(Google Cloud Platform). But after DigitalOcean(DO) released their Kubernetes features, I want to move all my side projects that exist in GCP to DO. The reasons for this migrations is because the GCP is too expensive and overkill just for simple side projects that not really have any production users.
But, I just migrate the Kubernetes clusters and Database. And I still used a few services from GCP, for example, Google services like GCR(Google Container Registry) for my container registry, because GCR is a bit cheap compared to DockerHub for the private registry.
And when migrating the Kubernetes Clusters, I found an issue. The issue is about Authentication to GCR when pulling the private Images. This is how the pods status when I get the pods.
$ kubectl get pods<br>NAME                    READY   STATUS         RESTARTS   AGE<br>august-f7fc98c5-x4chl   0/1     ErrImagePull   0          88s
After looking for the logs, the issue happens because I need to define an access token when pulling the private images. So here I will explain all my steps to resolve this issue.
Steps 1: Create Credentials for GCRGo to the GCP Console. Select “API & Services” > “Credentials”Select “Create credentials” > “Services Account Key” > “Create New Services Account”.And then, fill the service account name, and for the Role, select the ViewerAnd click Create. After we create, the credential will automatically be downloaded in a JSON file. It will be looks like this.
So now, we already have credentials that able to pull private images from GCR.
Steps 2: Add a Kubernetes Secret in Kubernetes ClusterAnd the next step is, we will create a Kubernetes secret in our Kubernetes cluster.
$ kubectl create secret docker-registry gcr-json-key \<br>  --docker-server=asia.gcr.io \<br>  --docker-username=_json_key \<br>  --docker-password="$(cat ~/json-key-file-from-gcp.json)" \<br>  --docker-email=any@valid.email
Run the command above and input based on your needs. For example: docker-server: asia.gcr.io (I use the Asia server). And fill the email with your registered email in GCP and so on.If you got this error below, it happens because you already have a secret with named gcr-json-key. You could delete the secret and re-create again, or just put another name when creating the secret.
$ Error from server (AlreadyExists): secrets "gcr-json-key" already exists
To ensure the secret is already created, just get the secret; it should exist with the name gcr-json-key.
$ kubectl get secret<br>NAME         TYPE                                  DATA   AGE<br>gcr-json-key kubernetes.io/dockerconfigjson        1      6s
Steps 3: Using the Secret for Deployment
There are 2 ways how do we can use the created secret from previous steps. They are
Add the secret into ImagePullSecrets in default service account in a Kubernetes’s namespace. With this method, every pod that will be deployed will use the secret when pulling the images.The other way is, add the secret directly to deployment configuration to each pod who needs it.
Steps 3.a: Add the Secret to “ImagePullSecrets” in the Default Service Account.
The first way is with adding the secret in the default service account. To do this, we can directly copy this command below.
$ kubectl patch serviceaccount default \<br>-p '{"imagePullSecrets": [{"name": "gcr-json-key"}]}'
With that command, our Kubernetes cluster should already able to pull Image from GCR.
$ kubectl describe pod pod_name<br>....<br>Normal  Pulling    16s   kubelet, default-staging-oro2  Pulling image "asia.gcr.io/personal-project/august:latest"
Normal  Pulled     12s   kubelet, default-staging-oro2  Successfully pulled image "asia.gcr.io/personal-project/august:latest"
If somehow still error, try to delete the pod and wait for the pod to be re-deployed again.
Steps 3.b: Add the Secret to Each Pods Deployment Configuration
And for this step, we need to update our deployment file. And we need to add the secret directly to the deployment file. And this method only works for each pod that has the secret included.
Looks for the property: imagePullSecrets. We must add the secret directly in our deployment file.
And for my case, I choose the first method, the reasons is because my default container registry is GCR. So if in the future I have a different registry, I will just add in the deployment file directly to each pod who need it.
So, that’s what I learned today. Maybe it’s only for GCR, but I think the concept is still the same for other Container Registry.

Written by imantumorang | Software Engineer
Published by HackerNoon on 2019/06/25