Chinaunix首页 | 论坛 | 博客
  • 博客访问: 355379
  • 博文数量: 34
  • 博客积分: 251
  • 博客等级: 二等列兵
  • 技术积分: 419
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-21 15:50
文章分类

全部博文(34)

文章存档

2017年(5)

2016年(19)

2012年(10)

我的朋友

分类: 虚拟化

2016-06-01 11:50:50

参考文档:

1.    官方文档:

2.    官方最佳实践:https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/

3.   

4.    CMDENTRYPOINT的区别:http://www.cnblogs.com/programfish/p/4101884.html

Dockefile创建image是被推荐的方式,不同于”docker build”需要手动commitrm中间层镜像,dockerfile是自动化的创建image(两者原理均是使用基础镜像启动容器后commit)

一.Dockerfile构建image的优化建议

以下优化建议仅为个人当前观点,将来如有更多更好的优化建议尽量及时更新。

1.  精简程序

在构建image时,不需要安装不必要的程序,这样可以保证构建出的image轻小,依赖性小且构建速度快。

2.  1个容器运行1个服务

大多数情况下,建议1个容器运行1个服务即可,这样可以减少服务的耦合性,充分发挥容器复用及快速横向扩展的优势。

3.  合理控制镜像层数

1dockerfile指令会生成1层新的镜像,镜像层越多,image越大,容器启动速度越慢;建议尽可能减少image层数,但同时需要注意dockerfile的可读性,即合理控制image层数。

4.  Dockerfile指令参数排序

对指令参数的排序主要是为了dockerfile的可读性与确保不会重复输入参数。如:

RUN yum install -y \

Git \

net-tools \

openssh-server

5.  使用缓存

前面讲到1dockerfile指令会生成1层新的镜像,下一条指令会基于上一步生成的镜像构建新的镜像层,如果一个镜像存在相同的父镜像与指令(“ADD”指令除外),默认docker会使用缓存的镜像,而不是重新执行dockerfile指令。

所以在修改Dockerfile时,为了有效利用镜像,可以尽量不动Dockerfile的前面几行。

例如”MAINTAINER”一般在第二行,如果修改此处,那后续的”RUN”指令会全部执行,而不是使用缓存的镜像层。

二.Dockerfile主要指令及语法

1.  FROM

Dockerfile第一条指令,此指令指定dockerfile构建image的基础镜像,如果宿主机仓库没有指定的基础镜像,则从远端仓库pull

语法:FROM [image]:[tag]

2.  MAINTAINER

指明image作者,方便联系。

语法:MAINTAINER [author name] (author information, email and so on)

3.  RUN

在当前镜像生成的容器的外层(可读写层)执行命令,并commit1个新的镜像层,接下来的指令会在这个新的镜像层生成的容器里执行。

语法(2)

1)       RUN [command]

#shell form:在shell环境下执行,调用”/bin/sh –c”

2)       RUN ["executable", "param1", "param2"]

#exec form:不会触发shell,所以环境变量无法调用,但可以在没有bashimage中执行

4.  ADD

复制文件,有两个参数[source]与[destination]

注意:

1)    destination是容器内的绝对路径,如果路径不存在则自动创建;source可以是文件/文件夹/URL,如果是文件/文件夹,必须是Dockerfile所在目录的一个相对路径,且不能含../path/

2)    ADD支持自动解压tar文件,解压之后再copy到容器内。

语法:ADD [source] [destination]

5.  COPY

基本与ADD相同,但不支持远程URL(source),与自动解压的功能。

注意:官方最佳实践中建议尽量使用copy,使用RUNCOPY的组合代替ADD,因为COPY处理更透明。

6.  ENTRYPOINT

配置给容器一个可执行的命令,类似将容器变为1个可执行文件/命令。

意味着在每次使用镜像创建容器时,一个特定的应用程序可以被设置为默认程序;同时也意味着该镜像每次被调用时仅能运行指定的应用。

注意:

1)   多个ENTRYPOINT指令只有最后一个生效(后面覆盖前面);

2)   exec格式时,”docker run [image]的所有参数会追加到ENTRYPOINT之后,即”docker run [image]的参数可以传递给ENTRYPOINT,不会被覆盖,但”docker run [image]的参数会覆盖CMD指令;

3)   exec格式时,因为CMD可以为ENTRYPOINT提供参数,ENTRYPOINT本身也可以包含参数,且”docker run [image]的参数可以覆盖CMD指令,所以可以把那些可能需要变动的参数写到CMD里,而把那些不需要变动的参数写到ENTRYPOINT里面。

4)   exec格式时,在启动容器时使用--entrypoint参数会覆盖dockerfile里的ENTRYPOINT

5)   shell form格式会屏蔽掉docker run启动容器后面带的命令参数或者CMD里的参数;

语法(2)

1)    ENTRYPOINT ["executable", "param1","param2"]

