怎样去构建一个优质的Docker容器镜像
抛砖引玉
先说结论
以不变应万变
- 善用
cache
, 使用一个相对固定的build
环境 - 构建
自己的基础镜像
- 善用
洁身自好
- 保持
context
干净:.dockerignore
- 镜像环境清理
- 保持
你需要的了解的参考资料
docker storage driver
: docs.docker.com/storage/sto…dockerfile best practices
: docs.docker.com/develop/dev…
为什么要优化镜像
- 一个小镜像有什么好处: 分发更快,存储更少,加载更快。
- 镜像臃肿带来了什么问题: 存储过多,分发更慢且浪费带宽更多。
镜像的构成
- 俯瞰镜像: 就是一个删减版的操作系统。
- 侧看镜像: 由一层层的
layer
堆叠而成
那么问题来了
- 是否层数少的镜像, 就是一个好镜像?
- 在企业应用中, 要怎么去规划和建设
CI中的镜像和构建
? - 带集群足够大, 节点足够多的时候, 要怎么快速分发这些镜像 ?
举个例子 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.1
到 0.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
复制代码
可以看到,
- 每层 layer 都使用 cache (
---> Using cache
) ,并未重新构建。 - 我们可以通过
docker image ls |grep demo
看到,demo:0.0.1
与demo: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
复制代码
可以看到 ,
- 第二层仍然使用
cache
- 但是第三层已经生成了新的 hash 了
- 虽然第四层的操作没有变更,但是由于上层的镜像已经变化了,所以第四层本身也发生了变化。
注意: 每层在
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
复制代码
可以看到,
- 虽然和
3rd build
使用的Dockerfile
相同, 但由于没有缓存,每一层都是重新 build 的。 - 虽然
demo:0.0.3
和demo:0.0.4
在功能上是一致的。但是 他们的 layer 不同, 从根本上来说,他们是不同的镜像。
转载于:https://juejin.im/post/5c998af86fb9a070f84077c0
怎样去构建一个优质的Docker容器镜像相关推荐
- 程序员,如何逐步去构建一个大型网站系统,面试必问!!!
往往程序员在面试的时候,公司的面试任职资格上,总有一个大型系统网站的开发经验,我们先来看看几张面试招聘信息截图....... 大型网站定义 首先我们要思考一个问题,什么样的网站才是大型网站,从网站的技 ...
- 【云原生】第四篇--Docker容器镜像介绍及应用
Docker容器镜像介绍及应用 一.Docker容器镜像操作 1.1 查看本地容器镜像 1.1.1 使用docker images命令查看 1.1.2 使用docker image命令查看 1.1.3 ...
- Docker容器镜像安全最佳实践指南
文章目录: 0x02 Docker 容器安全最佳实践 1.主机安全配置 1.1 更新docker到最新版本 1.2 为容器创建一个单独的分区 1.3 只有受信任的用户才能控制docker守护进程 1. ...
- Docker容器镜像
一.Docker容器镜像操作 1.查看本地镜像 docker iamges docker iamges list 查看docker容器镜像本地存储位置 ls /var/lib/docker 2.搜索D ...
- 从零开始构建一个高可靠的RabbitMQ镜像集群
从零开始构建一个高可靠的RabbitMQ镜像集群 1.集群环境节点规划如表所示: 1 集群构建 1.停止MQ服务,首先停止3个节点的服务的命令如下: service rabbitmq-server s ...
- 【云原生】第十二篇--docker容器镜像仓库Harbor部署
docker容器镜像仓库Harbor部署 一.容器镜像加速器 1.1 获取阿里云容器镜像加速地址 1.2 配置docker daemon使用加速器 二.容器镜像仓库 2.1 docker hub 2. ...
- 【ORACLE】从安装ORACLE LINUX 8开始构建一个ORACLE21C的docker镜像
前言 最近有不少ORACLE21C的特性想测试,但是它有些特性是基于ORACLE LINUX操作系统的,网上没搜到现成docker或者虚拟机镜像,而且oracle cloud免费的21c体验不对中国区 ...
- 容器云java开发_使用码云构建 Docker 容器镜像并部署到华为云
华为公有云平台的容器镜像服务开放了对码云代码库的支持. 华为云平台的容器镜像服务(SWR),能够支持从源码到镜像.从镜像到应用的容器镜像全生命周期的管理服务,为用户提供简单易用.安全可靠的镜像管理功能 ...
- docker — 容器镜像
目录 一.容器镜像结构 1.Linux 操作系统结构 2.容器镜像 3.base 镜像 4.容器镜像的分层结构 5.UnionFS 联合文件系统 6.容器 copy-on-write(写时复制) 特性 ...
最新文章
- C++游戏开发需要阅读的书籍
- org.activiti.engine.ActivitiException: Couldn't deserialize object in variable 'application'
- 漂流瓶 php,PHP实现的迷你漂流瓶
- vue 日期格式化返回指定个数月份_12、vue中日期格式化转换的函数
- java sipush_003-整型入栈指令(iconst、bipush、sipush、ldc)
- 推荐系统系列教程之十:协同过滤中的相似度计算方法有哪些?
- 特征抽取 PCA主成分分析
- 使用CoreTelephony获得SIM卡网络运营商名称
- 关于HTTPS的简要内容
- 数据库高级查询与性能优化1,开窗函数与子查询
- ASA上的NAT配置及互联网接入(动态NAT、动态PAT、静态NAT、静态PAT以及NAT豁免、使用思科TFTP服务器上传ASDM模块)
- http post java工具类_java实现Http post(参数json格式)、get 请求的HttpUtil工具类
- TM1620 led显示芯片用stm8来驱动
- 【论文笔记-01】Re-ranking Person Re-identification with k-reciprocal Encoding
- 【张朝阳的物理课笔记】 5. 波动方程,声音在空气中的传播速度
- 重磅!清华大学首个原创虚拟美女学生,“华智冰”唱歌好听到爆
- VsCode镜像下载(国内镜像源,高速秒下)
- 蓝桥杯-算法训练 印章
- Rust学习教程03 - 安装Rust环境
- 与其自怨自艾,不如夯实勤奋
热门文章
- Google金山词霸体验小记
- iptables的基本概念及数据报文在iptables中的流传过程
- 由浅入深CIL系列:4.抛砖引玉:使用CIL来分析string类型在.NET运算中的性能和避免装箱...
- Linux的DNS高速缓存
- From NSURLConnection to NSURLSession
- Java运行时出现”the serializable class drawline does not declare a static final serialversio”...
- [转]context-param和init-param区别 context-param和in...
- 最近安装了Netscape Navigator 9.0英文版,真好用!
- pdf页眉页脚设置步骤
- JAVA远程通信的几种选择(RPC,Webservice,RMI,JMS的区别)