利用Docker分层构建优化镜像大小
合适docker镜像文件大小不仅影响容器启动效率,也影响资源占用效率。本文介绍如何利用分层方式构建docker镜像,采用多种方式避免镜像文件太大而影响性能。
Docker 镜像大小优化的重要性
-
资源利用效率
较小的镜像文件在存储和传输过程中占用更少的空间和带宽。例如,在将镜像从本地仓库推送到远程仓库或者在集群环境中分发镜像时,小镜像可以加快传输速度,减少网络资源的占用。
当在主机上存储大量镜像时,较小的镜像可以节省磁盘空间,使得可以在有限的磁盘容量下存储更多的镜像,这对于容器编排系统(如 Kubernetes)管理大量不同的容器镜像非常重要。
-
容器启动速度
小镜像启动速度通常更快。因为在容器启动时,需要将镜像中的文件系统加载到容器的存储层,如果镜像文件较小,那么加载的时间和资源消耗会相应减少,从而提高容器的启动效率。
分层构建镜像的原理和优势
-
原理
Docker 镜像是由多层文件系统叠加而成的。每一层都代表了一次对文件系统的修改,例如安装软件包、添加配置文件等操作。当构建镜像时,Docker 会将这些操作按顺序记录下来,形成一个分层的结构。
例如,基础镜像(如
ubuntu:latest)是最底层,然后在其上添加新的层,如安装nginx软件包会形成一个新的层,修改nginx的配置文件又会形成另外一层。

