Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically use secret when pulling from private registry

Is it possible to globally (or at least per namespace), configure kubernetes to always use an image pull secret when connecting to a private repo? There are two use cases:

  1. when a user specifies a container in our private registry in a deployment
  2. when a user points a Helm chart at our private repo (and so we have no control over the image pull secret tag).

I know it is possible to do this on a service account basis but without writing a controller to add this to every new service account created it would get a bit of a mess.

Is there are way to set this globally so if kube tries to pull from registry X it uses secret Y?

Thanks

like image 760
apr_1985 Avatar asked Mar 18 '19 13:03

apr_1985


People also ask

What is imagePullSecret?

An imagePullSecrets is an authorization token, also known as a secret, that stores Docker credentials that are used for accessing a registry. Two formats are available for you to create an application from the management console.

Which type of Kubernetes secret should you use to pass credentials for an image repository so that Kubelet can pull private images on behalf of your pods?

The imagePullSecrets field for a Pod is a list of references to Secrets in the same namespace as the Pod. You can use an imagePullSecrets to pass image registry access credentials to the kubelet. The kubelet uses this information to pull a private image on behalf of your Pod.


1 Answers

As far as I know, usually the default serviceAccount is responsible for pulling the images. To easily add imagePullSecrets to a serviceAccount you can use the patch command:

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

It's possible to use kubectl patch in a script that inserts imagePullSecrets on serviceAccounts across all namespaces.

If it´s too complicated to manage multiple namespaces you can have look at kubernetes-replicator, which syncs resources between namespaces.

Solution 2:
This section of the doc explains how you can set the private registry on a node basis:

Here are the recommended steps to configuring your nodes to use a private registry. In this example, run these on your desktop/laptop:

  1. Run docker login [server] for each set of credentials you want to use. This updates $HOME/.docker/config.json.
  2. View $HOME/.docker/config.json in an editor to ensure it contains just the credentials you want to use.
  3. Get a list of your nodes, for example:

    • If you want the names:
      nodes=$(kubectl get nodes -o jsonpath='{range.items[*].metadata}{.name} {end}')

    • If you want to get the IPs:
      nodes=$(kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?(@.type=="ExternalIP")]}{.address} {end}')

  4. Copy your local .docker/config.json to one of the search paths list above. for example:

    for n in $nodes; do scp ~/.docker/config.json root@$n:/var/lib/kubelet/config.json; done

Solution 3:
A (very dirty!) way I discovered to not need to set up an imagePullSecret on a deployment / serviceAccount basis is to:

  1. Set ImagePullPolicy: IfNotPresent
  2. Pulling the image in each node
    2.1. manually using docker pull myrepo/image:tag.
    2.2. using a script or a tool like docker-puller to automate that process.

Well, I think I don't need to explain how ugly is that.

PS: If it helps, I found an issue on kubernetes/kops about the feature of creating a global configuration for private registry.

like image 118
victortv Avatar answered Sep 18 '22 08:09

victortv