设为首页 收藏本站
查看: 1051|回复: 0

[经验分享] 用Dockerfile构建docker image

[复制链接]

尚未签到

发表于 2015-4-17 09:31:08 | 显示全部楼层 |阅读模式
DSC0000.png
     dockerfile是为快速构建docker image而设计的,当你使用docker build 命令的时候,docker 会读取当前目录下的命名为Dockerfile(首字母大写)的纯文本文件并执行里面的指令构建出一个docker image。
    而另一种构建docker iamge 的方法是pull一些基础镜像下来启动成容器,然后进入容器内安装各种需要的程序以及配置好需要的环境,最后commit成一个镜像。但是相比之 Dockerfile的方法会更加自动化,更加方便快捷,而且功能也更强大。(Docker build方法底层里也是在基础镜像下启动容器然后commit的,但是这些不需要我们手动去commit以及rm,都是自动化的。)
  
  ======(注:以下大部分内容均参考自官方文档)
  首先,是关于构建docker image的一些优化建议
  我们希望构建出的image对应的容器应该是可以在服务群中暂停(解耦性)并且快速替换,这要求容器可以在极短的时间内完成启动并配置运行起来。
  优化手段:
  
   使用.dockerignore文件 .
  dockerignore文件的设计是为了在docker build的过程中排除不需要用到的文件以及目录,目的是为了docker build这个过程可以尽可能地快速高效以及构建出来的image没有多余的“垃圾”。
  
  不要安装不必要的程序包
  我们希望构建出来的image尽可以的轻小、依赖性小以及构建过程尽可能地快。这就需要你在构建的时候不要安装不必要的程序,例如,一个存储数据的数据库容器不需要安装文本编辑器。
  
  单一容器只运行单一的服务
  大部分情况下一个容器只建议运行一个服务,这样的好处在于:减小耦合度、利于容器复用以及提高容器的横向可扩展性。如果服务之间是需要联系的,就应该把服务放在不现的容器内,然后用container linking来关联这些容器以达到目的。
  
  最小化镜像层数(layers)
  关于镜像层数(layers)的概念请参考:docker镜像与容器存储结构分析http://www.programfish.com/blog/?p=9
  把镜像层数减到最少可能加快容器的启动速度,但是这里也要权衡另一个问题:dockerfile的可读性。你可以把一个dockerfile写得很 复杂以达到构建出最小层数的镜像,但同时你的dockerfile可读性也降低了。所以我们要在镜像层数和dockerfile可读性之间做出让步与妥 协。
  
  对多?参数进行排序(一般按字母顺序)
  对参数排序可以方便以后修改更新这些参数以及确保不会重复重复输入了某些参数。例如官方的一个例子是:
  RUN apt-get update && apt-get install -y \
  bzr \
  cvs \
  git \
  mercurial \
  Subversion
  把要安装的程序包名按字母排序可以方便管理。
  
  构建的时候使用cache
  Docker build期间docker会按你提供的dockerfile文件里面的指令按顺序逐条执行。Docker在首先检查每一条指令的时候会去cache里搜 查是否有执行过这条指令并且可以复用的镜像,如果没有再去构造一个新的镜像。这是默认的情况,如果你指定不要这个过程可以在docker build里用如下参数:
  –no-cache=true
  Docker查找cache的过程:
  首先在cache里从base image(详见:docker镜像与容器存储结构分析http://www.programfish.com/blog/?p=9)起,docker会比较dockerfile里的下一条指令与这个base image的每一个子镜像的构建指令是否匹配,如果匹配则命中,否则cache标为无效。
  对于一般指令这样简单比较就足够了,但是有些精确的指令要求更详细精确的比较或者说明。 (add和copy指令见官方文档https://docs.docker.com/articles/dockerfile_best-practices/) 一旦cache在dockerifle里某一条指令检查时被标为无效,执行这个dockerfile以后的指令就不再使用cache。
  
  Dockerfile主要指令简介:
  
  FROM   
  dockerfile里的第一条指令,后面跟有效的镜像名(如果该镜像你的本地仓库没有则会从远程仓库Pull取)。后面的指令在些镜像中执行。
  FROM :
  
  MAINTAINER
  MAINTAINER  作者信息
  
  RUN   
  后跟要执行的linux命令,每一条RUN指令(可能会有多条linux命令)会在当前容器最上面的可读写层执行并且提交成一个新的镜像层,接下来的指令会在这个新的镜像层里执行。
  RUN  (the command is run in a shell – /bin/sh -c – shell form)
  RUN ["executable", "param1", "param2"] (exec form)
  注意下面的情况:  
  不要在一条RUN指令里单一使用apt-get update命令,这样可能会导致以后的apt-get install 安装出错。
  避免使用RUN apt-get upgrade 或者dist-upgrade,这样有些重要的软件包可能更新失败,如果你确实想要更新某个包A,使用apt-get install install  -y A 。这样会自动更新这个软件包。
  更多请参考官方文档。
  
  CMD
  CMD指令指定你制作出来的镜像在启动成容器时运行命令的默认的参数。
  CMD有三种写法:
  CMD ["executable","param1","param2"] (exec form, this is the preferred form)
  CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
  CMD command param1 param2 (shell form)
  第一种是可执行文件加参数,第二种是作为ENTRYPOINT的参数,第三种是作为”/bin/sh -c”的参数。
  这里CMD与ENTRYPOINT的区别强烈推荐你去看 论docker CMD与ENTRYPOINT的大区别 http://www.iyunv.com/programfish/p/4101884.html 这篇文章。看完你就懂了。
  
  ENTRYPOINT
  ENTRYPOINT字面意思指定容器的进入点。可以把你的容器制作成类似可执行文件的用法。这个指令会覆盖它前面的CMD指令,而多个 ENTRYPOINT指令只有最后一个生效(后面覆盖前面)。同时你也可以在在启动container 的时候指定–entrypoint参数来覆盖dockerfile里的ENTRYPOINT。详见官方文档。
  例如我用了这样的指令制作镜像名叫echotest:
  ENTRYPOINT ["/bin/echo"]
  然后之后这样运行:
  docker  run  -it  echotest  “this is a echo”
  实际上是平时这样的命令:
  docker  run  -it  echotest  /bin/echo  “this is a echo”
  这样你应该明白了吧。 这样一个容器的行为就很类似一个可执行文件了。 这里CMD与ENTRYPOINT的区别强烈推荐你去看 论docker CMD与ENTRYPOINT的大区别 http://www.iyunv.com/programfish/p/4101884.html 这篇文章。看完你就懂了。
EXPOSE
  EXPOSE指定容器对外暴露的端口号。
  
  ENV
  指定环境变量的值,例如你要确保CMD[“nginx”]能成功启动,你应该用ENV PATH /usr/local/nginx/bin:$PATH设定环境变量。另外你可以设定另外一些变量用于RUN命令里以便于dockerfile文件的维护:
  ENV PG_MAJOR 9.3
  ENV PG_VERSION 9.3.4
  RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && …
  ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
  这样多次出现版本号就可以通过一个变量来管理方便维护。
  
  VOLUME   
  VOLUME ["path"] 创建指定的挂载点。
  
  WORKDIR   
  进入指定目录工作。
  其它指令详情见官方文档:https://docs.docker.com/reference/builder/
  
  这里引用官方的一个dockerfile例子:
  # Nginx
  #
  # VERSION               0.0.1
  FROM      ubuntu
  MAINTAINER  Victor  Vieux  
  RUN  apt-get  update  &&  apt-get install -y  inotify-tools  nginx  apache2  openssh-server
  # Firefox over VNC
  #
  # VERSION               0.3
  FROM  ubuntu
  # Install  vnc,  xvfb  in  order  to  create  a  ‘fake’  display  and  firefox
  RUN  apt-get  update  &&  apt-get  install  -y  x11vnc  xvfb  firefox
  RUN  mkdir  ~/.vnc
  # Setup  a  password
  RUN  x11vnc  -storepasswd  1234  ~/.vnc/passwd
  # Autostart  firefox  (might  not  be  the  best  way,  but  it  does  the  trick)
  RUN  bash  -c  ‘echo  “firefox”  >>  /.bashrc ‘
  EXPOSE  5900
  CMD    ["x11vnc",  "-forever" , "-usepw",  "-create" ]
  # Multiple  images  example
  #
  #VERSION               0.1
  FROM  ubuntu
  RUN  echo  foo  >  bar
  # Will  output  something  like ===> 907ad6c2736f
  FROM ubuntu
  RUN  echo  moo > oink
  # Will  output  something  like ===> 695d7793cbe4
  # You?ll  now  have  two  images, 907ad6c2736f with /bar, and 695d7793cbe4 with
  # /oink.
  
  #号为注释符,这里一个dockerfile构建4个镜像。  
  写好Dockerfile文件后就可以在该目录下运行docker build . 命令了(可以用 -t 参数指定tag)。
  
   欢迎访问本人网站:http://www.programfish.com
  LinuxCoder 社区: http://linuxcoder.org
  注意:转载请注明 “作者:广州Linux爱好者+云计算 刁金明”
  
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-57994-1-1.html 上篇帖子: 为docker配置固定ip 下篇帖子: Hadoop on Docker
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表