文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何编写优雅的Dockerfile

2023-06-03 17:29

关注

导读

Kubernetes要从容器化开始,而容器又需要从Dockerfile开始,本文将介绍如何写出一个优雅的Dockerfile文件。

文章主要内容包括:

感谢公司提供大量机器资源及时间让我们可以实践,感谢在此专题上不断实践的部分项目及人员的支持。 如何编写优雅的Dockerfile

一、Docker容器

1.1 容器的特点

我们都知道容器就是一个标准的软件单元,它有以下特点:

1.2 Docker容器

目前市面上的主流容器引擎有Docker、Rocket/rkt、OpenVZ/Odin等等,而独霸一方的容器引擎就是使用最多的Docker容器引擎。

Docker容器是与系统其他部分隔离开的一系列进程,运行这些进程所需的所有文件都由另一个镜像提供,从开发到测试再到生产的整个过程中,Linux 容器都具有可移植性和一致性。相对于依赖重复传统测试环境的开发渠道,容器的运行速度要快得多,并且支持在多种主流云平台(PaaS)和本地系统上部署。Docker容器很好地解决了“开发环境能正常跑,一上线就各种崩”的尴尬。

如何编写优雅的Dockerfile

Docker容器的特点:

二、Dockerfile

Dockerfile是用来描述文件的构成的文本文档,其中包含了用户可以在使用行调用以组合Image的所有命令,用户还可以使用Docker build实现连续执行多个命令指今行的自动构建。

通过编写Dockerfile生磁镜像,可以为开发、测试团队提供基本一致的环境,从而提升开发、测试团队的效率,不用再为环境不统一而发愁,同时运维也能更加方便地管理我们的镜像。

Dockerfile的语法非常简单,常用的只有11个:

如何编写优雅的Dockerfile

2.1 编写优雅地Dockerfile

编写优雅的Dockerfile主要需要注意以下几点:

只要记住以上三点就能写出不错的Dockerfile。

为了方便大家了解,我们用两个Dockerfile实例进行简单的对比:

FROM ubuntu:16.04RUN apt-get updateRUN apt-get install -y apt-utils libjpeg-dev \ python-pipRUN pip install --upgrade pipRUN easy_install -U setuptoolsRUN apt-get clean
FROM ubuntu:16.04RUN apt-get update && apt-get install -y apt-utils \libjpeg-dev python-pip \         && pip install --upgrade pip \    && easy_install -U setuptools \    && apt-get clean

我们看第一个Dockerfile,乍一看条理清晰,结构合理,似乎还不错。再看第二个Dockerfile,紧凑,不易阅读,为什么要这么写?

从下表可以看出两个Dockerfile所编译出来的镜像大小:

$ docker images | grep ubuntu      REPOSITORY      TAG     IMAGE ID    CREATED     SIZE                                                                                                                                   ubuntu                 16.04       9361ce633ff1  1 days ago 422MBubuntu                 16.04-1   3f5b979df1a9  1 days ago  412MB

呃…. 好像并没有特别的效果,但若Dockerfile非常长的话可以考虑减少层次,因为Dockerfile最高只能有127层。

三、使用多阶构建

Docker在升级到Docker 17.05之后就能支持多阶构建了,为了使镜像更加小巧,我们采用多阶构建的方式来打包镜像。在多阶构建出现之前我们通常使用一个Dockerfile或多个Dockerfile来构建镜像。

3.1单文件构建

在多阶构建出来之前使用单个文件进行构建,单文件就是将所有的构建过程(包括项目的依赖、编译、测试、打包过程)全部包含在一个Dockerfile中之下:

FROM golang:1.11.4-alpine3.8 AS build-envENV GO111MODULE=offENV GO15VENDOREXPERIMENT=1ENV BUILDPATH=github.com/lattecake/helloRUN mkdir -p /go/src/${BUILDPATH}COPY ./ /go/src/${BUILDPATH}RUN cd /go/src/${BUILDPATH} && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go install –vCMD [/go/bin/hello]

