<p>Mostly addressed to: google-cloud-platform</p>

<p>Overall problem I am trying to solve is; to pull images from Google Container Registry from private Kubernetes.</p>

<p><strong>Update</strong> Just added heptio-contour if some one over there have come across this - as the good people at Heptio has created the script mentioned in the question further down - thanks.</p>

<p>First step is to just use the Service Account with a JSON key - as described <a href="https://cloud.google.com/container-registry/docs/advanced-authentication#json_key_file" rel="nofollow noreferrer">here</a>.<br>
But when I run:</p>

<pre><code>cat gcr-sa-key.json | docker login -u _json_key --password-stdin https://gcr.io
</code></pre>

<p>I should be able to login docker, but it fails with:</p>

<pre><code>cat gcr-sa-key.json | docker login -u _json_key --password-stdin https://gcr.io
Error response from daemon: Get https://gcr.io/v2/: unauthorized: GCR login failed. You may have invalid credentials. To login successfully, follow the steps in: https://cloud.google.com/container-registry/docs/advanced-authentication
</code></pre>

<p><strong>Note</strong>: I got the <code>gcr-sa-key.json</code> file from running <a href="http://docs.heptio.com/content/private-registries/pr-gcr.html" rel="nofollow noreferrer">this</a> - keep in mind that I am overall trying to use this from Kubernetes.</p>

<p>I expect this to be a Google issue, but/and if I do run as described in the doc from Heptio I get:</p>

<pre><code>Events:
  Type     Reason          Age                From                                        Message
  ----     ------          ----               ----                                        -------
  Normal   Scheduled       50s                default-scheduler                           Successfully assigned default/&lt;image-name&gt;-deployment-v1-844568c768-5b2rt to my-cluster-digitalocean-1-7781
  Normal   Pulling         37s (x2 over 48s)  kubelet, my-cluster-digitalocean-1-7781  pulling image "gcr.io/&lt;project-name&gt;&lt;image-name&gt;:v1"
  Warning  Failed          37s (x2 over 48s)  kubelet, my-cluster-digitalocean-1-7781  Failed to pull image "gcr.io/&lt;project-name&gt;/&lt;image-name&gt;:v1": rpc error: code = Unknown desc = Error response from daemon: pull access denied for gcr.io/&lt;project-name&gt;/&lt;image-name&gt;, repository does not exist or may require 'docker login'
  Warning  Failed          37s (x2 over 48s)  kubelet, my-cluster-digitalocean-1-7781  Error: ErrImagePull
  Normal   SandboxChanged  31s (x7 over 47s)  kubelet, my-cluster-digitalocean-1-7781  Pod sandbox changed, it will be killed and re-created.
  Normal   BackOff         29s (x6 over 45s)  kubelet, my-cluster-digitalocean-1-7781  Back-off pulling image "gcr.io/&lt;project-name&gt;/&lt;image-name&gt;:v1"
  Warning  Failed          29s (x6 over 45s)  kubelet, my-cluster-digitalocean-1-7781  Error: ImagePullBackOff
</code></pre>

<p>Just info. that might be related, I saw <a href="https://github.com/GoogleContainerTools/skaffold/issues/336" rel="nofollow noreferrer">this</a> issue on github.</p>

<p>You are missing the most important bit, you need to somehow grant a Kubernetes' default service account (the simplest approach) the permission to access your private container registry while pulling images. You do this in three steps:</p>

<ol>
<li>Create and grant your GCP service account appropriate role in AIM (at least Storage Object Viewer) as explain <a href="https://cloud.google.com/container-registry/docs/access-control#granting_users_and_other_projects_access_to_a_registry" rel="nofollow noreferrer">here</a> in official doc</li>
<li>Create kubernetes secret (of 'docker-registry' type) using downloaded JSON key for your GCP service account</li>
</ol>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code>kubectl create secret docker-registry my-private-gcr-readonly \
--docker-server=gcr.io \
--docker-username=_json_key \
--docker-password="$(cat /usr/local/home/demo/414141.json)" \
--docker-email=some@project-id.iam.gserviceaccount.com</code></pre>
</div>
</div>
</p>

<ol start="3">
<li>Grant your default Kubernetes service account (your PODs are running under its security context by default) the right to pull Image from private GCR repo. This is done indirectly, by assigning it the secret for imagePull operation:  </li>
</ol>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code>kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "my-private-gcr-readonly"}]}'</code></pre>
</div>
</div>
</p>

<p>That's it !</p>

<p>PS.</p>

<p>You can also check <a href="https://container-solutions.com/using-google-container-registry-with-kubernetes/" rel="nofollow noreferrer">this</a> tutorial, that explains both ways of accessing Google Container Registry from within Kubernetes cluster (using JSON Key or Access token)</p>
