免费下载案例集|20+数字化领先企业人才培养实践经验 了解详情
写点什么

Docker 这么火,但你真的会写 Dockerfile 吗?【下】

  • 2020-03-10
  • 本文字数:1557 字

    阅读完需:约 5 分钟

Docker 这么火,但你真的会写 Dockerfile 吗?【下】

本文是 Dockerfile 编写教程下半部分:Dockerfile 是应用一系列自定义的命令和格式构成文本文件从而简化镜像构建的过程。但如果处理不当,也会跌坑里~ Caicloud 独家奉献 Dockerfile 的 best practice。秘笈拿好,保你出坑~

一个容器只放一个应用

在一个 Container 中安装多个应用既使得镜像更大又使得可读性和逻辑性更差。所以类似一个函数只干一件事的思想,一个 Container 也只应该放一个应用。

合理使用 CMD 和 ENTRYPOINT 命令

CMD 和 ENTRYPOINT 都能用来指定开始运行的程序,而且这两个命令都有两种不用的语法:


CMD foo a b c
复制代码


或者:


CMD [“foo”, “a”, “b”, “c”]
复制代码


对于第一种语法,docker 会自动加入“/bin/sh –c”到命令中,这样就有可能导致意想不到的行为。为了避免这种行为,我们推荐所有的 CMD 和 ENTRYPOINT 都应该使用第二种语法。


如果两个同时使用,请确定确定他们的含义没有错误。一般来说需要两个同时使用的情况只有 ENTRYPOINT 指定需要运行的 binary,CMD 给出运行的默认参数。

挑选合适的基础镜像

一个合适的基础镜像是能满足运行应用所需要的最小的镜像。这里包括


  • 如果不需要操作系统,那么使用 scratch 镜像就好;能使用小的镜像就不要使用大的。

  • 指定的基础镜像需要有版本号,比如 debian 就有很多不同的版本。不指定版本号就永远用的 latest,这个会一直变。因为不同版本的系统和安装的软件有兼容性问题,所以不指定版本会使得 Dockerfile 不稳定。

  • 如果多个镜像需要安装一系列相同的软件,那么可以考虑新建一个基础镜像来安装这些软件。以后的镜像直接使用新生成的基础镜像就好

优化 apt-get 相关操作

将多个 apt-get 操作合成一个既能减少 layer 数,又能更好的管理安装的东西(避免重复安装)。在 apt-getinstall 之前,最好使用 apt-getupdate 这样可以保证安装的程序是最新版本的。在安装完之后最好使用 apt-get clean 来清理中间结果。下面给出了一个比较推荐的 apt-get 操作的格式:


RUN apt-get update && apt-get install -y \                                                                                  package-bar \  package-baz \                            package-foo && \apt-get    clean
复制代码


需要安装的软件最好按字母序排列,这样以后要查找或者增加新的软件方便。

合理使用 ADD 命令

