如何写出最优Dockerfile

我们知道,制作docker镜像有两种方法: docker commit 的方式和Dockerfile的方式

但是,生产实践中一定优先使用Dockerfile的方式构建镜像

使用dockerfile构建镜像有哪些好处呢?

1. 易于版本化管理

2. 过程可追溯

3. 屏蔽构建环境异构

 

但是,如果dockerfile使用不当也会引发很多问题

1. 镜像构建时间过长,甚至镜像构建失败

2. 镜像层数 过多,导致镜像文件过大

 

Dockerfile书写原则?

单一职责: 不同功能的应用应该尽量拆分为不同的容器,每个容器只负责一个业务进程

提供注释信息:晦涩难懂的代码尽量添加注释

保持容器最小化: 应该避免安装无用的软件包

合理选择基础镜像:容器的核心是应用,只要基础镜像能够满足应用的运行环境即可

尽量使用构建缓存

 

 

FROM centos:7 

# 设置环境变量指令放前面
ENV PATH  /usr/local/bin:$PATH

# 安装软件指令放前面
RUN  yum   install cmake -y

# 把业务软件的配置,版本等经常变动的步骤放在最后

  

 

 

 

正确设置时区

 

Ubuntu系统

RUN   ln  -sf   /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime

RUN  echo "Asia/Shanghai"  >>   /etc/timezone


Centos系统
RUN   ln  -sf   /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime

 

  

 

 

使用国内软件源加快镜像构建速度

 

COPY   CentOS7-Base-163.repo    /etc/yum.repos.d/CentOS7-Base.repo

 

  

 

最小化镜像层数

减少RUN命令的使用

常用指令使用说明

RUN

1. RUN 指令在构建时将会生成一个新的镜像层并且执行RUN指令后面的内容

2. 当RUN指令后面跟的内容比较复杂时,建议使用反斜杠(\)结尾并进行换行

3. RUN指令后面的内容尽量按照字母顺序排序,提高可读性

例如:

FROM  centos:7
RUN  yum  install  -y  automake \
               curl  \
               python \
               vim

  

CMD和ENTRYPOINT的区别

相同点:

CMD/ENTRYPOINT   ["command","param"]    exec模式
CMD/ENTRYPOINT    command  param          shell模式

  

不同点:

Dockerfile中如果使用了ENTRYPOINT指令,启动容器时需要指定--entrypoint参数才能覆盖Dockerfile中的ENTRYPOINT指令

而使用CMD设置的命令则可以被docker run 后面的参数直接覆盖

ENTRYPOINT指令可以结合CMD指令使用,也可以单独使用,而CMD指令只能单独使用

 

那么什么时候使用ENTRYPOINT,什么时候使用CMD呢?

希望镜像足够灵活,推荐使用CMD指令

如果镜像只执行单一的具体程序,并且不希望用户在执行docker run 时覆盖默认程序,建议使用ENTRYPOINT

 

如论使用ENTRYPOINT还是CMD,建议都使用exec模式

 

COPY 与 ADD 区别

COPY 只支持基本的文件和文件夹的拷贝功能

ADD 支持更多的文件来源类型,比如自动提取tar包,并且可以支持源文件为URL格式

日常使用中,应该使用哪个命令向容器里添加文件呢?

推荐使用COPY指令(更加透明,仅支持本地文件向容器拷贝)

 

案例

在容器中安装memtester(一种内存压测工具,应该避免使用以下格式)

 

推荐写法

 

WORKDIR

推荐使用WORKDIR来指定容器的工作路径

应该尽量避免使用RUN  cd  /work/path  &&  do  some work  这样的指令

 

posted @ 2021-10-20 17:26  羊脂玉净瓶  阅读(76)  评论(0)    收藏  举报