我不完全确定这里发生了什么,但是当我在容器中运行代码时,似乎缓冲了stdout,但是如果我在主机或OSX上运行它,则不会。
https://github.com/myles-mcdonnell/procwrap/blob/master/procwrap.go
相关部分(为简洁起见而修改):
cmd := exec.Command("ping", "127.0.0.1")
logger := &lumberjack.Logger{
Filename: conf.LogFile,
MaxSize: conf.MaxLogSizeMb,
MaxBackups: conf.MaxLogBackups,
MaxAge: conf.MaxLogAgeDays,
}
cmd.Stdout = io.MultiWriter(os.Stdout, logger)
err := cmd.Run()
在容器中运行子进程运行正常,但我只是间隔地看到输出(到stdout和日志文件),就像刷新缓冲区一样。在容器外部运行它,并在生成时输出。我使用的是1.6.3。我看到以交互方式和后台运行容器的相同行为。
Docker版本:
Client:
Version: 1.10.3
API version: 1.22
Go version: go1.5.3
Git commit: 20f81dd
Built: Thu Mar 10 21:49:11 2016
OS/Arch: darwin/amd64
Server:
Version: 1.12.0
API version: 1.24
Go version: go1.6.3
Git commit: 8eab29e
Built: Thu Jul 28 23:54:00 2016
OS/Arch: linux/amd64
=======更新======
我根据基本图像看到了不同的行为。在debian上运行procwrap:wheezy base我得到缓冲输出。在ubuntu上做同样的事情:相信它是同步的。下面的Dockerfiles,只需执行' docker run {image_name}'在每个观察。在wheezy VM上运行procwrap(不涉及docker)不会缓冲输出。
TRUSTY:
FROM ubuntu:trusty
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y git
RUN curl -O https://storage.googleapis.com/golang/go1.6.3.linux-amd64.tar.gz
RUN tar -xvf go1.6.3.linux-amd64.tar.gz
RUN mv go /usr/local
ENV GOROOT=/usr/local/go
RUN mkdir -p /go/src/github.com/myles-mcdonnell
ENV GOPATH=/go
ENV PATH=$PATH:$GOPATH/bin:$GOROOT/bin
RUN go get github.com/myles-mcdonnell/procwrap
WORKDIR /go/src/github.com/myles-mcdonnell/procwrap
CMD procwrap -v
喘鸣:
FROM debian:wheezy
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y git
RUN curl -O https://storage.googleapis.com/golang/go1.6.3.linux-amd64.tar.gz
RUN tar -xvf go1.6.3.linux-amd64.tar.gz
RUN mv go /usr/local
ENV GOROOT=/usr/local/go
RUN mkdir -p /go/src/github.com/myles-mcdonnell
ENV GOPATH=/go
ENV PATH=$PATH:$GOPATH/bin:$GOROOT/bin
RUN go get github.com/myles-mcdonnell/procwrap
WORKDIR /go/src/github.com/myles-mcdonnell/procwrap
CMD procwrap -v
答案 0 :(得分:4)
我面临同样的问题,看起来根本原因是“stdout缓冲”。 如有任何其他问题,您可以开始阅读http://www.pixelbeat.org/programming/stdio_buffering/和谷歌。 我没有通过“stdbuf”或任何linux / app设置来解决它,并且更改了控制台应用程序的源代码我希望在每次写入时进行dockerize以继续文件刷新。
(由于很多原因,我的配置很奇怪,但它是:应用程序已将日志输出配置到名为“/ dev / stdout”的文件,并且它在每个日志写入时执行file_flush,而docker可以显示实际的消息时间在“码头日志-f XXXXX”)
答案 1 :(得分:1)
这是你要问的吗?
为什么我看到我的输出是大块的?它被缓冲并在某个地方冲洗了吗?
是。您的Docker容器正在Docker engine上运行(可能由Docker machine包装)并且您的命令正在从客户端运行。即使您的引擎是在本地安装的,并且您在交互模式下运行容器,您输入的命令和您看到的输出仍然基本上是针对{{1}的HTTP请求的结果}。 (或Unix Socket或TTY通信。)(我简化。)Docker通过网络驱动程序路由I / O,即必须将其stdout刷新到(虚拟?)网络连接,然后客户端刷新 到你的标准输出。
在后台模式下,引擎捕获stdout和(by default)写入文件。 localhost
命令从客户端向引擎发送请求,引擎通过回读该文件的内容进行响应。