如何在使用Docker api附加到容器后使用stdin,stdout和stderr流?

时间:2016-02-17 06:28:46

标签: java api nginx docker stream

我正在尝试使用给定https://docs.docker.com/engine/reference/api/docker_remote_api_v1.22/

的api附加到容器

我有一个基于docker-hub nginx图像的容器正在执行。我可以发送一个附加到它的请求,并保存stderr,stdin和stdout的标志。我的目标是以交互方式使用它们。

我无法弄清楚如何使用java,发送命令和读取输出的过程。

我使用的是Docker 1.10.1版。 Api v1.22。使用的操作系统是Ubuntu 14.04。该应用程序使用JDK 1.8。

我专注于通过api调用使用attach命令,比如 http://localhost:4243/containers/container_id/attach?stdin=1&stdout=1 (4243是Docker侦听命令的地方),stdin和stdout标志用于启用流。文档包含标志详细信息。打完电话后,我想"互动"用我的容器。这可能是根据api文档,但我对如何这样做有点不清楚。

帮助将不胜感激!

1 个答案:

答案 0 :(得分:3)

您可以使用其中一个库,它们允许您从Java程序与docker交互。两种可能的替代方案是docker-clientdocker-java。 Docker-client在附加stdin时遇到了一些问题,这些问题列在issue#156中。有一个known work-around使用一些脏的反射来解决这个问题(它真的适合我)。因此,要在给定id的现有容器中启动交互式应用程序,请使用:

DockerClient dockerClient = DefaultDockerClient.builder()
      .uri( dockerURI )
      .readTimeoutMillis( Long.MAX_VALUE ) // without this interactive session may disconnect
      .build(); // use other config options if appropriate

String execId = dockerClient.execCreate(id, new String[] {"/bin/bash"}, 
    ExecCreateParam.attachStdin(), ExecCreateParam.attachStdout(),
    ExecCreateParam.attachStderr(), ExecCreateParam.tty() );
LogStream ls = dockerClient.execStart( execId );

现在使用ls.attach(stdout, stderr)将应用程序stdout,stderr重定向到您自己的OutputStream对象中的单独线程。要写入stdin,请使用上面链接的技巧获取WritableByteChannel并随意写入。

docker-java库似乎解决了类似的stdin问题(参见issue#253),尽管我从未使用过docker-java。