72

I am trying to use kubectl run command to pull an image from private registry and run a command from that. But I don't see an option to specify image pull secret. It looks like it is not possible to pass image secret as part for run command.

Is there any alternate option to pull a container and run a command using kubectl? The command output should be seen on the console. Also once the command finishes the pod should die.

noorul
  • 1,283
  • 1
  • 8
  • 18

8 Answers8

64

You can use the overrides if you specify it right, it's an array in the end, that took me a bit to figure out, the below works on Kubernetes of at least 1.6:

--overrides='{ "spec": { "template": { "spec": { "imagePullSecrets": [{"name": "your-registry-secret"}] } } } }'

for example

kubectl run -i -t hello-world --rm --generator=run-pod/v1 \
--image=eu.gcr.io/your-registry/hello-world \
--image-pull-policy="IfNotPresent" \
--overrides='{ "spec": { "template": { "spec": { "imagePullSecrets": [{"name": "your-registry-secret"}] } } } }'
im_infamous
  • 972
  • 1
  • 17
  • 29
Elmar Weber
  • 2,683
  • 28
  • 28
  • 2
    For Windows you'll need to escape the double quotes (and remove the two single quotes). You'll have something like `--overrides="{ \"apiVersion\": \"v1\", ...}] } }"` – Andrei Damian-Fekete Jul 04 '19 at 11:54
  • 1
    This response is conceptually right but it is not working anymore as the deployment API used by `kubectl run` has moved from v1. Have a look on the [@Raman comment below](https://stackoverflow.com/questions/40288077/how-to-pass-image-pull-secret-while-using-kubectl-run-command#comment79611937_40646132) to find the right way to do it. – dbaltor Jul 27 '19 at 02:17
  • 3
    In my case, it worked with this override: `--overrides='{ "apiVersion": "apps/v1", "spec": { "template": { "spec": { "imagePullSecrets": [{"name": "your-registry-secret"}] } } } }'` – marcostvz Aug 21 '19 at 08:43
  • @marcostvz thx for comment, I've amended the answer to remove deprecated construction and added your method as well – im_infamous Nov 18 '20 at 09:55
  • 8
    In my case in Azure: `--overrides='{ "spec": { "imagePullSecrets": [{"name": "your-registry-secret"}] } }'` – Rui Martins Feb 07 '21 at 23:14
  • 3
    In my case, `overrides` seems to need to be a pod definition object rather than a deployment definition object. This means unwrapping the object twice: `--overrides='{ "apiVersion": "v1", "spec": { "imagePullSecrets": [{"name": "your-registry-secret"}] } }'` – Blieque Nov 29 '21 at 22:08
  • ugh, it's ugly :D – Somebody Aug 30 '22 at 14:11
38

You could create the docker-registry secret as described at @MarkO'Connor's link, then add it to the default ServiceAccount. It's the SA that acts on the behalf of pods, including pulling their images.

From Adding ImagePullSecrets to a service account:

$ kubectl create secret docker-registry myregistrykey --docker-username=janedoe --docker-password=●●●●●●●●●●● --docker-email=jdoe@example.com
secret "myregistrykey" created

$ kubectl get serviceaccounts default -o yaml > ./sa.yaml

$ cat sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: 2015-08-07T22:02:39Z
  name: default
  namespace: default
  resourceVersion: "243024"
  selfLink: /api/v1/namespaces/default/serviceaccounts/default
  uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6
secrets:
- name: default-token-uudge

$ vi sa.yaml
[editor session not shown]
[delete line with key "resourceVersion"]
[add lines with "imagePullSecret:"]

$ cat sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: 2015-08-07T22:02:39Z
  name: default
  namespace: default
  selfLink: /api/v1/namespaces/default/serviceaccounts/default
  uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6
secrets:
- name: default-token-uudge
imagePullSecrets:
- name: myregistrykey

$ kubectl replace serviceaccount default -f ./sa.yaml

Now, any new pods created in the current namespace will have this added to their spec:

spec:
  imagePullSecrets:
  - name: myregistrykey
mgoodness
  • 536
  • 3
  • 7
  • 28
    Simpler: `kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}'` – Raman Sep 20 '17 at 15:07
  • 1
    @Raman...this command (which is in the documentation..) does not work for me. I get => error: unable to parse "'{\"imagePullSecrets\":": yaml: found unexpected end of stream Any ideas?? – Kostas Demiris Apr 25 '18 at 14:29
  • 4
    @KostasDemiris `kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}'` should work – jitter May 08 '18 at 17:34
  • 1
    kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}' get some parsing error Error from server (BadRequest): invalid character 'i' looking for beginning of object key string (1.10 on Windows) kubectl replace serviceaccount default -f ./sa.yaml work for me – user1295211 Sep 15 '18 at 15:07
  • The provided link doesn´t work anymore. – david.perez Aug 22 '23 at 09:15