这种的做法会带来一些问题:

以Golang为例,它运行时不依赖任何环境,只需要有一个编译环境,那这个编译环境在实际运行时是没有任务作用的,编译完成后,那些源码和编译器已经没有任务用处了也就没必要留在镜像里。

如何编写优雅的Dockerfile

上表可以看到,单文件构建最终占用了312MB的空间。

3.2 多文件构建

在多阶构建出来之前有没有好的解决方案呢?有,比如采用多文件构建或在构建服务器上安装编译器,不过在构建服务器上安装编译器这种方法我们就不推荐了,因为在构建服务器上安装编译器会导致构建服务器变得非常臃肿,需要适配各个语言多个版本、依赖,容易出错,维护成本高。所以我们只介绍多文件构建的方式。

多文件构建,其实就是使用多个Dockerfile,然后通过脚本将它们进行组合。假设有三个文件分别是:Dockerfile.run、Dockerfile.build、build.sh。

Dockerfile.build

FROM golang:1.11.4-alpine3.8 AS build-envENV GO111MODULE=offENV GO15VENDOREXPERIMENT=1ENV BUILDPATH=github.com/lattecake/helloRUN mkdir -p /go/src/${BUILDPATH}COPY ./ /go/src/${BUILDPATH}RUN cd /go/src/${BUILDPATH} && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go install –v


Dockerfile.run

FROM alpine:latestRUN apk –no-cache add ca-certificatesWORKDIR /rootADD hello .CMD ["./hello"]

Build.sh

#!/bin/shdocker build -t –rm hello:build . -f Dockerfile.builddocker create –name extract hello:builddocker cp extract:/go/bin/hello ./hellodocker rm -f extractdocker build –no-cache -t –rm hello:run . -f Dockerfile.runrm -rf ./hello

执行build.sh完成项目的构建。

如何编写优雅的Dockerfile

从上表可以看到,多文件构建大大减小了镜像的占用空间,但它有三个文件需要管理,维护成本也更高一些。

3.3 多阶构建

最后我们来看看万众期待的多阶构建。

完成多阶段构建我们只需要在Dockerfile中多次使用FORM声明,每次FROM指令可以使用不同的基础镜像,并且每次FROM指令都会开始新的构建,我们可以选择将一个阶段的构建结果复制到另一个阶段,在最终的镜像中只会留下最后一次构建的结果,这样就可以很容易地解决前面提到的问题,并且只需要编写一个Dockerfile文件。这里值得注意的是:需要确保Docker的版本在17.05及以上。下面我们来说说具体操作。

在Dockerfile里可以使用as来为某一阶段取一个别名”build-env”:

FROM golang:1.11.2-alpine3.8 AS build-env

然后从上一阶段的镜像中复制文件,也可以复制任意镜像中的文件:

COPY –from=build-env /go/bin/hello /usr/bin/hello

看一个简单的例子:

FROM golang:1.11.4-alpine3.8 AS build-envENV GO111MODULE=offENV GO15VENDOREXPERIMENT=1ENV GITPATH=github.com/lattecake/helloRUN mkdir -p /go/src/${GITPATH}COPY ./ /go/src/${GITPATH}RUN cd /go/src/${GITPATH} && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go install -vFROM alpine:latestENV apk –no-cache add ca-certificatesCOPY --from=build-env /go/bin/hello /root/helloWORKDIR /rootCMD ["/root/hello"]

执行docker build -t –rm hello3 .后再执行docker images ,然后我们来看镜像的大小:

如何编写优雅的Dockerfile

多阶构建给我们带来很多便利,最大的优势是在保证运行镜像足够小的情况下还减轻了Dockerfile的维护负担,因此我们极力推荐使用多阶构建来将你的代码打包成Docker 镜像。

作者:王聪

内容来源:宜信技术学院

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