stdout-stderr如何与Docker容器一起使用?

时间:2019-07-12 14:24:37

标签: linux docker jenkins stdout docker-machine

我记得stdinstdoutstderrProcess control block中文件描述符表的前3个条目。


在一个AWS EC2实例(host1)上,我们有詹金斯奴隶(比如slave-container)。

slave-container包括与运行在host1上的docker守护进程对话的docker客户端。

slave-containerbuild-container上启动另一个docker容器(例如说host1来构建源代码)。

以下是slave-container的管道输出:

Running on slave-container in /var/jenkins_home/workspace/abc-app
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Buildabcapp)
[Pipeline] sh
+ docker inspect -f . 111111111110.dkr.ecr.us-east-1.amazonaws.com/someteam/abc-build:7-jdk.x.2
.
[Pipeline] withDockerContainer
slave-container seems to be running inside container 55664444444444444444444444444444444444444444
$ docker run -t -d -u 9000:9000 -w /var/jenkins_home/workspace/abc-app --volumes-from 55664444444444444444444444444444444444444444  111111111110.dkr.ecr.us-east-1.amazonaws.com/someteam/abc-build:7-jdk.x.2 cat
[Pipeline] {
[Pipeline] sh
+ grep -q success
+ echo Yes

docker run命令上方,启动build-container,该命令运行shell命令,该命令在stdout的{​​{1}}上提供输出:

slave-container

+ grep -q success + echo Yes 的stdout如何显示build-container的stdout / stderr?

2 个答案:

答案 0 :(得分:1)

当您运行其他命令时,Docker引擎会公开一个由Docker客户端使用的API。

在没有docker run参数的情况下运行-d的特定情况下,客户端使用端点:

POST /containers/create-用于创建容器

POST /containers/(id or name)/attach-用于附加到容器并将stdout和stderr流传输到客户端。

有关更多信息,请查看API文档:https://docs.docker.com/engine/api/v1.24/#31-containers

答案 1 :(得分:1)

发生意外行为的原因是因为Jenkins在实际的shell命令之前使用sh运行了所有set -x函数。如果您不熟悉set -x,请查看here

这可以通过检查Jenkins source code中的sh函数来证明,

public String[] buildCommandLine(FilePath script) {
    if(command.startsWith("#!")) {
        // interpreter override
        int end = command.indexOf('\n');
        if(end<0)   end=command.length();
        List<String> args = new ArrayList<>(Arrays.asList(Util.tokenize(command.substring(0, end).trim())));
        args.add(script.getRemote());
        args.set(0,args.get(0).substring(2));   // trim off "#!"
        return args.toArray(new String[0]);
    } else
        return new String[] { getDescriptor().getShellOrDefault(script.getChannel()), "-xe", script.getRemote()};
}

如您所见,在默认情况下,它以set -xset -e运行。 您可以通过在脚本前面加上shebang来覆盖该行为。