Creating image pull secret for google container registry that doesn't expire?

This is really tricky but after a lot of trail and error I think I've got it working.

  1. Go to the Google Developer Console > Api Manager > Credentials and click "Create credentials" and create a "service account key"
  2. Under "service account" select new and name the new key "gcr" (let the key type be json)
  3. Create the key and store the file on disk (from here on we assume that it was stored under ~/secret.json)
  4. Now login to GCR using Docker from command-line:

    $ docker login -e [email protected] -u _json_key -p "$(cat ~/secret.json)" https://eu.gcr.io

    This will generate an entry for "https://eu.gcr.io" in your ~/.docker/config.json file.

  5. Copy the JSON structure under "https://eu.gcr.io" into a new file called "~/docker-config.json", remove newlines! For example:

    {"https://eu.gcr.io": { "auth": "<key>","email": "[email protected]"}}

  6. Base64 encode this file:

    $ cat ~/docker-config.json | base64

  7. This will print a long base64 encoded string, copy this string and paste it into an image pull secret definition (called ~/pullsecret.yaml):

apiVersion: v1
  kind: Secret
  metadata:
    name: mykey
  data:
    .dockercfg: <paste base64 encoded string here>
  type: kubernetes.io/dockercfg
  1. Now create the secret:

    $ kubectl create -f ~/pullsecret.yaml

  2. Now you can use this pull secret from a pod, for example:
apiVersion: v1
kind: Pod
metadata: 
  name: foo
  namespace: awesomeapps
spec: 
  containers: 
    - image: "janedoe/awesomeapp:v1"
      name: foo
  imagePullSecrets: 
    - name: mykey

or add it to a service account.


It is much easier with kubectl

kubectl create secret docker-registry mydockercfg \
  --docker-server "https://eu.gcr.io" \
  --docker-username _json_key \
  --docker-email [email protected] \
  --docker-password=$(cat your_service_account.json)

One important detail after you download your_service_account.json from google is to join all the lines in the json into one row. For this you could replace cat with paste:

  --docker-password=$(paste -s your_service_account.json)

You can also grant the service account your cluster runs as access to the GCS bucket:

  eu.artifacts.{project-id}.appspot.com

This answer has a few gsutil commands to make that happen.