47

I'm writing a shell script which needs to login into the pod and execute a series of commands in a kubernetes pod.

Below is my sample_script.sh:

kubectl exec octavia-api-worker-pod-test -c octavia-api bash
unset http_proxy https_proxy
mv /usr/local/etc/octavia/octavia.conf /usr/local/etc/octavia/octavia.conf-orig
/usr/local/bin/octavia-db-manage --config-file /usr/local/etc/octavia/octavia.conf upgrade head

After running this script, I'm not getting any output. Any help will be greatly appreciated

Bernardo Ramos
  • 4,048
  • 30
  • 28
ahmed meraj
  • 844
  • 1
  • 9
  • 15

4 Answers4

100

Are you running all these commands as a single line command? First of all, there's no ; or && between those commands. So if you paste it as a multi-line script to your terminal, likely it will get executed locally.

Second, to tell bash to execute something, you need: bash -c "command".

Try running this:

$ kubectl exec POD_NAME -- bash -c "date && echo 1"

Wed Apr 19 19:29:25 UTC 2017
1

You can make it multiline like this:

$ kubectl exec POD_NAME -- bash -c "date && \
      echo 1 && \
      echo 2"
ahmet alp balkan
  • 42,679
  • 38
  • 138
  • 214
  • 1
    What does '--' do in this case? Why is it needed? – Zhinkk Jul 26 '18 at 19:41
  • 4
    The double dash symbol "--" is used to separate the arguments you want to pass to the command from the kubectl arguments – 0xMH Oct 17 '18 at 17:54
  • Thanks for your answer. I haven't seen such separator for docker. Does it exist there as well ? – cafebabe1991 Jul 17 '20 at 14:03
  • 1
    @cafebabe1991 No. In `docker run` command, any positional argument that comes after the `[image]` argument is considered to be `CMD` arguments. And you can pass an `--entrypoint=[program]` option before the `[image]`. e.g. `docker run --rm -it --entrypoint=sleep busybox 9999` runs `sleep 9999` – ahmet alp balkan Jul 17 '20 at 22:38
8

The following should work

kubectl -it exec podname -- bash -c "ls && ls"

bin   dev   etc   home  proc  root  run   sys   tmp   usr   var bin  
dev   etc   home  proc  root  run   sys   tmp   usr   var

If above command doesn't work then try too replace bash with one of the following /bin/bash, sh or /bin/sh

Eldad Assis
  • 10,464
  • 11
  • 52
  • 78
RB7
  • 435
  • 7
  • 9
4

-t can solve your task

For example, I run here few cmd:

kubectl get pods |grep nginx|cut -f1 -d\  |\
while read pod; \
 do echo "$pod writing:";\
  kubectl exec -t $pod -- bash -c \
   "dd if=/dev/zero of=/feeds/test.bin bs=260K count=4 2>&1|\
    grep copi |cut -d, -f4; \
    a=$SECONDS; echo -ne 'reading:'; cat /feeds/test.bin >/dev/null ; \
    let a=SECONDS-a ; \
    echo $a sec"
done

p.s. your example will be:

kubectl exec -t octavia-api-worker-pod-test -c octavia-api -- bash -c "unset http_proxy https_proxy ; mv /usr/local/etc/octavia/octavia.conf /usr/local/etc/octavia/octavia.conf-orig ; /usr/local/bin/octavia-db-manage --config-file /usr/local/etc/octavia/octavia.conf ; upgrade ; head"
  • This is not a good idea. -t has certain output characters like \r you should probably not use in your scripts. https://stackoverflow.com/questions/55034214/why-do-docker-run-t-outputs-include-r-in-the-command-output – ahmet alp balkan Mar 11 '19 at 15:09
4

Posting here because google search still brings you to this post...

I'd like to throw out using a HEREDOC as an additional possibility.

kubectl exec -i --tty-false PODNAME -- bash << EOF
echo "insert all your commands here."
echo "this subprocess will even pickup any variables you have in"
echo "the shell script that is calling this"
EOF
JuanD
  • 391
  • 1
  • 6
  • 13