【问题标题】:How stdout-stderr work with docker containers?stdout-stderr 如何与 docker 容器一起使用?
【发布时间】:2019-11-22 08:09:05
【问题描述】:

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


在 AWS EC2 实例上(host1),我们有 jenkins 从属设备(比如slave-container)。

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

slave-containerhost1 上启动另一个 docker 容器(比如 build-container 以构建源代码)。

下面是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 命令,在 stdoutslave-container 上提供输出:

+ grep -q success
+ echo Yes

build-container 的标准输出/标准错误如何显示在slave-container 的标准输出上?

【问题讨论】:

  • 看! {} 与抑制输出无关(在这里与您讨论:stackoverflow.com/questions/56960876/…)。另外,我不会将所有东西整合在一起然后开始尝试解决问题,而是一次做一步。 Jenkins 是这里的重要因素,我相信不是 docker。
  • @Perplexabot Jenkins 正在 docker 容器中运行
  • 之前带有+ 的任何内容很可能是由于Jenkins 而不是docker

标签: linux docker jenkins stdout docker-machine


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 但在我的情况下......它有-d
【解决方案2】:

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

这可以通过检查Jenkins source codesh 函数来证明,看:

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 来覆盖该行为。

【讨论】:

  • 这些命令来自没有 jenkins 的 docker 容器...请检查具有图像参数的docker run 命令(55664444444444444444444444444444444444444444
  • 我看到了你所说的那一行,我仍然认为这与 Jenkins vs docker 有关。我认为如果您添加 Jenkinsfile 的相关部分会很有用。
猜你喜欢
  • 2019-12-11
  • 1970-01-01
  • 2022-11-27
  • 1970-01-01
  • 2015-05-20
  • 2014-03-10
  • 2021-11-22
  • 2021-02-11
  • 2021-01-28
相关资源
最近更新 更多