Dockerfile之优化经验浅谈

本文讲的是Dockerfile之优化经验浅谈,【编者的话】本文主要讲述如何优化Dockerfile,来缩短docker镜像构建需要的时间,以及Dockerfile的一些编辑规范,推荐所有的Docker爱好者阅读,非常基础的文章,本文也许会给你一些启发和指导。

优化您的Dockerfiles

Docker镜像应该是小而快的。然而,假设你在BusyBox镜像中预编译GO二进制文件,他们就会变得又大又复杂。如果不能构建一个良好的Dockerfile来帮助你提高构建缓存命中率,那么你的镜像构建过程将会变得相当的缓慢。

比如一个用于软件安装的bash脚本,里面堆砌着大量的curl、wget等命令语句,大家在写Dockerfile的时候通常就会像写这个bash脚本一样,将一系列的Docker命令堆砌在其中,这种Dockerfile在构建镜像的时候是比较低效和缓慢的。

秩序

当你正在为一个应用程序构建一个新的Dockerfile,在决定需要引哪些包、运行什么命令的时候肯定会进行很多次尝试,也会遇到很多的问题。优化你的Dockerfile确保命中“构建缓存”的概率越来越大,这样之后的每一次构建中会比前一次要更快一些。

一般的规律是有频率的改变Dockerfile中命令的排序,观察分析运行命令所耗费的时间及与其他镜像共享资源的方式。

这就意味着像WORKDIR、CMD、ENV这些命令应该在底部,然而一个RUN apt-get -y update更新应该在上面,因为它需要更长时间来运行,也可以与你所有的镜像共享。

最后任何ADD(或其它缓存失效的命令)命令应该尽可能地在Dockerfile底部,在那里你有可能做出很多改变,然后后续命令缓存失效。

明智地选择你的基础镜像

在如Ubuntu这样的操作系统镜像和Python或Java7中一个特定的应用程序中,有很多基础镜像可供选择。常识告诉你使用Ruby2来运行基于Ruby应用程序并且使用Python3运行Python应用程序。但是现在你有两个几乎没有共同之处的基础镜像,所以你需要下载和构建。相反,如果你使用Ubuntu运行这两个程序,你只需要下载一次基础镜像。

将层作为你的优势

在一个Dockerfile中每个命令都会在原来的基础上生成一层镜像。你可以很快的在三十多层的时候就结束了,这未必是一个问题,但也可以通过组合RUN命令,并使用一行EXPOSE命令列出你所有的开放端口,这样可以有效减少镜像的层数。

通过将RUN命令分组,可以在容器间分享更多的层。当然如果你有一组命令可以多个容器通用,那么你应该创建一个独立的基础镜像,它包含你建立的所有镜像。

对于每一层来说你都可以跨多个镜像分享,这样可以节省大量的磁盘空间。

容器的体积

在创建容器并考虑到体积问题的时候,不要为了节省空间去使用体积小的镜像,尽量使用你将要提供数据的应用程序打成的镜像。如果你这样做了,并且提交了磁盘数据,你不仅在容器中储存了你的数据,而且对实际应用程序的调试也非常有用。

消耗

当你已经构建了一个镜像,在运行它的时候发现有一个package缺少了,把它添加到Dockerfile的底部,而不是添加到顶部的run apt-get命令那里。这意味着你能尽快的重新构建这个镜像了。一旦你的镜像可以正常工作,你可以再提交源码之前重新优化整理Dockerfile。

案例

如果一个Dockerfile是由类似于一个bash脚本写出来的,那么它可能会是这样的:

FROM ubuntu:trusty
MAINTAINER Paul Czarkowski "paul@paulcz.net"

RUN apt-get -yq update

# Apache
RUN \
apt-get -yqq install \
apache2 \
apache2-utils \
libapache2-mod-python \
python-dev \
python-pip \
python-cairo \
python-pysqlite2 \
python-mysqldb \
python-jinja2
sqlite3 \
curl \ 
wget \
git \
software-properties-common

RUN \
curl -sSL https://bootstrap.pypa.io/get-pip.py | python && \
pip install whisper \
carbon \
graphite-web \
'Twisted<12.0' \
'django<1.6' \
django-tagging

# Add start scripts etc
ADD . /app