20

Usually when you need kubectl run it's because you're testing something temporary, in a namespace that already has the docker registry secret to access the private registry. So the simplest is to edit the default service account to give it the pull secret to use when a pull secret is not present (which will be the case for kubectl run):

kubectl edit serviceaccount default

The edit will show something similar to this:

apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: "2019-04-16T14:48:17Z"
  name: default
  namespace: integration-testing
  resourceVersion: "60516585"
  selfLink: /api/v1/namespaces/integration-testing/serviceaccounts/default
  uid: ab7b767d-6056-11e9-bba8-0ecf3bdac4a0
secrets:
- name: default-token-4nnk4

Just append an imagePullSecrets:

imagePullSecrets:
- name: <name-of-your-docker-registry-password-secret>

so it will look like this:

apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: "2019-04-16T14:48:17Z"
  name: default
  namespace: integration-testing
  resourceVersion: "60516585"
  selfLink: /api/v1/namespaces/integration-testing/serviceaccounts/default
  uid: ab7b767d-6056-11e9-bba8-0ecf3bdac4a0
secrets:
- name: default-token-4nnk4
imagePullSecrets:
- name: <name-of-your-docker-registry-password-secret>

Say name is YOUR_PWD_SECRET, then this secret must exist in the kubectl context's namespace:

tooluser:/host $ kubectl get secret YOUR_PWD_SECRET
NAME              TYPE                             DATA   AGE
YOUR_PWD_SECRET   kubernetes.io/dockerconfigjson   1      186d

If it doesn't exist you must create it, either from scratch or copy it from another namespace (best way to do that is answer by NicoKowe at https://stackoverflow.com/a/58235551/869951).

With a secret holding your docker registry password, the secret in the same namespace where the kubectl run will execute, and with a default service account that lists the secret as imagePullSecrets, the kubectl run will work.

Oliver
  • 27,510
  • 9
  • 72
  • 103
8

On Windows, you can do patch, but as it shows a JSON error, you have to do this trick (using PowerShell):

> $imgsec=  '{"imagePullSecrets": [{"name": "myregistrykey"}]}' | ConvertTo-Json
> kubectl patch serviceaccount default -p $imgsec

Also , if you want to update/ append imagePullSecret , then you should be using something like this :

> $imgsec=  '[{"op":"add","path":"/imagePullSecrets/-","value":{"name":"myregistrykey2"}}]' | ConvertTo-Json

> kubectl patch serviceaccount default --type='json' -p  $imgsec

.

Paras Patidar
  • 1,024
  • 11
  • 11
  • 1
    Thanks for sharing this! I've spread the word on this approach a little as I seemed to come up in a few places whilst I was searching for a solution :) – Matt Woodward Dec 15 '18 at 00:15
7

Since kubectl run now just deploys a pod, the proper override would be:

kubectl run --image=your.private.registry/nginx nginx --overrides='{ "spec": { "imagePullSecrets": [{"name": "your-registry-secret"}] } }'
marcostvz
  • 1,148
  • 11
  • 17
1

As far as I know you cannot, but you can use kubectl run nginx --image=nginx --overrides='{ "apiVersion": "v1", "spec": { ... } }' , but this is not very different from what you can do with kubectl create -f mypod.json

What I think you're after is not a Pod but a Job, for example, if you need to populate a database, you can create a container that does that, and run it as a job instead of a pod or replica set.

Kubectl run ... creates deploymentorjob` objects. Jobs finish when the pod execution terminates and you can check the logs.

Take a look here and here for the termination

  • Good idea but after running it I got "error: api.Secret is not suitable for converting to "extensions/v1beta1". So I think they have disabled this on purpose. The command was `kubectl run ovass-fetcher-$(date +%s) --image=nginx --overrides="$(kubectl get secret registrykey -o json)"` where I had previously set up a working secret: registrykey. – wassname Jun 07 '17 at 02:25
  • @wassname check my answer below with an example how it works at least on K8s 1.6 or later – Elmar Weber Nov 07 '17 at 11:20
0

Please try the following command:

kubectl run nginx--image=nginx --overrides='{"apiVersion": "apps/v1", 
"spec": {"template":{"spec":{"imagePullSecrets": [{"name": "secret-name"}]}}}}'
Nicolas Pepinster
  • 5,413
  • 2
  • 30
  • 48
Thulasya
  • 11
  • 3
0

I have reslove the problem by

kubectl run nginx--image=nginx --overrides='{"apiVersion": "apps/v1", 
"spec": {"template":{"spec":{"imagePullSecrets": [{"name": "secret-name"}]}}}}'
Adiii
  • 54,482
  • 7
  • 145
  • 148
baifuwa
  • 1
  • 1