The difference between using command&args to execute shell commands and mounting shell scripts and executing them in kubernetes

Viewed 36

I want to use k8s job to perform some scheduled tasks, as follows:

containers:
    - name: container-rgs4wl
      image: 'alpine-curl:3.16.0'
      command:
        - |-
          for i in `cat domains`
          do
              http_status=`curl -I -m 10 -o /dev/null -s -w %{http_code} $i`
              curl -X POST -H 'Content-type: application/json' --data  "{\"text\":\"$i check http status  ${http_status}\"}" ${SLACK_WEBHOOK_URL}
          done

After completion, it will prompt me the following error:

Error: failed to start container "container-rgs4wl": Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "for i in `cat domains`;\ndo\n http_status=`curl -I -m 10 -o /dev/null -s -w %{http_code} $i`\n curl -X POST -H 'Content-type: application/json' --data \"{\\\"text\\\":\\\"$i check http status ${http_status}\\\"}\" ${SLACK_WEBHOOK_URL}\ndone": stat for i in `cat domains`; do http_status=`curl -I -m 10 -o /dev/null -s -w %{http_code} $i` curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$i check http status ${http_status}\"}" ${SLACK_WEBHOOK_URL} done: no such file or directory: unknown

When I specify command in /bin/bash -c:

containers:
    - name: container-ixi4bh
      image: 'harbor.weex.tech/public/alpine-curl:3.16.0'
      command:
        - /bin/sh
        - '-c'
        - |
          for i in `cat domains` 
          do
              http_status=`curl -I -m 10 -o /dev/null -s -w %{http_code} $i`
              curl -X POST -H 'Content-type: application/json' --data  "{\"text\":\"$i check http status  ${http_status}\"}" ${SLACK_WEBHOOK_URL}
          done

It prompts the following in the log:

 /bin/sh: syntax error: unexpected word (expecting "do")

When I use the docker run command to execute in a locally started container it works fine.

$ docker run -ti --rm alpine-curl:3.16.0 sh
/ # for i in `cat domains`
>           do
>               http_status=`curl -I -m 10 -o /dev/null -s -w %{http_code} $i`
>               curl -X POST -H 'Content-type: application/json' --data  "{\"text\":\"$i check http status  ${http_st
atus}\"}" ${SLACK_WEBHOOK_URL}
>           done
okokokokokokok/ # 

ok means normal return.


well...well...well...Maybe it's an image problem, I replaced it with centos:centos7:

containers:
        - name: container-x8ba1n
          image: 'centos:centos7'
          command:
            - /bin/bash
            - '-c'
            - |
              for i in `cat domains` 
              do
                  http_status=`curl -I -m 10 -o /dev/null -s -w %{http_code} $i`
                  curl -X POST -H 'Content-type: application/json' --data  "{\"text\":\"$i check http status  ${http_status}\"}" ${SLACK_WEBHOOK_URL}
              done

There are still exceptions, as follows:

 /bin/bash: -c: line 1: syntax error near unexpected token `http_status=`curl -I -m 10 -o /dev/null -s -w %{http_code} $i`'
 /bin/bash: -c: line 1: `    http_status=`curl -I -m 10 -o /dev/null -s -w %{http_code} $i`'

Hey...I really don't know the reason, but I finally wrote a shell script and mounted it into the container for execution, this is ok.

          containers:
            - name: container-u37d3w
              image: 'centos:centos7'
              command:
                - /bin/bash
              args:
                - /check.sh
              env:
                - name: SLACK_WEBHOOK_URL
                  value: >-
                    https://hooks.slack.com/services/...
              resources: {}
              volumeMounts:
                - name: volume-m3lym7
                  readOnly: true
                  mountPath: /domains
                  subPath: domains
                - name: volume-ho9ctd
                  readOnly: true
                  mountPath: /check.sh
                  subPath: check.sh

I would like to know what is the difference between using command or args and executing a shell script.

1 Answers

You can consider it like, command is like the command we run in Linux, for example, printenv, grep, echo and you pass the argument into it that's args.

like echo(command) "hello"(args)

So if you want to run the command in shell you can try something like

command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]

Or else you can try something like

  image: k8s.gcr.io/busybox
  command: [ "sh", "-c"]
  args:
  - while true; do
      echo -en '\n';
      printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;
      sleep 10;
    done;
  env:

You can read more about : https://kubernetes.io/docs/tasks/inject-data-application/_print/

Related