Dockerfile容器化应用最佳实践

Dockerfile容器化应用最佳实践

将一个应用容器化,就是将这个应用构建成Docker镜像,然后以Docker容器方式来运行。

构建Docker镜像就是编写Dockerfile,并通过docker build 命令构建成Docker镜像。

可以用”小、快、好、省“来概括Dockerfile的最佳实践。

最佳实践

让构建出来的镜像尽可能”小“

Why?

小的镜像的好处包括构建镜像快,占用磁盘空间小,网络传输快(比如docker pulldocker push 时速度快)。

How?

  • 选择适合的尽量小的基础镜像

    比如,你要从Linux操作系统基础镜像开始构建,可以参考下表来选择合适的基础镜像:

镜像名称 大小 使用场景
busybox 1.15MB 临时测试用
alpine 4.41MB 主要用于测试,也可用于生产环境
centos 200MB 主要用于生产环境,支持CentOS/Red Hat,常用于追求稳定性的企业应用
ubuntu 81.1MB 主要用于生产环境,常用于人工智能计算和企业应用
debian 101MB 主要用于生产环境

让构建镜像过程尽可能“快”

Why?

加快构建的好处不言而喻,比如加快构建Docker镜像环节可以提升整个部署流水线的效率。

How?

  • 使用清洁的构建上下文(build context)

    Docker CLI是由给定一个目录或者URL作为构建上下文的,在镜像构建之前会将该上下文发送到Docker Daemon。建议在一个新的目录里创建Dockerfile,然后在该目录里只添加镜像包含的文件。这为docker build命令提供了一个更加清洁的上下文并且允许更快地构建镜像。否则,扫描带有多个文件的目录将不必要地减慢构建速度。

    参考文档:https://docs.docker.com/engine/reference/builder/#usage

  • 利用构建时缓存(build cache)

    Docker build构建镜像时会重复使用已经构建过的中间层作为缓存来加快构建过程。而Docker build构建时是按照Dockerfile顺序构建的,因此需要将不经常变化的生成层的命令放在前面,把经常变化的生成层的命令放在后面。

    参考文档:https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache

让镜像变得”好用“

Why?

好用的镜像,造就好用的容器。好用的容器是指可以使用Docker 标准命令前后台运行,传入运行时环境变量控制容器行为,传入运行命令替换缺省命令,优雅的停止,方便查看日志和进入容器内部调试。

How?

让构建镜像变得”省事、省心“

Why?

Dockerfile越复杂,越容易出错;Dockerfile有问题,运行的容器会有安全隐患。

How?

  • 选择高级别基础镜像

    尽量使用高级别基础镜像来简化编写Dockerfile的工作,比如为Java应用容器化使用openjdk基础镜像,而不是从alpine 操作系统基础镜像开始构建。

  • 保持Dockerfile尽可能简单

    参考Docker官方和其它一些好的开源软件的Dockerfile,让Dockerfile尽量保持简单,可读。

  • 使用经过安全扫描的基础镜像

    经过安全扫描的基础镜像,可以让容器运行在一个安全的环境。

FAQ

Q: ARGENV 命令的区别。

A: ARG 支持在构建镜像时(build-time)修改参数的值,比如docker build --build-arg var=xxx

ENV 支持在运行容器时(run-time) 修改参数的值,比如docker run -e var=yyy

Q: ADDCOPY 命令的区别。

A: 推荐使用COPY命令。

Q: Docker build的cache问题。

A: ADDCOPY 命令利用cksum来检查同名文件是否存在在缓存中,但是对cksum的计算不包括last-modified time和last-accessed time,有可能导致缓存机制失效。如果你的应用每次都基于一个同名文件,需要注意这个问题。

https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache

Q: RUN , CMDENTRYPOINT的区别。

A: RUN 命令是在docker build 构建时被执行,在容器运行时不会被执行。

CMDENTRYPOINT 命令是在docker run 运行容器时被执行,在容器构建时不会被执行。

Docker缺省的ENTRYPOINT是/bin/sh -c

参考文档

猜你喜欢

转载自blog.csdn.net/nklinsirui/article/details/80967810