如何使用Kubernetes在一个yaml文件中设置多个命令?

时间:2015-11-24 06:53:11

标签: yaml kubernetes

在这个官方文档中,它可以在yaml配置文件中运行命令:

  

http://kubernetes.io/v1.1/docs/user-guide/configuring-containers.html

<select name="environmentDetails" id="environmentDetails"><option>FGR - Production</option><option>RFGGDDF - Production</option><option>ECO1 - Development</option><option>MindSpace - Development</option><option>IBM1 - Test</option><option>CDF - Test</option></select>

如果我想运行多个命令,怎么办?

10 个答案:

答案 0 :(得分:79)

command: ["/bin/sh","-c"]
args: ["command one; command two && command three"]

说明: command ["/bin/sh", "-c"]说“运行shell,并执行以下说明”。然后将args作为命令传递给shell。在shell脚本中,分号分隔命令,如果第一个成功,&&有条件地运行以下命令。在上面的示例中,它始终运行command one后跟command two,只有command three成功才会运行command two

备选方案:在许多情况下,您要运行的某些命令可能是设置要运行的最终命令。在这种情况下,构建自己的Dockerfile是可行的方法。请特别查看RUN指令。

答案 1 :(得分:23)

我倾向于多行化args,这是最简单易读的。此外,可以在不影响图像的情况下更改脚本,只需重新启动pod即可。例如,对于mysql转储,容器规范可能是这样的:

containers:
  - name: mysqldump
    image: mysql
    command: ["/bin/sh", "-c"]
    args:
      - echo starting;
        ls -la /backups;
        mysqldump --host=... -r /backups/file.sql db_name;
        ls -la /backups;
        echo done;
    volumeMounts:
      - ...

这样做的原因是yaml实际上连接了&#34; - &#34;之后的所有行。成为一个,并且sh运行一个长串&#34; echo开始; ls ...;回声完成;&#34;。

答案 2 :(得分:22)

如果您愿意使用Volume和ConfigMap,可以mount ConfigMap data作为脚本,然后运行该脚本:

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-configmap
data:
  entrypoint.sh: |-
    #!/bin/bash
    echo "Do this"

    echo "Do that"
---
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: "ubuntu:14.04"
    command:
    - /bin/entrypoint.sh
    volumeMounts:
    - name: configmap-volume
      mountPath: /bin/entrypoint.sh
      readOnly: true
      subPath: entrypoint.sh
  volumes:
  - name: configmap-volume
    configMap:
      defaultMode: 0700
      name: my-configmap

这会稍微清理您的pod规范,并允许更复杂的脚本。

$ kubectl logs my-pod
Do this
Do that

答案 3 :(得分:4)

恕我直言,最好的选择是使用YAML的本机block scalars。在这种情况下,特别是 folded 样式块。

通过调用sh -c,您可以将参数作为命令传递给容器,但是如果要用换行符优雅地将它们分开,则需要使用折叠样式块,因此YAML将知道将换行符转换为空格,从而有效地将命令串联起来。

完整的示例:

apiVersion: v1
kind: Pod
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  containers:
  - name: busy
    image: busybox:1.28
    command: ["/bin/sh", "-c"]
    args:
    - >
      command_1 &&
      command_2 &&
      ... 
      command_n

答案 4 :(得分:2)

如果要避免将所有命令与;&&合并为一个命令,则还可以使用heredoc获取真正的多行脚本:

command: 
 - sh
 - "-c"
 - |
   /bin/bash <<'EOF'

   # Normal script content possible here
   echo "Hello world"
   ls -l
   exit 123

   EOF

这对于运行现有的bash脚本很方便,但缺点是需要一个内部和一个外壳实例来设置heredoc。

答案 5 :(得分:2)

我不确定该问题是否仍然有效,但由于我没有在上述答案中找到解决方案,因此决定将其写下来。

我使用以下方法:

readinessProbe:
  exec:
    command:
    - sh
    - -c
    - |
      command1
      command2 && command3

我知道我的示例与readinessProbe,livenessProbe等有关,但是怀疑容器命令也存在这种情况。这提供了灵活性,因为它反映了用Bash编写的标准脚本。

答案 6 :(得分:0)

在这里,您可以使用kubernetes在一个YAML文件中传递多个命令和参数:

public function bind($param, $value, $type = null){
    if(is_null($type)){
        switch(true){
            case is_int($value):
                $type = PDO::PARAM_INT;
                break;
            case is_bool($value):
                $type = PDO::PARAM_BOOL;
                break;
            case is_null($value):
                $type = PDO::PARAM_NULL;
                break;
                default:
                $type = PDO::PARAM_STR;
        }
    }
    $this->stmt->bindValue($param, $value, $type);
}
yaml文件中的

完整的容器块:

# Write your commands here
command: ["/bin/sh", "-c"]
# Write your multiple arguments in args
args: ["/usr/local/bin/php /var/www/test.php & /usr/local/bin/php /var/www/vendor/api.php"]

答案 7 :(得分:0)

只需带来另一个可能的选择,便可以使用秘密,因为它们以卷的形式显示在豆荚中:

秘密示例:

apiVersion: v1
kind: Secret 
metadata:
  name: secret-script
type: Opaque
data:
  script_text: <<your script in b64>>

山药提取物

....
containers:
    - name: container-name
      image: image-name
      command: ["/bin/bash", "/your_script.sh"]
      volumeMounts:
        - name: vsecret-script
          mountPath: /your_script.sh
          subPath: script_text
....
  volumes:
    - name: vsecret-script
      secret:
        secretName: secret-script

我知道许多人会争辩说这不是必须使用的秘密,但这是一种选择。

答案 8 :(得分:0)

这是我的成功跑步

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

答案 9 :(得分:0)

这是运行多行命令的另一种方式。

apiVersion: batch/v1
kind: Job
metadata:
  name: multiline
spec:
  template:
    spec:
      containers:
      - command:
        - /bin/bash
        - -exc
        - |
          set +x
          echo "running below scripts"
          if [[ -f "if-condition.sh" ]]; then
            echo "Running if success"
          else
            echo "Running if failed"
          fi
        name: ubuntu
        image: ubuntu
      restartPolicy: Never
  backoffLimit: 1