抛砖引玉

先说结论

  1. 以不变应万变

    • 善用 cache, 使用一个相对固定的 build 环境
    • 构建 自己的基础镜像
  2. 洁身自好

    • 保持 context 干净: .dockerignore
    • 镜像环境清理

你需要的了解的参考资料

  • docker storage driver: docs.docker.com/storage/sto…
  • dockerfile best practices: docs.docker.com/develop/dev…

为什么要优化镜像

  • 一个小镜像有什么好处: 分发更快,存储更少,加载更快。
  • 镜像臃肿带来了什么问题: 存储过多,分发更慢且浪费带宽更多。

镜像的构成

  • 俯瞰镜像: 就是一个删减版的操作系统。
  • 侧看镜像: 由一层层的 layer 堆叠而成

那么问题来了

  1. 是否层数少的镜像, 就是一个好镜像?
  2. 在企业应用中, 要怎么去规划和建设 CI中的镜像和构建 ?
  3. 带集群足够大, 节点足够多的时候, 要怎么快速分发这些镜像 ?

举个例子 docker build

  • Dockerfile v1
# v1
FROM nginx:1.15-alpineRUN echo "hello"

RUN echo "demo best practise"

ENTRYPOINT [ "/bin/sh" ]
复制代码
  • Dockerfile v2
# v2
FROM nginx:1.15-alpineRUN echo "hello"

RUN echo "demo best practise 02"

ENTRYPOINT [ "/bin/sh" ]
复制代码

1st build

全新构建

# docker build -t demo:0.0.1 .
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM nginx:1.15-alpine---> 9a2868cac230
Step 2/4 : RUN echo "hello"---> Running in d301b4b3ed55
hello
Removing intermediate container d301b4b3ed55---> 6dd2a7773bbc
Step 3/4 : RUN echo "demo best practise"---> Running in e3084037668e
demo best practise
Removing intermediate container e3084037668e---> 4588ecf9837a
Step 4/4 : ENTRYPOINT [ "/bin/sh" ]---> Running in d63f460347ff
Removing intermediate container d63f460347ff---> 77b52d828f21
Successfully built 77b52d828f21
Successfully tagged demo:0.0.1
复制代码

2nd build

Dockerfile 与 1st build 完全一致, 命令仅修改 build tag , 从 0.0.10.0.2

# docker build -t demo:0.0.2 .
Sending build context to Docker daemon  4.096kB
Step 1/4 : FROM nginx:1.15-alpine---> 9a2868cac230
Step 2/4 : RUN echo "hello"---> Using cache---> 6dd2a7773bbc
Step 3/4 : RUN echo "demo best practise"---> Using cache---> 4588ecf9837a
Step 4/4 : ENTRYPOINT [ "/bin/sh" ]---> Using cache---> 77b52d828f21
Successfully built 77b52d828f21
Successfully tagged demo:0.0.2
复制代码

可以看到,

  1. 每层 layer 都使用 cache (---> Using cache) ,并未重新构建。
  2. 我们可以通过 docker image ls |grep demo 看到, demo:0.0.1demo:0.0.2 的 layer hash 是相同。 所以从根本上来说, 这两个镜像就是同一个镜像,虽然都是 build 出来的。

3rd build

这次, 我们将第三层 RUN echo "demo best practise" 变更为 RUN echo "demo best practise 02"

docker build -t demo:0.0.3 .
Sending build context to Docker daemon  4.608kB
Step 1/4 : FROM nginx:1.15-alpine---> 9a2868cac230
Step 2/4 : RUN echo "hello"---> Using cache---> 6dd2a7773bbc
Step 3/4 : RUN echo "demo best practise 02"---> Running in c55f94e217bd
demo best practise 02
Removing intermediate container c55f94e217bd---> 46992ea04f49
Step 4/4 : ENTRYPOINT [ "/bin/sh" ]---> Running in f176830cf445
Removing intermediate container f176830cf445---> 2e2043b7f3cb
Successfully built 2e2043b7f3cb
Successfully tagged demo:0.0.3
复制代码

可以看到 ,

  1. 第二层仍然使用 cache
  2. 但是第三层已经生成了新的 hash 了
  3. 虽然第四层的操作没有变更,但是由于上层的镜像已经变化了,所以第四层本身也发生了变化。

注意: 每层在 build 的时候都是依赖于上册 ---> Running in f176830cf445

4th build

第四次构建, 这次使用 --no-cache 不使用缓存, 模拟在另一台电脑上进行 build 。

# docker build -t demo:0.0.4 --no-cache .
Sending build context to Docker daemon  5.632kB
Step 1/4 : FROM nginx:1.15-alpine---> 9a2868cac230
Step 2/4 : RUN echo "hello"---> Running in 7ecbed95c4cd
hello
Removing intermediate container 7ecbed95c4cd---> a1c998781f2e
Step 3/4 : RUN echo "demo best practise 02"---> Running in e90dae9440c2
demo best practise 02
Removing intermediate container e90dae9440c2---> 09bf3b4238b8
Step 4/4 : ENTRYPOINT [ "/bin/sh" ]---> Running in 2ec19670cb14
Removing intermediate container 2ec19670cb14---> 9a552fa08f73
Successfully built 9a552fa08f73
Successfully tagged demo:0.0.4
复制代码