#exec form:推荐使用的格式

2)    ENTRYPOINT command param1 param2

#shell form:会屏蔽掉docker run时后面加的命令参数与CMD里的参数

7.  CMD

指定制作出的image在启动成容器时运行的默认命令或参数。

注意:

1)   1dockerfile只有1CMD指令,如果使用多个CMD指令,只有最后1个指令生效;

2)   docker run命令如果指定容器运行参数,会把CMD里的参数覆盖;

3)   RUN指令是在构建image时执行,将命令固化在image中;而CMD指令在构建image时并不执行,而是在容器启动时执行(切记docker run指定的容器参数会覆盖CMD指令)

4)   如果CMD提供的是默认参数,执行命令需要提前在ENTRYPORINT中指定。

语法(3)

1)    CMD ["executable","param1","param2"]

#exec form:推荐使用的格式,可执行文件+参数

2)    CMD ["param1","param2"]

#传递到ENTRYPOINT,作为ENTRYPOINT的参数

3)    CMD command param1 param2

#shell form:作为”/bin/sh –c”的参数

8.  EXPOSE

指定容器运行时需要监听的端口,用在多容器之间通信使用。

语法:EXPOSE [port]

9.  ENV

设置环境变量,增加运行程序的灵活性,使用键值对格式。

如果需要更改镜像生成容器时改变环境变量,可在运行docker run是带-env [key]=[value]参数修改既定环境变量。

语法:ENV [key] [value]

10.        ONBUILD

指令用来设置一些触发的指令,用于在当该镜像被作为基础镜像来创建其他镜像时执行一些操作,ONBUILD中定义的指令会在用于生成其他镜像的Dockerfile文件的FROM指令之后被执行,可以用来执行一些因为环境而变化的操作,使镜像更加通用,dockerfile所有指令都可以用于ONBUILD指令

注意:

1)    ONBUILD定义的指令在生成当前image”docker build”中不会执行;

2)    通过查看docker inspect [image]命令执行结果的OnBuild键来查看某个镜像ONBUILD指令定义的内容;

3)    ONBUILD中定义的指令会当做引用该镜像的Dockerfile文件的FROM指令的一部分来执行,执行顺序会按ONBUILD定义的先后顺序执行,如果ONBUILD中定义的任何一个指令运行失败,则会使FROM指令中断并导致整个build失败,当所有的ONBUILD中定义的指令成功完成后,会按正常顺序继续执行build

4)    ONBUILD中定义的指令不会继承到当前引用的镜像中,即当引用ONBUILD的镜像创建完成后将会清除所有引用的ONBUILD指令;

5)    ONBUILD指令不允许嵌套;

6)    ONBUILD指令不会执行其定义的FROMMAINTAINER指令。

11.        USER

镜像正在运行时或接下来的RUN指令设定用户名或UID

语法:USER [uid]

12.        WORKDIR

指定RUNCMDENTRYPOINT命令的工作目录,默认为/目录。

可在dockerfile中多次出现,如果使用相对路径,后一次的相对路径是上一次WORKDIR的值。

语法:WORKDIR /path/to/workdir

13.        VOLUME

指定挂载点,可以用来让其他容器挂载以实现数据共享或对容器数据的备份、恢复或迁移。

语法:VOLUME ["path"]

三.Dockerfile示例

1.  Dockerfile

使用Dockerfile构建1个可sshimage

点击(此处)折叠或打开

  1. [root@localhost ~]# touch Dockerfile
  2. [root@localhost ~]# vim Dockerfile

#注意”Dockerfile”首字母大写

点击(此处)折叠或打开

  1. # Get a base image.
  2. FROM centos:latest
  3. # Author
  4. MAINTAINER Netonline "xxxxx@gmail.com"
  5. # Install some CLI tools.
  6. RUN yum install -y \
  7. net-tools \
  8. openssh-clients \
  9. openssh-server && \
  10. sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config && \
  11. # Modify root password.
  12. echo "root:123456" | chpasswd && \
  13. # Generate keys for sshd.
  14. ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key && \
  15. ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key && \
  16. ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key
  17. # Open sshd port and execute service.
  18. EXPOSE 22
  19. CMD ["/usr/sbin/sshd", "-D"]

#此示例将RUN需要执行的指令合并为1条指令,可减少image层数;
#yum
安装程序是按字母顺序排列的(非强制要求)

2.  构建image

点击(此处)折叠或打开

  1. [root@localhost ~]# docker build -t centos:ssh .

#”docker build”执行时使用同目录的”Dockerfile”文件;另外”centos:ssh”为构建的image名,注意命令最后带的.




3.  验证

点击(此处)折叠或打开

  1. [root@localhost ~]# docker images

阅读(2929) | 评论(0) | 转发(0) |
0

上一篇:Docker镜像加速

下一篇:Open vSwitch for CentOS

给主人留下些什么吧!~~