【问题标题】:How to execute multiple commands in a Pod's container with client-go?如何使用 client-go 在 Pod 的容器中执行多个命令?
【发布时间】:2020-06-29 11:34:58
【问题描述】:

所以我尝试使用 client-go 在 Pod 的容器上执行一个链,即多个命令,它似乎只适用于像 ls 这样的一些命令。

这是我尝试过的:

    req := client.CoreV1().RESTClient().Post().Resource("pods").Name(pod.Name).Namespace(pod.ObjectMeta.Namespace).SubResource("exec") // .Param("container", containerName)
    scheme := runtime.NewScheme()
    if err := _v1.AddToScheme(scheme); err != nil {
        panic(err.Error())
    }
    parameterCodec := runtime.NewParameterCodec(scheme)
    req.VersionedParams(&_v1.PodExecOptions{
        Stdin:     false,
        Stdout:    true,
        Stderr:    true,
        TTY:       false,
        Container: containerName,
        Command:   strings.Fields("/bin/sh -c " + command),
    }, parameterCodec)
    exec, err := remotecommand.NewSPDYExecutor(restConfig, "POST", req.URL())
    if err != nil {
        panic(err.Error())
    }
    var stdout, stderr bytes.Buffer
    err = exec.Stream(remotecommand.StreamOptions{
        Stdin:  nil,
        Stdout: &stdout,
        Stderr: &stderr,
        Tty:    false,
    })
    if err != nil {
        panic(err.Error())
    }
log.Printf("Output from pod: %v", stdout.String())
log.Printf("Error from pod: %v", stderr.String())

当command 变量只是一个简单的ls -l 时,我得到了所需的输出。但是当我尝试做类似'ls -l && echo hello' 的事情时,它会产生一个错误command terminated with exit code 2。 如果我只输入echo hello,它不会输出任何内容。但是,如果我删除Bourne Shell 前缀/bin/sh -c 并且Command 属性等于string.Fields("echo hello"),它确实会产生所需的输出hello,但是这种方法不允许我链接命令。

总而言之,我要做的是在 Pod 的容器上执行一系列命令。

【问题讨论】:

  • 我认为 Command 应该是 [ "sh", "-c", "ls -l && echo hello" ] 而不是 [ "sh", "-c", "ls", "-l", "&&", "echo", "hello" ] 这是 string.Fields 拆分它的方式。
  • 不知道有没有办法获取远程执行命令的退出码?

标签: go kubernetes sh client-go


【解决方案1】:

corev1.PodExecOptions.Command 接受 []string 类型的值。

req.VersionedParams(&_v1.PodExecOptions{
  Stdin:     false,
  Stdout:    true,
  Stderr:    true,
  TTY:       false,
  Container: containerName,
  Command:   cmds,
}, parameterCodec)

cmds 可以是:

cmds := []string{
    "sh",
    "-c",
    "echo $HOME; ls -l && echo hello",
    }

输出:

/root
total 68
drwxr-xr-x   2 root root 4096 Feb 24 00:00 bin
drwxr-xr-x   2 root root 4096 Feb  1 17:09 boot
drwxr-xr-x   2 root root 4096 Feb 24 00:00 mnt
drwxr-xr-x   2 root root 4096 Feb 24 00:00 opt
dr-xr-xr-x 396 root root    0 Mar 19 11:47 proc
drwx------   2 root root 4096 Feb 24 00:00 root
.
.
hello

解释: Tim's answer

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

命令["/bin/sh", "-c"] 表示“运行一个shell,并执行以下指令”。然后将 args 作为命令传递给 shell。在 shell 脚本中,semicolon 分隔命令,如果第一个成功,&& 有条件地运行以下命令。在上面的例子中,它总是在命令two之后运行命令one,并且只有在命令two成功时才运行命令three。

注意: 对于 bash,它将类似于以下内容:

cmds := []string{
     "bash",
     "-c",
     `export MYSQL_PWD=${MYSQL_ROOT_PASSWORD}
mysql -h localhost -nsLNE -e "select 1;" 2>/dev/null | grep -v "*"`,
                    },

【讨论】:

  • 不知道有没有办法获取远程执行命令的退出码?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-22
  • 2016-03-26
  • 2021-05-25
  • 2022-11-27
  • 2022-11-28
  • 2018-12-17
相关资源
最近更新 更多