1.ADD 命令和 COPY 命令在很大层度上功能是一样的。但是 COPY 语义更加直接,所以我们推荐尽量使用 COPY 命令。唯一例外的是 ADD 命令自带解压功能,如果需要拷贝并解压一个文件到镜像中,那么我们可以使用 ADD 命令。除此之外,我们都推荐使用 COPY 命令。



    ADD http://example.com/big.tar.xz /usr/src/things/RUN tar -xJf /usr/src/things/big.tar.xz -C    /usr/src/thingsRUN make -C /usr/src/things all
    复制代码


    我们不推荐使用 ADD 命令来获取网络资源。网络资源应该使用 RUN wget 或者 curl 命令来获取。因为使用 wget 或者 curl 更加方便清理存储的中间文件和临时文件,同时这样也能使用更少的 layer 来完成同样的事情。比如命令:


    可以由以下命令代替:


    RUN mkdir -p /usr/src/things \&& curl -SL    http://example.com/big.tar.xz \| tar -xJC /usr/src/things \&& make -C /usr/src/things all
    复制代码

    不要设置公共端口

    Dockerfile 支持 mapping 私有端口和公共端口(比如命令 EXPOSE 80:8080),但是我们不推荐 mapping 公共端口因为 Container 在编译的时候无法确定这个公共端口在它运行的环境中是否已经被其他程序占用。

    清理没用的中间结果

    中间结果可以包括:


    • 安装的对最后应用没有的软件。比如安装 foo 需要软件 bar,但是最后的应用不需要 bar。那么在安装完成 foo 之后就可以把 bar 删了

    • 拷贝的临时文件

    • 安装产生的中间结果


    本文转载自才云 Caicloud 公众号。


    原文链接:https://mp.weixin.qq.com/s/wy2wn0NMNuK3aDoNGj_7nQ


    2020-03-10 21:24711

    评论

    发布
    暂无评论
    发现更多内容

    基于字节码的统一异常上报实践

    转转技术团队

    异常机制 Java’

    Vue3中如何使用异步请求?

    Python研究所

    6月月更

    CTO专访:合见工软深化产品布局 加速国产EDA技术革新

    科技热闻

    亲测!Centos7部署PHP + Swoole

    迷彩

    Apache Linux 微服务 swoole 6月月更

    助力极致体验,火山引擎边缘计算最佳实践

    火山引擎边缘云

    云计算 边缘计算 低时延 边缘云原生 边缘网络

    钛动科技:我们的 Zadig 落地之路

    Zadig

    DevOps 持续交付 企业出海 研发效率

    微博评论架构设计

    泋清

    #架构训练营

    易快报:我们用 Zadig 实现万次构建部署,聪明运维,释放开发生产力

    Zadig

    DevOps 微服务架构 CI/CD 容器化 Zadig

    龙书虎书鲸书啃不动?试试豆瓣评分9.5的猴书

    图灵教育

    编译原理 go语言

    面试突击61:说一下MySQL事务隔离级别?

    王磊

    Java java面试

    高校如何基于云原生构建面向未来的智慧校园?全栈云原生架构VS传统IT架构

    York

    云原生 数字化转型 智慧校园 教育科技

    rxjs Observable 设计原理背后的 Pull 和 Push 思路

    汪子熙

    typescript 响应式编程 angular RXJS 6月月更

    SOFARegistry 源码|数据同步模块解析

    SOFAStack

    源码解析 注册中心 数据同步 开源软件

    java就业培训 | 怎么实现 SpringBoot 并行任务

    @零度

    JAVA开发 springboot

    TTChat x Zadig 开源共创 Helm 接入场景,环境治理搞得定!

    Zadig

    DevOps 微服务 音视频 测试环境治理

    妙!妙盈科技全面实施 Zadig 助力容器化建设,全面拥抱 Kubernetes 和云原生

    Zadig

    DevOps CI/CD 容器化 自动化运维 Zadig

    智能指标驱动的管理和决策平台 Kyligence Zen 全新上线,限量内测中

    Kyligence

    InfoQ百位优质创作者签约计划第三季,终于等到了!!!

    InfoQ写作社区官方

    热门活动 签约计划第三季

    中科方德技术专家直播:如何基于 OpenStack、Ceph 构建私有云平台? | 第 27 期

    OpenAnolis小助手

    Ceph 龙蜥大讲堂 中科方德 OpenStack 私有云平台

    揭秘百度智能测试在测试自动执行领域实践

    百度Geek说

    测试

    影响LED封装散热主要因素有哪些?

    Dylan

    LED LED显示屏 led显示屏厂家

    什么是外链和内链?

    源字节1号

    前端开发 后端开发 网站开发

    年轻就要醒着拼,年轻就要勇于尝试

    Zadig

    DevOps 微服务治理 自动化运维 企业案例

    架构实战营第五模块课后作业

    Geek_53787a

    架构实战营

    高效远程办公的基石:有效沟通 |社区征文

    wljslmz

    远程办公 初夏征文

    大数据培训 | Flink SQL窗口表值函数聚合实现原理

    @零度

    flink 大数据开发

    ONES 创始人王颖奇对话《财富》(中文版):中国有没有优秀的软件?

    万事ONES

    悬赏平台并没有WEB端开发,在原生开发和混合开发中哪种合适?

    开源直播系统源码

    软件开发 app源码 原生开发 混合开发 悬赏平台源码

    iMile 利用 Zadig 多云环境周部署千次,跨云跨地域持续交付全球业务

    Zadig

    DevOps 微服务架构 CI/CD 持续交付 国际化

    超级详细的 Maven 教程(基础+高级)

    Ayue、

    maven

    揭秘!付费会员制下的那些小心机!

    CRMEB

    Docker 这么火,但你真的会写 Dockerfile 吗?【下】_语言 & 开发_才云科技_InfoQ精选文章