可以看到,

  1. 虽然和 3rd build 使用的 Dockerfile 相同, 但由于没有缓存,每一层都是重新 build 的。
  2. 虽然 demo:0.0.3demo:0.0.4 在功能上是一致的。但是 他们的 layer 不同, 从根本上来说,他们是不同的镜像。

转载于:https://juejin.im/post/5c998af86fb9a070f84077c0

怎样去构建一个优质的Docker容器镜像相关推荐

  1. 程序员,如何逐步去构建一个大型网站系统,面试必问!!!

    往往程序员在面试的时候,公司的面试任职资格上,总有一个大型系统网站的开发经验,我们先来看看几张面试招聘信息截图....... 大型网站定义 首先我们要思考一个问题,什么样的网站才是大型网站,从网站的技 ...

  2. 【云原生】第四篇--Docker容器镜像介绍及应用

    Docker容器镜像介绍及应用 一.Docker容器镜像操作 1.1 查看本地容器镜像 1.1.1 使用docker images命令查看 1.1.2 使用docker image命令查看 1.1.3 ...

  3. Docker容器镜像安全最佳实践指南

    文章目录: 0x02 Docker 容器安全最佳实践 1.主机安全配置 1.1 更新docker到最新版本 1.2 为容器创建一个单独的分区 1.3 只有受信任的用户才能控制docker守护进程 1. ...

  4. Docker容器镜像

    一.Docker容器镜像操作 1.查看本地镜像 docker iamges docker iamges list 查看docker容器镜像本地存储位置 ls /var/lib/docker 2.搜索D ...

  5. 从零开始构建一个高可靠的RabbitMQ镜像集群

    从零开始构建一个高可靠的RabbitMQ镜像集群 1.集群环境节点规划如表所示: 1 集群构建 1.停止MQ服务,首先停止3个节点的服务的命令如下: service rabbitmq-server s ...

  6. 【云原生】第十二篇--docker容器镜像仓库Harbor部署

    docker容器镜像仓库Harbor部署 一.容器镜像加速器 1.1 获取阿里云容器镜像加速地址 1.2 配置docker daemon使用加速器 二.容器镜像仓库 2.1 docker hub 2. ...

  7. 【ORACLE】从安装ORACLE LINUX 8开始构建一个ORACLE21C的docker镜像

    前言 最近有不少ORACLE21C的特性想测试,但是它有些特性是基于ORACLE LINUX操作系统的,网上没搜到现成docker或者虚拟机镜像,而且oracle cloud免费的21c体验不对中国区 ...

  8. 容器云java开发_使用码云构建 Docker 容器镜像并部署到华为云

    华为公有云平台的容器镜像服务开放了对码云代码库的支持. 华为云平台的容器镜像服务(SWR),能够支持从源码到镜像.从镜像到应用的容器镜像全生命周期的管理服务,为用户提供简单易用.安全可靠的镜像管理功能 ...

  9. docker — 容器镜像

    目录 一.容器镜像结构 1.Linux 操作系统结构 2.容器镜像 3.base 镜像 4.容器镜像的分层结构 5.UnionFS 联合文件系统 6.容器 copy-on-write(写时复制) 特性 ...

最新文章

  1. C++游戏开发需要阅读的书籍
  2. org.activiti.engine.ActivitiException: Couldn't deserialize object in variable 'application'
  3. 漂流瓶 php,PHP实现的迷你漂流瓶
  4. vue 日期格式化返回指定个数月份_12、vue中日期格式化转换的函数
  5. java sipush_003-整型入栈指令(iconst、bipush、sipush、ldc)
  6. 推荐系统系列教程之十:协同过滤中的相似度计算方法有哪些?
  7. 特征抽取 PCA主成分分析
  8. 使用CoreTelephony获得SIM卡网络运营商名称
  9. 关于HTTPS的简要内容
  10. 数据库高级查询与性能优化1,开窗函数与子查询
  11. ASA上的NAT配置及互联网接入(动态NAT、动态PAT、静态NAT、静态PAT以及NAT豁免、使用思科TFTP服务器上传ASDM模块)
  12. http post java工具类_java实现Http post(参数json格式)、get 请求的HttpUtil工具类
  13. TM1620 led显示芯片用stm8来驱动
  14. 【论文笔记-01】Re-ranking Person Re-identification with k-reciprocal Encoding
  15. 【张朝阳的物理课笔记】 5. 波动方程,声音在空气中的传播速度
  16. 重磅!清华大学首个原创虚拟美女学生,“华智冰”唱歌好听到爆
  17. VsCode镜像下载(国内镜像源,高速秒下)
  18. 蓝桥杯-算法训练 印章
  19. Rust学习教程03 - 安装Rust环境
  20. 与其自怨自艾,不如夯实勤奋

热门文章

  1. Google金山词霸体验小记
  2. iptables的基本概念及数据报文在iptables中的流传过程
  3. 由浅入深CIL系列:4.抛砖引玉:使用CIL来分析string类型在.NET运算中的性能和避免装箱...
  4. Linux的DNS高速缓存
  5. From NSURLConnection to NSURLSession
  6. Java运行时出现”the serializable class drawline does not declare a static final serialversio”...
  7. [转]context-param和init-param区别 context-param和in...
  8. 最近安装了Netscape Navigator 9.0英文版,真好用!
  9. pdf页眉页脚设置步骤
  10. JAVA远程通信的几种选择(RPC,Webservice,RMI,JMS的区别)