-
优势对镜像大小的影响
复用已有层:分层构建最大的优势之一是可以复用层。如果多个镜像都基于相同的基础镜像,并且在基础镜像之上的某些层是相同的(例如都安装了相同的系统库),那么这些相同的层在存储时只会保存一份。
例如,有镜像 A 和镜像 B 都基于
ubuntu:latest构建,并且都安装了python3 - pip包,那么这个python3 - pip安装层只会在存储中保存一次,多个镜像可以共享该层。这样可以大大减少镜像存储所需的空间总量。增量构建和更新:当需要更新镜像中的某一部分时,只需要更新对应的层。例如,如果只是更新了应用程序的代码而没有改变基础操作系统或其他依赖库,那么只有包含代码的层会被更新,其他层可以保持不变。这使得更新镜像时的数据传输量最小化,有助于保持镜像大小的合理性。
分层构建镜像的最佳实践
-
合理选择基础镜像
基础镜像的大小对最终镜像大小有很大影响。尽量选择轻量级的基础镜像。例如,对于基于 Linux 的应用程序,如果不需要完整的 Ubuntu 或 CentOS 系统的所有功能,可以选择
alpine作为基础镜像。alpine是一个轻量级的 Linux 发行版,其镜像大小通常只有几兆字节,相比完整的 Ubuntu 或 CentOS 镜像(可能几百兆字节)要小很多。例如,构建一个简单的 Python Web 应用容器,使用
python:alpine作为基础镜像会比使用python:ubuntu产生更小的镜像。 -
合并多层操作(减少层数)
虽然分层有很多优势,但过多的层也可能导致一些问题,如镜像存储和传输效率下降。在构建镜像过程中,可以将一些相关的操作合并到同一层中。
例如,在安装多个软件包时,可以在一个
RUN指令中完成,而不是为每个软件包安装使用一个单独的RUN指令。比如在Dockerfile中,不要这样写:
RUN apt - get updateRUN apt - get install - y package1RUN apt - get install - y package2
应该这样写:
RUN apt - get update && apt - get install - y package1 package2
这样可以减少镜像的层数,因为每一个RUN指令都会产生一个新的层。
- 清理无用文件和缓存
在构建镜像过程中,安装软件包或编译程序等操作可能会产生一些临时文件和缓存。这些文件会增加镜像的大小,但在容器运行时可能并不需要。
例如,在apt - get安装软件包后,可以使用apt - get clean命令清理软件包缓存。在构建基于 Java 的应用程序镜像时,编译后的字节码文件可能不需要包含源代码文件,那么可以在构建过程中删除源代码文件。在Dockerfile中可以这样写:
RUN apt - get update && apt - get install - y package && apt - get clean
或者在构建 Java 应用程序镜像时:
# 假设编译后的代码在/target目录,源代码在/src目录COPY. /appWORKDIR /appRUN mvn clean install - DskipTestsRUN rm - rf /app/src
通过分层构建镜像并结合上述最佳实践,可以有效地控制 Docker 镜像的大小,提高镜像的存储和使用效率。
- 多阶段构建
原理:多阶段构建允许将构建过程分为多个阶段,每个阶段可以使用不同的基础镜像和构建工具。在前面的阶段可以进行代码编译、测试等操作,在后面的阶段只复制运行时需要的文件,从而减少最终镜像的大小。
示例:以一个 Go 语言应用为例,第一阶段可以使用包含 Go 编译器的基础镜像来编译应用程序,第二阶段可以使用一个轻量级的alpine基础镜像来运行编译后的程序。
# 第一阶段:构建应用FROM golang:1.18 - alpine AS builderCOPY. /appWORKDIR /appRUN go build - o myapp# 第二阶段:运行应用FROM alpine:latestCOPY -- from = builder /app/myapp /usr/local/bin/myappCMD ["myapp"]
在这个例子中,第一阶段构建出了 Go 应用,第二阶段只复制了运行时需要的可执行文件myapp到一个轻量级的alpine镜像中,最终的镜像不包含 Go 编译器和其他构建过程中产生的不必要的文件,大大减小了镜像大小。
相关文章:
利用Docker分层构建优化镜像大小
合适docker镜像文件大小不仅影响容器启动效率,也影响资源占用效率。本文介绍如何利用分层方式构建docker镜像,采用多种方式避免镜像文件太大而影响性能。 Docker 镜像大小优化的重要性 资源利用效率 较小的镜像文件在存储和传输过程中占用更少的空间和带…...
Spring 魔法探秘:从 Bean 线程安全到事务魔法全解析
1.Spring 框架中的单例 Bean 是线程安全的么? Spring 框架中的单例 Bean 本身并不保证线程安全性。单例模式意味着在整个应用程序的生命周期中,只会创建该 Bean 的一个实例,并且所有对该 Bean 的请求都将共享这个实例。 线程安全与否取决于…...
[Maven]IDEA父工程创建子工程后父工程不可运行
IDEA在使用maven构建项目时,如果你在当前工程下创建一个子工程,那么原有的工程(变为父工程的工程)原有的代码通常会变得不可运行。 这是因为,使用maven创建父子工程关系后,IDEA会自动变更项目的模块相关配置。 比如这是我maven工程…...
【系统移植】在开发板上加载内核和根文件系统的三种方法
实现环境:ubuntu24.04和FS4412实验平台。 要在开发板上运行linux操作系统,首先要将linux内核镜像(uImage)、设备树(dexynos4412-fs4412.dtb)和根文件系统镜像(ramdisk.img)加载到开发板内存。有以下几种方式加载: 一、通过tftp加载内核和根文件系统 二、通过EMMC加…...
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍02-基于错误消息的SQL注入(Error-Based SQL Injection)
免责声明 本教程仅为合法的教学目的而准备,严禁用于任何形式的违法犯罪活动及其他商业行为,在使用本教程前,您应确保该行为符合当地的法律法规,继续阅读即表示您需自行承担所有操作的后果,如有异议,请立即停…...
数据结构-排序(来自于王道)
排序的基本概念 插入排序 在这个算法中,除了输入的数组本身,没有使用额外的数据结构来存储数据,所有的操作都是在原数组上进行的。因此,无论输入数组的大小 n 是多少,算法执行过程中所占用的额外空间是固定的ÿ…...
【蓝桥杯选拔赛真题93】Scratch青蛙过河 第十五届蓝桥杯scratch图形化编程 少儿编程创意编程选拔赛真题解析
目录 Scratch青蛙过河 一、题目要求 编程实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 1、思路分析 2、详细过程 四、程序编写 五、考点分析 六、推荐资料 1、入门基础 2、蓝桥杯比赛 3、考级资料 4、视频课程 5、python资料 Scr…...
ReactPress最佳实践—搭建导航网站实战
Github项目地址:https://github.com/fecommunity/easy-blog 欢迎Star。 近期,阮一峰在科技爱好者周刊第 325 期中推荐了一款开源工具——ReactPress,ReactPress一个基于 Next.js 的博客和 CMS 系统,可查看 demo站点。(…...
Hive-4.0.1数据库搭建(可选配置用户名密码远程连接)
1.官网下载tar包上传到服务器并解压(我这里解压到了hive目录): 2.进入到conf目录,并复制模板配置文件进行修改: cd /apache-hive-4.0.1-bin/conf cp hive-default.xml.template hive-site.xml3.编写内容如下: <property>&…...
P8772 求和 P8716 回文日期
文章目录 [蓝桥杯 2022 省 A] 求和[蓝桥杯 2020 省 AB2] 回文日期 [蓝桥杯 2022 省 A] 求和 题目描述 给定 n n n 个整数 a 1 , a 2 , ⋯ , a n a_{1}, a_{2}, \cdots, a_{n} a1,a2,⋯,an, 求它们两两相乘再相加的和,即 S a 1 ⋅ a 2 a 1 ⋅ a 3 ⋯ a…...
MySQL迁移SQLite
将 MySQL 的表结构和数据迁移到 SQLite,可以通过以下步骤实现。这个过程主要包括导出 MySQL 数据库到 SQL 文件,然后将其导入到 SQLite 数据库中。 步骤 1: 导出 MySQL 数据库 首先,需要将 MySQL 数据库导出为一个 SQL 文件。可以使用 mysq…...
RocketMQ中的顺序消息和乱序消息详解
内容编辑中… 1.背景 顺序消息是消息队列 RocketMQ 提供的一种高级消息类型。 对于一个指定的Topic,消息严格按照先进先出(FIFO)的原则进行消息发布和消费。 即先发送的消息先消费,后发送的消息后消费。 顺序消息在发送、存储和投递的处理过程中,强调多条消息间的先后…...
Unity UGUI图片循环列表插件
效果展示: 下载链接:https://gf.bilibili.com/item/detail/1111843026 概述: LoopListView2 是一个与 UGUI ScrollRect 相同的游戏对象的组件。它可以帮助 UGUI ScrollRect 以高效率和节省内存的方式支持任意数量的项目。 对于具有10,000个…...
Kafka系列教程 - Kafka 生产者 -2
1. 生产者简介 不管是把 Kafka 作为消息队列系统、还是数据存储平台,总是需要一个可以向 Kafka 写入数据的生产者和一个可以从 Kafka 读取数据的消费者,或者是一个兼具两种角色的应用程序。 使用 Kafka 的场景很多,诉求也各有不同ÿ…...
AI Chat API 对接说明
AI Chat API 对接说明 我们知道,市面上一些问答 API 的对接还是相对没那么容易的,比如说 OpenAI 的 Chat Completions API,它有一个 messages 字段,如果要完成连续对话,需要我们把所有的上下文历史全部传递࿰…...
Thread线程基础使用
多线程目的:其实就是希望“并行”执行多任务,提升效率。 单核多线程基于时间片轮询 并发而非并行 线程最大数等于cpu核心数为佳 namespace thinger.ThreadDemo {class Program{//主线程static void Main(string[] args){Console.WriteLine("这个…...
【Linux】结构化命令
结构化命令structured command:允许脚本根据条件跳过部分命令,改变执行流程。 1、if-then语句 格式1: if command then commands fi 格式2: if command; then commands fi 运行if之后的command命令,如果它的退出状态码…...
ElasticSearch01-概述
零、文章目录 ElasticSearch01-概述 1、Elastic Stack (1)简介 官网地址:https://www.elastic.co/cn/ELK是一个免费开源的日志分析架构技术栈总称,包含三大基础组件,分别是Elasticsearch、Logstash、Kibana。但实际…...
docker xxxx is using its referenced image ea06665f255d
Error response from daemon: conflict: unable to remove repository reference “registrxxxxxx” (must force) - container 9642fd1fd4a0 is using its referenced image ea06665f255d 这个错误表明你尝试删除的镜像正在被一个容器使用,因此无法删除。要解决这…...
Vue 2 中 v-text 和 v-html 指令的使用详解
目录 Vue 2 中 v-text 和 v-html 指令的使用详解 v-text 指令 简介 基本语法 示例 1:基础用法 特点 v-html 指令 简介 基本语法 示例 2:基础用法 注意事项 区别与选择指南 何时使用 最佳实践 Vue 2 中 v-text 和 v-html 指令的使用详解 V…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
软件工程 期末复习
瀑布模型:计划 螺旋模型:风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合:模块内部功能紧密 模块之间依赖程度小 高内聚:指的是一个模块内部的功能应该紧密相关。换句话说,一个模块应当只实现单一的功能…...
