加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 服务器 > 系统 > 正文

四个超实用的 Docker 镜像构建方法

发布时间:2022-07-30 16:21:29 所属栏目:系统 来源:互联网
导读:最近做了一个好玩的工具,叫 xbin.io[1] 。其中有一项工作是为不同的工具来构建 Docker 镜像,让他们都运行在 Docker 中(实际上,是兼容 Docker image 的其他 sandbox 系统,没有直接用 Docker)。支持的工具越来越多,为了节省资源,Build 的 Docker image
  最近做了一个好玩的工具,叫 xbin.io[1]  。其中有一项工作是为不同的工具来构建 Docker 镜像,让他们都运行在 Docker 中(实际上,是兼容 Docker image 的其他  sandbox 系统,没有直接用 Docker)。支持的工具越来越多,为了节省资源,Build 的 Docker image  就越小越好,文件越少,其实启动速度也会略微快一些,也会更安全一些。
 
 
  了解了原理之后,你会发现,这种设计对于 Docker 来说非常合适:
 
  如果 2 个 image 都是基于 Ubuntu,那么两个 Image 可以共用 Ubuntu 的 base image,只需要存储一份;
  如果 pull 新的 image,某一层如果已经存在,那么这一层之前的内容其实就不需要 pull 了;
  后面 build image 的技巧其实都是基于这两点。
 
  另外稍微提一下,Docker image 其实就是一个 tar 包[5]。一般来说我们通过 Dockerfile 用 docker built 命令来构建,但是其实也可以用其他工具构建,只要构建出来的 image 符合 Docker 的规范[6],就可以运行。比如,之前的博文 Build 一个最小的 Redis Docker Image[7] 就是用 Nix 构建出来的。
 
  技巧1:删除缓存
  一般的包管理器,比如 apt, pip 等,下载包的时候,都会下载缓存,下次安装同一个包的时候不必从网络上下载,直接使用缓存即可。
 
  但是在 Docker Image 中,我们是不需要这些缓存的。所以我们在 Dockerfile 中下载东西一般会使用这种命令:
 
  复制
  RUN dnf install -y --setopt=tsflags=nodocs
     httpd vim &&
   RUN dnf clean all
  1.
  2.
  3.
  4.
  Dockerfile 里面的每一个 RUN 都会创建一层新的 layer,如上所说,这样其实是创建了 3 层  layer,前 2 层带来了缓存,第三层删除了缓存。如同 git 一样,你在一个新的 commit 里面删除了之前的文件,其实文件还是在 git 历史中的,最终的 docker image 其实没有减少。
 
  但是 Docker 有了一个新的功能,docker build --squash。squash 功能会在 Docker 完成构建之后,将所有的 layers 压缩成一个 layer,也就是说,最终构建出来的 Docker image 只有一层。所以,如上在多个 RUN 中写 clean 命令,其实也可以。我不太喜欢这种方式,因为前文提到的,多个 image 共享 base image 以及加速 pull 的 feature 其实就用不到了。
 
  一些常见的包管理器删除缓存的方法:
 
 
  rvm cleanup all
 
  gem
 
  gem cleanup
 
  cpan
 
  rm -rf ~/.cpan/{build,sources}/*
 
  pip
 
  rm -rf ~/.cache/pip/*
 
  apt-get
 
  apt-get clean
 
  另外,上面这个命令其实还有一个缺点。因为我们在同一个 RUN 中写多行,不容易看出这个 dnf 到底安装了什么。而且,第一行和最后一行不一样,如果修改,diff 看到的会是两行内容,很不友好,容易出错。
 
  可以写成这种形式,比较清晰。
 
  复制
  RUN true
     && dnf install -y --setopt=tsflags=nodocs
         httpd vim
     && systemctl enable httpd
     && dnf clean all
     && true
  1.
  2.
  3.
  4.
  5.
  6.
  技巧2:改动不频繁的内容往前放
  通过前文介绍过的原理,可以知道,对于一个 Docker image 有 ABCD 四层,B 修改了,那么 BCD 会改变。
 
  根据这个原理,我们在构建的时候可以将系统依赖往前写,因为像 apt, dnf 这些安装的东西,是很少修改的。然后写应用的库依赖,比如 pip install,最后 copy 应用。
 
  比如下面这个 Dockerfile,就会在每次代码改变的时候都重新 Build 大部分 layers,即使只改了一个网页的标题。
 
  复制
  FROM python:3.7-buster
  # copy source
  RUN mkdir -p /opt/app
  COPY myapp /opt/app/myapp/
  WORKDIR /opt/app
  # install dependencies nginx
  RUN apt-get update && apt-get install nginx
  RUN pip install -r requirements.txt
  RUN chown -R www-data:www-data /opt/app
  # start server
  EXPOSE 8020
  STOPSIGNAL SIGTERM
  CMD ["/opt/app/start-server.sh"]
 
 
  我们可以改成,先安装 Nginx,再单独 copy requirements.txt,然后安装 pip 依赖,最后 copy 应用代码。
 
 
 
  复制
  FROM python:3.7-buster
  # install dependencies nginx
  RUN apt-get update && apt-get install nginx
   RUN chown -R www-data:www-data /opt/app
  # start server
  EXPOSE 8020
  STOPSIGNAL SIGTERM
  CMD ["/opt/app/start-server.sh"]

(编辑:应用网_丽江站长网)

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

    热点阅读