【问题标题】:Docker micro-containersDocker 微容器
【发布时间】:2017-06-04 21:50:51
【问题描述】:

我正在试验微型容器。我创建了以下 Dockerfile。这个想法是这个 Docker 文件从一个非常小的基础镜像开始。 (5 MB) 安装构建工具,进行构建,然后删除构建工具。

FROM alpine
ENTRYPOINT ["/bin/dockerdemo"]

RUN apk update
RUN apk add -t build-deps build-base go git

COPY . /go/src/dockerdemo

RUN cd /go/src/dockerdemo \
    && export GOPATH=/go \
    && go get \
    && go build -o /bin/dockerdemo \
    && rm -rf /go

RUN apk del --purge build-base go git

我期待它真的很小。但它是 358 MB。看来最后一个命令实际上并没有删除构建组件。

我对 Docker 很陌生,所以我可能在这里完全遗漏了一些东西。

也可能是镜像上的文件系统没有被压缩,所以即使构建组件文件消失了,文件系统仍然是 358 MB。

【问题讨论】:

    标签: docker containers alpine


    【解决方案1】:

    如果该步骤对文件系统进行了更改,则 docker 文件中的每个 COMMAND 都可以提交一个新的 image file system layer

    即使您在所有其他步骤之后RUN rm -rf /,图像仍然会在图像中存储每个前一层的内容。

    在一个RUN 步骤中进行安装和删除,以避免提交您不想保留的文件系统更改:

    FROM alpine
    ENTRYPOINT ["/bin/dockerdemo"]
    
    COPY . /go/src/dockerdemo
    
    RUN set -uex; \
        apk update; \
        apk add -t build-deps build-base go git; \
        cd /go/src/dockerdemo; \
        export GOPATH=/go; \
        go get; \
        go build -o /bin/dockerdemo; \
        rm -rf /go; \
        apk del --purge build-base go git
    

    您会注意到,在使用此设置时,每次都必须运行所有步骤,因此您会失去一些 Docker 缓存的好处。

    构建映像

    如果您对构建周转时间有疑问,另一种方法是使用与运行应用程序的镜像分开的特定构建镜像。

    关于 Go 的一个很酷的事情是您可以在没有依赖项的情况下 build static binaries 并在 FROM scratch 运行它们,从而产生一个真正的微型容器。

    正如 Mark O'Connor 所说,您可能不需要为构建设置自己的映像,因为您可以使用官方的 golang image

    FROM golang
    
    COPY . /go/src/dockerdemo
    
    RUN set -uex; \
        cd /go/src/dockerdemo; \
        export GOPATH=/go; \
        go get; \
        CGO_ENABLED=0 GOOS=linux go build -ldflags "-s" -a -installsuffix cgo -o /bin/dockerdemo;
    

    从图像中提取二进制文件

    docker run go-build tar -cvf /bin/dockerdemo > dockerdemo.tar
    

    从中构建应用容器

    FROM scratch
    ADD dockerdemo.tar /
    ENTRYPOINT ["/bin/dockerdemo"]
    

    【讨论】:

    • 是的,构建需要一段时间,因此构建和运行映像是有意义的。命令“ADD dockerdemo.tar /”不会在文件系统上留下一个 tar 文件吗?或者 ADD 是否隐式支持 tar 文件并自动进行提取?
    • docs.docker.com/engine/reference/builder/#/add 如果 是采用可识别压缩格式(identity、gzip、bzip2 或 xz)的本地 tar 存档,则将其解压缩为目录。来自远程 URL 的资源不会被解压缩。当一个目录被复制或解压时,它的行为与 tar -x 相同
    • Multistage docker builds 是这些天要走的路。
    【解决方案2】:

    您确定占用 350 MB 的不是 build-depsbuild-basego 和/或 git

    【讨论】:

      【解决方案3】:

      为什么不使用来自 Docker hub 的官方 golang 镜像?它有一个高山选项。

      https://hub.docker.com/_/golang/

      结帐1.8-alpine Dockerfile:


      Docker 是一个分层的附加文件系统。这意味着文件并没有真正被删除。您需要导出/导入以将所有内容压缩到单个层。

      【讨论】:

        猜你喜欢
        • 2018-09-27
        • 2017-04-06
        • 2020-09-14
        • 2018-06-10
        • 1970-01-01
        • 2022-10-04
        • 2018-06-26
        • 2017-01-03
        • 2019-07-31
        相关资源
        最近更新 更多