Google Cloud Registry (GCR) with external Kubernetes

For information about how to pull from other private registries, see the following topics:

If you run Kubernetes on Google Cloud Platform (GCP), Google Cloud Registry (GCR) support should be automatic. You must still make sure, however, that your instance has the correct permissions to access your private images. For details, see Using Container Registry with Google Cloud Platform.

To connect to GCR from an environment other than GCP, you add an ImagePullSecrets field to the configuration for a Kubernetes service account. This is a type of Kubernetes secret that contains credential information.

To create this secret, Heptio recommends that you create a GCP service account and use its keys to pull from GCR. These keys are stored in a JSON key file. This approach lets you store long-lived credentials, instead of passing short-lived access tokens.

Note:A GCP service account is different from a Kubernetes service account.

You can create the file with the following script. The script creates the necessary Google Cloud Platform (GCP) service account and gives it access to the registry.

# create a GCP service account; format of account is email address
SA_EMAIL=$(gcloud iam service-accounts --format='value(email)' create k8s-gcr-auth-ro)
# create the json key file and associate it with the service account
gcloud iam service-accounts keys create k8s-gcr-auth-ro.json --iam-account=$SA_EMAIL
# get the project id
PROJECT=$(gcloud config list core/project --format='value(core.project)')
# add the IAM policy binding for the defined project and service account
gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:$SA_EMAIL --role roles/storage.objectViewer

Then create the secret and specify the file that you just created:

SECRETNAME=varSecretName

kubectl create secret docker-registry $SECRETNAME \
  --docker-server=https://gcr.io \
  --docker-username=_json_key \
  --docker-email=user@example.com \
  --docker-password="$(cat k8s-gcr-auth-ro.json)"

where the values must be as follows:

$SECRETNAMEAn arbitrary string to serve as the name of the secret
docker-serverMust be set to “https://gcr.io” (or some variant, a subdomain may be required depending on your availability zone)
docker-usernameMust be set to _json_key
docker-emailMust be any well-formed email address (not used, but required)
docker-passwordThe contents of the json key file that you created in the previous script
Note:The command above only creates the secret in the default namespace. You will need to specify -n and create a secret for each namespace that your pods are in, because pods can only reference the image pull secrets in their own namespace.

You can now add the secret to your Kubernetes configuration. You can add it to the default service account with the following command:

SECRETNAME=varSecretName

kubectl patch serviceaccount default \
  -p "{\"imagePullSecrets\": [{\"name\": \"$SECRETNAME\"}]}"

If you work with only the default service account, then all pods in the namespace pull images from the private registry. This is the case whether or not you explicitly specify the service account in the pod spec. If you work with multiple service accounts, each service account must provide the appropriate imagePullSecrets value. For more information, see the Kubernetes documentation on service accounts.

After you run kubectl patch to add your imagePullSecrets value, the YAML for the default service account looks like the following:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: default
  namespace: default
  selfLink: /api/v1/namespaces/default/serviceaccounts/default
imagePullSecrets:
  - name: your_secret_name

Or you can specify the imagePullSecrets value on individuals pods. The YAML for this approach might look like the following:

apiVersion: v1
kind: Pod
metadata:
  name: <pod_name>
spec:
  containers:
    - name: <container_name>
      image: gcr.io/<registry_name>/<image_name>:<tagname>
  imagePullSecrets:
      - name: your_secret_name

LEAVE A COMMENT