stdout被缓冲在docker容器中 [英] stdout being buffered in docker container
问题描述
我不完全确定这里发生了什么,但是当我在容器中运行代码时,似乎stdout正在缓冲,但是如果我在主机或OSX上运行它,则不是.
I'm not entirely sure what is going on here but it appears that stdout is being buffered when I run my code in a container, but not if I run it on the host or on OSX.
https://github.com/myles-mcdonnell/procwrap/blob/master/procwrap.go
相关部分(为简洁起见进行了修改):
The relevant piece (modified for brevity):
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和日志文件),就像正在刷新缓冲区一样.在容器外部运行它,并在生成时输出.我正在使用go 1.6.3.我看到了在后台交互运行容器的相同行为.
Running in a container the sub process runs fine but I only see output (to stdout and the log file) at intervals, like a buffer is being flushed. Run it outside of a container and it outputs as it is generated. I'm using go 1.6.3. I see the same behaviour running the container interactively and in the background.
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
========更新======
======= UPDATE ======
基于基本图像,我看到了不同的行为.在debian:wheezy的基础上运行procwrap,我得到了缓冲的输出.在ubuntu:trusty上做同样的事情,它是同步的.下面的Dockerfile,只需对每个文件执行'docker run {image_name}'即可观察.在微弱的VM(不涉及docker)上运行procwrap不会缓冲输出.
I'm seeing different behaviour based on the base image. Running procwrap on a debian:wheezy base I get buffered output. Doing the same on ubuntu:trusty it's synchronous. Dockerfiles below, simply execute 'docker run {image_name}' on each to observe. Run procwrap on a wheezy VM (no docker involved) does not buffer the output.
暴躁:
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
WHEEZY:
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
推荐答案
我遇到了同样的问题,看起来根本原因是"stdout缓冲".您可以开始阅读 http://www.pixelbeat.org/programming/stdio_buffering/和google如有任何其他问题.我无法通过"stdbuf"或任何linux/app设置来解决该问题,并且更改了我想通过dockerize在每次写入时继续进行文件刷新的控制台应用程序的源代码.
I faced same issue and looks like root cause is "stdout buffering". You can start reading http://www.pixelbeat.org/programming/stdio_buffering/ and google in case of any additional question. I failed to resolve it by "stdbuf" or any linux/app settings and changed source code of the console app I want to dockerize to proceed with file flush on each write.
(由于许多原因,我的配置很奇怪,但是它是:该应用已将日志输出配置到名为"/dev/stdout"的文件,并且它在每次写入日志时都执行file_flush,而docker可以真实显示消息时间在"docker日志-f XXXXX"上)
(my configuration is strange because of a lot of reason, but it is: the app has configured log output to the file named "/dev/stdout" and it performs file_flush on each log write and docker can show messages in real time on "docker logs -f XXXXX")
这篇关于stdout被缓冲在docker容器中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!