RUN mkdir -p /app/wsgi
RUN useradd -d /app -c 'application' -s '/bin/false' graphite
RUN chmod +x /app/bin/*
RUN chown -R graphite:graphite /app
RUN chown -R graphite:graphite /opt/graphite
RUN rm -f /etc/apache2/sites-enabled/*

ADD ./apache-graphite.conf /etc/apache2/sites-enabled/apache-graphite.conf

# Expose ports.
EXPOSE 80 
EXPOSE 2003 
EXPOSE 2004 
EXPOSE 7002

ENV APACHE_CONFDIR /etc/apache2
ENV APACHE_ENVVARS $APACHE_CONFDIR/envvars
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_RUN_DIR /var/run/apache2
ENV APACHE_PID_FILE $APACHE_RUN_DIR/apache2.pid
ENV APACHE_LOCK_DIR /var/lock/apache2
ENV APACHE_LOG_DIR /var/log/apache2

WORKDIR /app

# Define default command.
CMD ["/app/bin/start_graphite"]

然而这个Dockerfile的优化版本是基于之前所讨论的内容的,它看起来是这样的:

# 1 - Common Header / Packages
FROM ubuntu:trusty
MAINTAINER Paul Czarkowski "paul@paulcz.net"

RUN apt-get -yq update \
&& apt-get -yqq install \
wget \
curl \
git \
software-properties-common

# 2 - Python
RUN \
apt-get -yqq install \
python-dev \
python-pip \
python-pysqlite2 \
python-mysqldb

# 3 - Apache
RUN \
apt-get -yqq install \
apache2 \
apache2-utils

# 4 - Apache ENVs
ENV APACHE_CONFDIR /etc/apache2
ENV APACHE_ENVVARS $APACHE_CONFDIR/envvars
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_RUN_DIR /var/run/apache2
ENV APACHE_PID_FILE $APACHE_RUN_DIR/apache2.pid
ENV APACHE_LOCK_DIR /var/lock/apache2
ENV APACHE_LOG_DIR /var/log/apache2

# 5 - Graphite and Deps
RUN \
apt-get -yqq install \
libapache2-mod-python \
python-cairo \
python-jinja2 \
sqlite3

RUN \
pip install whisper \
carbon \
graphite-web \
'Twisted<12.0' \
'django<1.6' \
django-tagging

# 6 - Other
EXPOSE 80 2003 2004 7002

WORKDIR /app

VOLUME /opt/graphite/data

# Define default command.
CMD ["/app/bin/start_graphite"]

# 7 - First use of ADD
ADD . /app

# 8 - Final setup
RUN mkdir -p /app/wsgi \
&& useradd -d /app -c 'application' -s '/bin/false' graphite \
&& chmod +x /app/bin/* \
&& chown -R graphite:graphite /app \
&& chown -R graphite:graphite /opt/graphite \
&& rm -f /etc/apache2/sites-enabled/* \
&& mv /app/apache-graphite.conf /etc/apache2/sites-enabled/apache-graphite.conf

1 - Common Header / Packages

这是最常见的共享层,在同一个主机上运行所有镜像应该从它开始。你可以看到我已经添加了一些诸如curl和git的操作,他们不是必须的,但是对调试很有用。而且因为他们在分享层,所以它们不会占用太多空间。

2 - Python, 3 - Apache

现在说一下我们的语言规范。在这里我已经包含了python和apache的部分,因为到底把谁放在第一位并不十分清楚。如果我们把apache放在第一位,我们可以获得一个包含层和免费得到apache的ruby应用程序。

4 - Apache Envs

我把这些单独说出来是为了以下这些原因。

首先,镜像中添加Apache部分之后直接构建其他需要的部分模块,以便于在构建多个镜像的过程中尽量多应用公共缓存。你也许认为这并不重要,因为类似EVN的调用是很便宜的,但是我见到过随机的ENV调用耗费了10秒钟甚至更多时间。

有一个很好的例子:你可能想要在容器的底部启动,但这些命令不能被改变的,那么最好把他们移到略微靠前一点的地方。

其次,我真希望Docker能够在同一行指定多个环境,这样可以减少层数,最终提供了一种最简化的构建方式。

5 - Graphite and Deps

这包含了一些特定的apt和pip等资源包。你可以在一个单一的命令中加入他们,利用&&符号最为分隔符,如果需要修改只需要修改这条组合命令即可。

6 - Other

这包含了一大堆简易的命令,如ADD和VOLUME,比起以前安装的包,他们更不可能改变,但运行的效率也不慢,所以在这些命令的缓存失效以后就会变得并不那么重要了。
所以建议把类似的这些命令放在Dockerfile的底部。

7 - First ADD

你应该在最后面使用ADD命令。

8 - Final setup

将这些类似ADD命令的操作放入最后一层。

最后

希望这篇文章能够帮你编写一个更好的Dockerfile文件。这些都是我在构建我自己的镜像的时候所经历过的,虽然他们可能并不适用于所有情况(或可能是错误的),但他们确实提高了我的开发经验。

原文链接:Optimizing your Dockerfiles (翻译:王康 翻译:李颖杰)
===========================
译者介绍
王康,现就职于sion,高级软件工程师,负责云图部署服务的相关工作。曾就职于momo。个人比较热爱新兴技术,热爱共享学习。

原文发布时间为:2015-03-15

本文作者:大自然保护协会志愿者-王康

本文来自合作伙伴DockerOne,了解相关信息可以关注DockerOne。

原文标题:Dockerfile之优化经验浅谈

时间: 2025-01-02 18:22:44

Dockerfile之优化经验浅谈的相关文章

企业网站优化经验浅谈SEO之站内优化篇

     当初的自己开始工作可算是顶级的seo菜鸟了,自己当初在学校,在网上学习的全是seo理论知识,要是说实践的话那是曾没有过的.对此我也很感谢我以前公司的培养和给予我的机会.初做seo,是给企业公司网站做seo搜素引擎优化. 那么我就针对我做过的企业网站seo,结合自己那么一丁点的经验来给大家浅谈一下网站内部优化. 首先,你拿到一个网站你得首先看他是否适合做seo,是否需要做改版,网站结构是否需要改动等等问题.一般来说DIV+CSS是比较适合做seo网站优化的.待你解决掉网站构架整体问题后,

百度推广:SEM优化经验浅谈

如何能够成为合格的SEM优化师?如何能在纷杂的数据中找到优化目标?如何能帮助转化数据持续提升?了解SEM优化的3个要点就能让优化过程简单便捷,优化目标清晰可实现. 很多刚接触SEM的朋友,对于SEM都有一些迷茫和不解.同时认为SEM优化是一个虚无缥缈的事情.今天就简单的和大家分享一下什么是SEM,同时和大家沟通一下自己的一些优化心得,希望能引起大家的共鸣,一起总结和交流SEM的优化经验. 那么,什么是SEM(Search Engine Marketing,http://www.aliyun.co

结合自身优化手法浅谈企业站站内优化的操作要点

随着电子商务的发展愈演愈烈,企业网站也犹如雨后春笋般的异军突起,但是笔者发现目前很多企业网站在上线之前都存在或多或少的一些内部问题,根据笔者经验和观察,一些企业站上线之后,站内优化做的非常不好,有些企业网站基本的内容更新这块都存在一些问题,笔者一直从事的是企业网站的优化和运维工作,以自身在企业站站内优化这方面的相关心得和大家分享一下. 第一,关键词的选择和布局策略.一个企业网站上线之前,首先要对网站有一个准确的定位,围绕这个定位做好基本的关键词的选择,关键词选择可以参考同行的网站,也可以利用一些

企业类网站优化推广浅谈

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 11月初九橙idc正式上线,距今已经过去了两个月.可能网站和我最初的定位有些出入,本来我是想把这个站做成大站,不自觉得又走上了优化的道路.网站的呈现思路是同事告诉我的,后期整个网站被收录,到页面优化是我做的. 一.页面收录 可能是11.4号,谷歌就收录了整个网站80%的页面.而百度收录我的网站却是一个月后的事情,更确切的说是百度也很快得收录了

A5 SEO诊断优化小组浅谈视频如何推广

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 上篇文章说到了视频的录制要求,视频制作好之后,对于站长而言相信已经很清楚接下来要做的事了吧,自然就是视频的推广问题了,那么制作好的视频究竟如何推广才能达到最大的效果呢?下面A5 SEO诊断就这个问题来和大家简单聊聊. 1.利用 新浪微博 QQ微博.QQ群进行宣传 a) 新浪微博发布视频的豆单或推广地址(各视频每周各一次) b) 定期搞微博的T

80后农民工做网站 月收入突破5000SEO经验浅谈

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 笔者一实实在在80后农民工,03年职业中专毕业,做个酒楼服务员,甚至扫过厕所,因为无技术无文凭,更多时候一直混迹与工厂,06年开始建个人主页,纯爱好从位想过网站可以赚钱.09年10月经站长交流开始正式接触SEO!历时一年,网站收入与本月终于突破5000RMB! 经其它站长介绍了解到A5也有快一年了,但从来未曾发表过文章,实在因为笔者思绪凌乱,

网页设计之入门经验浅谈

  对于网页设计,我还是有一定的发言权的,多年的互联网工作经验,公司的自己的作品也有一些了,我认为对于网页设计这个方面来说,设计是一个不断学习的过程,对于网页设计,我的感想有以下两点. 第一,懂得网页设计 不管你去做什么东西,你都需要先去了解它,这是我们认知的一个基础的前提,那么对于网页设计,有的站长认为网页嘛,不需要那么刻意的去设计,只要自己的网站文章原创,搜索引擎收录,权重高,那么网页就无所谓了.其实这个想法是片面的,这样做出来的网站,完全忽略了用户的感受,就算你的网站在搜索引擎上被用户找到

[Android] [Java] Process 创建+控制+分析 经验浅谈

无论是Android亦或者Java中或多或少需要调用底层的一些命令,执行一些参数: 此时我们需要用到Java的Process来创建一个子进程,之所以是子进程是因为此进程依赖于发起创建请求的进程,如果发起者被Kill那个子进程也将Kill. 对于Process相信使用过的朋友一定不会陌生,它具有如下特点: 1.创建简单 2.控制难 3.容易导致无法创建子进程 4.如果是多线程那么很有可能造成内存溢出 以上现象如果你只是偶尔使用一次,创建一个进程或许你什么都没有感觉到,但是如果你使用了多线程,进行了

在A5论坛卖站经验浅谈

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 笔者混迹A5已有多年.a5是笔者非常值得学习的一个网站.原因很简单,a5切切实实的可以帮助帮助笔者赚到钱,一个可以帮我赚到钱的网站当然是一个好网站.所以笔者做网站常常以A5作为标尺,2012年,我开始在A5上卖网站.也取得了一些A5卖站的经验,以奉献给广大站长 笔者2012年一年在A5大约出售上百个网站.有流量站,有权重站,当然也有垃圾站.但