75

I want send multiple entrypoint commands to a Docker container in the command tag of kubernetes config file.

apiVersion: v1
kind: Pod
metadata:
  name: hello-world
spec:  # specification of the pod’s contents
  restartPolicy: Never
  containers:
  - name: hello
    image: "ubuntu:14.04"
    command: ["command1 arg1 arg2 && command2 arg3 && command3 arg 4"]

But it seems like it does not work. What is the correct format of sending multiple commands in the command tag?

Michael Hausenblas
  • 13,162
  • 4
  • 52
  • 66
Dimuthu
  • 7,946
  • 6
  • 22
  • 37
  • 6
    Possible duplicate of [How to set multiple commands in one yaml file with Kubernetes?](http://stackoverflow.com/questions/33887194/how-to-set-multiple-commands-in-one-yaml-file-with-kubernetes) – Tim Allclair Nov 30 '15 at 19:13

6 Answers6

96

There can only be a single entrypoint in a container... if you want to run multiple commands like that, make bash be the entry point, and make all the other commands be an argument for bash to run:

command: ["/bin/bash","-c","touch /foo && echo 'here' && ls /"]

Jordan Liggitt
  • 16,933
  • 2
  • 56
  • 44
  • What is the logic behind this one? Can't figure that out myself. – dmigo Oct 30 '19 at 22:20
  • @dmigo you can see here the Bash documentation for operators available (‘;’, ‘&’, ‘&&’, ‘||’) to create "lists of commands" https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Lists – diegoubi Jun 25 '20 at 23:05
73

Jordan's answer is correct.

But to improve readability I would prefer:

apiVersion: v1
kind: Pod
metadata:
  name: hello-world
spec:  # specification of the pod’s contents
  restartPolicy: Never
  containers:
  - name: hello
    image: "ubuntu:14.04"
    command: ["/bin/sh"]
    args:
      - -c
      - >-
          command1 arg1 arg2 &&
          command2 arg3 &&
          command3 arg4

Read this to understand YAML block scalar (The above >- format).

Victor Wong
  • 3,457
  • 1
  • 18
  • 31
28

use this command

command: ["/bin/sh","-c"]
args: ["command one; command two && command three"]
brian
  • 289
  • 3
  • 3
  • 1
    It's not really great because `args` is the k8s equivalent from `cmd` in dockerfile. And `command` is the k8s equivalent of `entrypoint`. https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell – Julio.G Jan 02 '21 at 20:40
  • @Julio.G I failed to grasp why exactly it's not ideal based on your comment. Could you please elaborate a bit more? – Webber Nov 14 '21 at 16:41
  • @Webber My past me should have precised what he was thinking. I think the younger me said that because it would be better to include `-c` in the `args` list instead of command . – Julio.G Nov 14 '21 at 18:12
  • @Webber that way -> https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#run-a-command-in-a-shell – Julio.G Nov 14 '21 at 18:12
8

You could simply list the commands as you would normally deal with yaml arrays/lists. Take a look at this question on yaml array syntax.

Below is an example of how to pass argument lists to command. Please note the semicolon at the end of commands , otherwise you'll get an error.

  containers:
  - name: my-container
    image: my-image:latest
    imagePullPolicy: Always
    ports:
    - containerPort: 80
    command: [ "/bin/bash", "-c" ]
    args:
     - 
        echo "check if my service is running and run commands";
        while true; do
            service my-service status > /dev/null || service my-service start;
            if condition; then
                    echo "run commands";
            else
                    echo "run another command";
            fi;
        done
        echo "command completed, proceed ....";
Zstack
  • 4,046
  • 1
  • 19
  • 22
3

Another example with multiple bash commands for busybox image. This will run continuously with a while loop otherwise generally busybox images with simple scripts complete the task and the pod will get shut down after that. This yaml will run the pod continuously.

apiVersion: v1
kind: Pod
metadata:
labels:
  run: busybox
  name: busybox
spec:
  containers:
  - command:
    - /bin/sh
    - -c
    - |
      echo "running below scripts"
      i=0; 
      while true; 
      do 
        echo "$i: $(date)"; 
        i=$((i+1)); 
        sleep 1; 
      done
  name: busybox
  image: busybox
DanielM
  • 3,598
  • 5
  • 37
  • 53
0

Expanding on the correct answer from Jordon

command: ["/bin/bash","-c","touch /foo && echo 'here' && ls /"]

Docker wants a single entrypoint in a container and this entrypoint should start one foreground process. This is why we need to use /bin/bash -c.

/bin/bash -c here will start one new process for a new shell and execute rest of the commands. This way container runtime can watch the single process and report if the container finishes gracefully.

ns15
  • 5,604
  • 47
  • 51