加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 服务器 > 搭建环境 > Windows > 正文

如何打造更小巧的容器镜像

发布时间:2019-03-28 20:35:56 所属栏目:Windows 来源:Chris Collins
导读:副标题#e# 五种优化 Linux 容器大小和构建更小的镜像的方法。 Docker 近几年的爆炸性发展让大家逐渐了解到容器和容器镜像的概念。尽管 Linux 容器技术在很早之前就已经出现,但这项技术近来的蓬勃发展却还是要归功于 Docker 对用户友好的命令行界面以及使用
副标题[/!--empirenews.page--]

如何打造更小巧的容器镜像

五种优化 Linux 容器大小和构建更小的镜像的方法。

Docker 近几年的爆炸性发展让大家逐渐了解到容器和容器镜像的概念。尽管 Linux 容器技术在很早之前就已经出现,但这项技术近来的蓬勃发展却还是要归功于 Docker 对用户友好的命令行界面以及使用 Dockerfile 格式轻松构建镜像的方式。纵然 Docker 大大降低了入门容器技术的难度,但构建一个兼具功能强大、体积小巧的容器镜像的过程中,有很多技巧需要了解。

第一步:清理不必要的文件

这一步和在普通服务器上清理文件没有太大的区别,而且要清理得更加仔细。一个小体积的容器镜像在传输方面有很大的优势,同时,在磁盘上存储不必要的数据的多个副本也是对资源的一种浪费。因此,这些技术对于容器来说应该比有大量专用内存的服务器更加需要。

清理容器镜像中的缓存文件可以有效缩小镜像体积。下面的对比是使用 dnf 安装 Nginx 构建的镜像,分别是清理和没有清理 yum 缓存文件的结果:

  1. # Dockerfile with cache
  2. FROM fedora:28
  3. LABEL maintainer Chris Collins <collins.christopher@gmail.com>
  4.  
  5. RUN dnf install -y nginx
  6.  
  7. -----
  8.  
  9. # Dockerfile w/o cache
  10. FROM fedora:28
  11. LABEL maintainer Chris Collins <collins.christopher@gmail.com>
  12.  
  13. RUN dnf install -y nginx
  14. && dnf clean all
  15. && rm -rf /var/cache/yum
  16.  
  17. -----
  18.  
  19. [chris@krang] $ docker build -t cache -f Dockerfile .
  20. [chris@krang] $ docker images --format "{{.Repository}}: {{.Size}}"
  21. | head -n 1
  22. cache: 464 MB
  23.  
  24. [chris@krang] $ docker build -t no-cache -f Dockerfile-wo-cache .
  25. [chris@krang] $ docker images --format "{{.Repository}}: {{.Size}}" | head -n 1
  26. no-cache: 271 MB

从上面的结果来看,清理缓存文件的效果相当显著。和清除了元数据和缓存文件的容器镜像相比,不清除的镜像体积接近前者的两倍。除此以外,包管理器缓存文件、Ruby gem 的临时文件、nodejs 缓存文件,甚至是下载的源码 tarball 最好都全部清理掉。

层:一个潜在的隐患

很不幸(当你往下读,你会发现这是不幸中的万幸),根据容器中的层的概念,不能简单地向 Dockerfile 中写一句 RUN rm -rf /var/cache/yum 就完事儿了。因为 Dockerfile 的每一条命令都以一个层的形式存储,并一层层地叠加。所以,如果你是这样写的:

  1. RUN dnf install -y nginx
  2. RUN dnf clean all
  3. RUN rm -rf /var/cache/yum

你的容器镜像就会包含三层,而 RUN dnf install -y nginx 这一层仍然会保留着那些缓存文件,然后在另外两层中被移除。但缓存实际上仍然是存在的,当你把一个文件系统挂载在另外一个文件系统之上时,文件仍然在那里,只不过你见不到也访问不到它们而已。

在上一节的示例中,你会看到正确的做法是将几条命令链接起来,在产生缓存文件的同一条 Dockerfile 指令里把缓存文件清理掉:

  1. RUN dnf install -y nginx
  2. && dnf clean all
  3. && rm -rf /var/cache/yum

这样就把几条命令连成了一条命令,在最终的镜像中只占用一个层。这样只会浪费一点缓存的好处,稍微多耗费一点点构建容器镜像的时间,但被清理掉的缓存文件就不会留存在最终的镜像中了。作为一个折衷方法,只需要把一些相关的命令(例如 yum installyum clean all、下载文件、解压文件、移除 tarball 等等)连接成一个命令,就可以在最终的容器镜像中节省出大量体积,你也能够利用 Docker 的缓存加快开发速度。

层还有一个更隐蔽的特性。每一层都记录了文件的更改,这里的更改并不仅仅已有的文件累加起来,而是包括文件属性在内的所有更改。因此即使是对文件使用了 chmod 操作也会被在新的层创建文件的副本。

下面是一次 docker images 命令的输出内容。其中容器镜像 layer_test_1 是在 CentOS 基础镜像中增加了一个 1GB 大小的文件后构建出来的镜像,而容器镜像 layer_test_2 是使用了 FROM layer_test_1 语句创建出来的,除了执行一条 chmod u+x 命令没有做任何改变。

  1. layer_test_2 latest e11b5e58e2fc 7 seconds ago 2.35 GB
  2. layer_test_1 latest 6eca792a4ebe 2 minutes ago 1.27 GB

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读