GKE docker image pull secret πŸ”

As of this writing Google Kubernetes Engine does not offer an auto-magic integration with Google Cloud Repositories.

We're left to our own devices but you're in luck! In two steps you'll be up and running..

Step 1: Create service account

resource "google_service_account" "gcr" {

    account_id   = "gke-image-pull"
    display_name = "gke-image-pull"

}
service-account.tf

resource "google_storage_bucket_iam_member" "gcr" {

    bucket = "artifacts.myproject-1234.appspot.com"
    member = "serviceAccount:${ google_service_account.gcr.email }"
    
    #
    # The important part:
    #
    role   = "roles/storage.objectViewer"

}
permissions.tf

resource "google_service_account_key" "gcr" {

    service_account_id = google_service_account.gcr.name

}
key.tf

resource "local_file" "gcr" {

    filename = "${ google_service_account.gcr.email }.json"
    content  = base64decode(google_service_account_key.gcr.private_key)

}
save-locally.tf

Step 2: Create the secret βž•

Create a new Secret that contains the authentication information required by the docker daemon (aka docker config json).

You have two options:

Option #1: Auto-magic secret creation with terraform 🀩

Create a file called image-secret.tf and deploy the following resource:

resource "kubernetes_secret" "gcr" {

    type = "kubernetes.io/dockerconfigjson"

    metadata {

        name = "gcr-image-pull"
        namespace = "default"

    }

    data = {

        ".dockerconfigjson" = jsonencode({

            auths = {

                "gcr.io" = {

                    username = "_json_key"
                    password = base64decode(google_service_account_key.myaccount.private_key)
                    email = "noreply@invalid.tld"
                    auth = base64encode("_json_key:${ base64decode(google_service_account_key.myaccount.private_key) }")

                }

            }

        })

    }

}
image-secret.tf

Option #2: Manually create the secret 😬

Use this if you're in a bind or want to test things out.

Please don't use this in a production environment given idempotency requirements of Infrastructure-as-Code.
kubectl create secret docker-registry gcr \
	--docker-server=gcr.io \
    --docker-username=_json_key \
    --docker-password="$(cat google-service-account-key.json)" \
    --docker-email=matthew@matthewdavis.io          

Now patch the default service account (or the service account your pod(s) are currently using):

kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "gcr"}]}'

Test the contents of your secret:

kg secret gcr-image-pull -o jsonpath={.data}
echo "base64 output from above" | base64 -d

Step 2: Employ imagePullSecrets πŸ—½

apiVersion: v1
kind: Pod
metadata:
  name: uses-private-registry
spec:
  containers:
  - name: private-reg-container
    image: gcr.io/someproject1234/myimage:v.1.2.3
  imagePullSecrets:
  - name: gcr

See also

Pull an Image from a Private Registry
This page shows how to create a Pod that uses a Secret to pull an image from a private container image registry or repository.πŸ›‡ This item links to a third party project or product that is not part of Kubernetes itself. More information Before you begin You need to have a Kubernetes cluster, and…