首页 > 其他 > 详细

为减少镜像重量下的多阶段构建镜像--关键词 - COPY --from=

时间:2020-03-07 11:57:22      阅读:2972      评论:0      收藏:0      [点我收藏+]

翻译 原文链接   https://blog.alexellis.io/mutli-stage-docker-builds/

 

是么是建造器模式?

对于像Golang这样的静态编译语言,人们倾向于从Golang“ SDK”映像中获取其Dockerfile,添加源代码,进行构建,然后将其推送到Docker Hub。不幸的是,所得图像的大小非常大-至少为670mb。
A workaround which is informally called the builder pattern involves using two Docker images - one to perform a build and another to ship the results of the first build without the penalty of the build-chain and tooling in the first image.
有个变通之法(非正式版),叫建造着者模式,使用两个Docker镜像  
一个用于执行构建,另一个用于发布结果镜像,后者不会带着大量执行构建过程中使用的构建链以及工具。

从而达到瘦身的效果!

 

建造器模式的示例:

     从Golang基本映像派生整个运行时/ SDK(Dockerfile.build)
     添加源代码
     产生一个静态链接的二进制文件
     将静态二进制文件从映像复制到主机(docker create,docker cp)
     源自SCRATCH或其他一些轻量级图像,例如alpine(Dockerfile)
     重新添加二进制文件
     将微小的映像推送到Docker Hub

 

一个例子:

Dockerfile.build

FROM golang:1.7.3

WORKDIR /go/src/github.com/alexellis/href-counter/

RUN go get -d -v golang.org/x/net/html
COPY app.go    .

RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

 Dockerfile

FROM alpine:latest
RUN apk --no-cache add ca-certificates

WORKDIR /root/

COPY app    .

CMD ["./app"]

build.sh

#!/bin/sh
echo Building alexellis2/href-counter:build

docker build --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy     -t alexellis2/href-counter:build . -f Dockerfile.build

docker create --name extract alexellis2/href-counter:build 
docker cp extract:/go/src/github.com/alexellis/href-counter/app ./app
docker rm -f extract

echo Building alexellis2/href-counter:latest

docker build --no-cache -t alexellis2/href-counter:latest .

 

如何理解多阶段构建?

Multi-stage builds give the benefits of the builder pattern without the hassle of maintaining three separate files:

多阶段构建的为建造者模式提供了很多益处,避免分多个文件维护的麻烦,如:

 

FROM golang:1.7.3

WORKDIR /go/src/github.com/alexellis/href-counter/

RUN go get -d -v golang.org/x/net/html
COPY app.go    .

RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest
RUN apk --no-cache add ca-certificates

WORKDIR /root/

COPY --from=0 /go/src/github.com/alexellis/href-counter/app    .

CMD ["./app"]

 

 

 

This is huge for developers and maintainers, especially when you support multiple Dockerfiles for different architectures such as the Raspberry Pi.

对于开发人员和维护人员而言,为树莓派等不同的架构支持多个Dockerfile时,这是很令人纠结的。

 

The general syntax involves adding FROM additional times within your Dockerfile - whichever is the last FROM statement is the final base image. To copy artifacts and outputs from intermediate images use COPY --from=<base_image_number>

不论哪个FROM是最后基础镜像的声明,通常会涉及额外次数去使用FROM
去中间层的镜像复制内容,可以使用 COPY --from=<base_image_number>

The second PR mentioned improves on this syntax and when merged would mean you can do something more like:

第二个公共版本中,提到改进了这种语法,也就是“合并”后意味着您可以做更多的事情,如:

 

FROM golang:1.7.3 as builder

WORKDIR /go/src/github.com/alexellis/href-counter/

RUN go get -d -v golang.org/x/net/html
COPY app.go    .

RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest
RUN apk --no-cache add ca-certificates

WORKDIR /root/

COPY --from=builder /go/src/github.com/alexellis/href-counter/app    .

CMD ["./app"]

 

注:
    1、FROM golang:1.7.3 as builder 给镜像取个别名 builder
    2、WORKDIR 当前工作目录 /go/src/github.com/alexellis/href-counter/app
    3、RUN 构建镜像时运行命令
    4、COPY 将脚本app.go拷贝到当前工作目录
    5、FROM alpine:latest 基于 alpine 一个小巧的 linux  
    6、RUN apk --no-cache add ca-certificates 
    7、FROM alpine:latest 基于 alpine 一个小巧的 linux  
    8、WORKDIR /root/ 切换至root目录 
    9、COPY --from=builder /go/src/github.com/alexellis/href-counter/app . 将上一层镜像复制制定目录复制到当前工作目录
    10、实例时运行 ./app

 

那么我门们该如何做呐?

基于mater分支构建docker

You can create a development build of Docker at any time by cloning the docker/docker repository and typing in make tgz. The resulting build will create binaries for you in the bundles folder.

您可以随时克隆docker / docker仓库,并输入make tgz来创建Docker的开发版本。 
生成的版本将在 打包文件夹中为您创建二进制文件。

构建步骤如下:

$ git clone https://github.com/docker/docker
$ cd docker
$ make tgz

 

让我用上述的COPY -- from 新特性,做个范例,看看有什么样的效果

Launch Docker within the container you built above:

在之前你创建的容器中启动Docker

These steps prepare the new Docker version for use:

以下步骤准备用新版Docker来供使用

$ docker run -v `pwd`/bundles:/go/src/github.com/docker/docker/bundles --privileged -ti docker-dev:master bash

The Docker development build creates an image called docker-dev. You can actually run Docker inside this image, which is what we‘ll do below:

Docker开发版本会创建一个名为docker-dev的镜像, 您实际上可以在此镜像中运行Docker,这是我们将在下面执行的操作:

$ export PATH=$PATH:`pwd`/bundles/latest/dynbinary-daemon:`pwd`/bundles/latest/binary-client/
$ dockerd &

Now still within the container, clone my repository and initiate a build using the multi-step Dockefile:

现在仍在此容器中,克隆我的仓库,并使用多步骤Dockefile启动构建:

$ git clone https://github.com/alexellis/href-counter
$ cd href-counter
$ docker build -t href-counter . -f Dockerfile.multi

the -f flag allows you to specify the name of a different Dockerfile.

-f 的标签语法 是可以让你为其他的Dockerfile指定名字。

Now run the Docker image:

$ docker run -e url=https://www.alexellis.io/ multi  
{"internal":9,"external":5}

$ docker run -e url=https://www.docker.com multi  
{"internal":97,"external":38}

Compare the differences in size between the resulting image and what we would have had if we used FROM golang:

对比 使用的是FROM golang 时和我们自己构建的容器大小区别:

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

multi               latest              bcbbf69a9b59        6 minutes ago       10.3MB
golang              1.7.3               ef15416724f6        4 months ago        672MB

 

总结

The builder pattern was effective as a work-around and would have created a binary of a similar size, but it was hard to maintain and very hard to use with Dockers automated build system.

构造模式作为一个变通的方法,建出一个相似大小的二进制的文件,可以非常有效的解决问题,但是,它也难以维护,很难与Docker的自动构建系统一起使用。

 

为减少镜像重量下的多阶段构建镜像--关键词 - COPY --from=

原文:https://www.cnblogs.com/nhz-M/p/12432878.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!