docker 镜像结构原理

news2024/10/5 18:23:19

目录

参考文档:第八篇:Docker镜像结构原理_Linux运维开发的技术博客_51CTO博客

1、基础镜像 base

base 镜像有两层含义:

为什么我们的镜像文件比一般的软件小一些呢?

二、镜像的分层结构

问什么 Docker 镜像要采用这种分层结构呢?

这时可能就有人会问了:如果多个容器共享一份基础镜像,当某个容器修改了基础镜像的内容,比如 /etc 下的文件,这时其他容器的 /etc 是否也会被修改?

三、容器的可写层

镜像分层实验:


参考文档:第八篇:Docker镜像结构原理_Linux运维开发的技术博客_51CTO博客

镜像:是一个软件单元

镜像是各个不同的层组合而成的,镜像的分层思想

最底层是基础镜像 , base image

1、基础镜像 base

base 镜像有两层含义:

1. 不依赖其他镜像,从 scratch 构建。
2. 其他镜像可以之为基础进行扩展。

为什么我们的镜像文件比一般的软件小一些呢?

原因是镜像里的系统使用的是宿主机的内核,因此比较小,而基础镜像里一般有操作系统的库、运行环境、依赖软件等

因此使用docker pull centos下载最新版本的Centos镜像也就207M左右,而我们平时下载一个原生的centos镜像都是4G,对于 Docker 初学者都会有这个疑问。

下面来了解下Linux 操作系统由内核空间和用户空间组成,如下图所示

rootfs
内核空间是 kernel,Linux 刚启动时会加载 bootfs 文件系统,之后 bootfs 会被卸载掉。
用户空间的文件系统是 rootfs,包含我们熟悉的 /dev, /proc, /bin 等目录。
对于 base 镜像来说,底层直接用 Host 的 kernel,自己只需要提供 rootfs 就行了。
而对于一个精简的 OS,rootfs 可以很小,只需要包括最基本的命令、工具和程序库就可以了。相比其他 Linux 发行版,CentOS 的 rootfs 已经算臃肿的了,alpine 还不到 10MB。
我们平时安装的 CentOS 除了 rootfs 还会选装很多软件、服务、图形桌面等,需要好几个 GB 就不足为奇了。

rootfs  --》是容器内部的操作系统,镜像里的操作系统提供的

不同的镜像里有rootfs,包含的东西不一样

rootfs 加载完成后,容器里形成一个封闭的环境,类似于一个操作系统

rootfs 通常包含了操作系统核心文件,例如 /bin、/sbin、/etc 等目录和一些配置文件、设备文件等。它刚好能够满足 Linux 启动所需的最小要求,并支持基本的系统管理工具,如 init、udev、mount 等。它包括操作系统所需的主要文件和目录,可以被挂载作为根文件系统使用。

bootfs --》 容器启动的时候需要的内容,是linux kernel 提供了bootfs

bootfs 可以理解为 Linux 系统启动时所需要的文件和目录所在的文件系统,通常包括操作系统内核、引导程序、设备驱动等。也就是说,bootfs 是启动过程中所需的基本文件和目录的集合。

需要注意的是,bootfs 和 rootfs 的概念并不相同,bootfs 只是一个启动过程中所需文件和目录的集合,而 rootfs 则是整个根文件系统的代表,包含了所有文件和目录。

Docker 可以同时支持多种 Linux 镜像,模拟出多种操作系统环境。 

比如 Ubuntu 14.04 使用 upstart 管理服务,apt 管理软件包;而 CentOS 7 使用 systemd 和 yum。这些都是用户空间上的区别,Linux kernel 差别不大。

容器只能使用 Host 的 kernel,并且不能修改。所有容器都共用 host 的 kernel,在容器中没办法对 kernel 升级。如果容器对 kernel 版本有要求(比如应用只能在某个 kernel 版本下运行),则不建议用容器,这种场景虚拟机可能更合适。

二、镜像的分层结构

Docker 支持通过扩展现有镜像,创建新的镜像。
实际上,Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的。

比如我们现在构建一个新的镜像,Dockerfile 如下:

① 新镜像不再是从 scratch 开始,而是直接在 Debian base 镜像上构建。
② 安装 emacs 编辑器。
③ 安装 apache2。
④ 容器启动时运行 bash。

linux的开机启动流程:

        MBR --》GRUB --》 kernel --》systemd --》其他服务进程

kernel是宿主机的内核,加载一个容器,先加载kernel

        kernel --》bootfs --》加载镜像里rootfs --》容器里已经有一个操作系统 --》加载程序 --》容器成功启动好了

镜像的构建过程如图:

 

可以看到,新镜像是从 base 镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。 

问什么 Docker 镜像要采用这种分层结构呢?


最大的一个好处就是 - 共享资源。

比如:有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

这时可能就有人会问了:如果多个容器共享一份基础镜像,当某个容器修改了基础镜像的内容,比如 /etc 下的文件,这时其他容器的 /etc 是否也会被修改?


答案:不会!因为修改会被限制在单个容器内

三、容器的可写层

当容器启动时,一个新的可写层被加载到镜像的顶部。
这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。

所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中。
只有容器层是可写的,容器层下面的所有镜像层都是只读的。

下面我们深入讨论容器层的细节。
镜像层数量可能会很多,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层中有一个相同路径的文件,比如 /a,上层的 /a 会覆盖下层的 /a,也就是说用户只能访问到上层中的文件 /a。在容器层中,用户看到的是一个叠加之后的文件系统。

1.添加文件
在容器中创建文件时,新文件被添加到容器层中。
2. 读取文件
在容器中读取某个文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,打开并读入内存。
3. 修改文件
在容器中修改已存在的文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之。
4. 删除文件
在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作。

只有当需要修改时才复制一份数据,这种特性被称作 Copy-on-Write。可见,容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改。
这样就解释了我们前面提出的问题:容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享。

镜像分层实验:

撰写一个简单的镜像

[root@mysql mydocker]# vim Dockerfile
[root@mysql mydocker]# cat Dockerfile 
FROM centos:7
RUN yum install vim -y
RUN yum install net-tools tree -y
RUN mkdir /sc
RUN touch /sc/feng{1..10}.txt
RUN rm -rf /sc/feng1.txt
CMD ["/bin/bash"]
[root@mysql mydocker]# 
[root@mysql mydocker]# docker build -t sccentos:7.9 . 

 我们如何查看生成的镜像的层数呢,我们可以使用

docker images -a

我们创建一个容器调用这个镜像

但是这样运行的话,我们是放在后台运行 ,但是这样我们查看docker 进程的时候,并没有看到我创建的这个进程,原因是什么呢

 

因此我们不能在后端运行

如何让此容器一直运行呢,我们需要使用下如命令:

这样就能通过docker ps 查看到我们的容器了

下面我们将优化docker容器分层 

优化后Dockerfile文件

创建新的镜像 

[root@mysql mydocker]# docker build -t sccentos:8 . 

优化后的镜像可以看到明显的大小的区别

因此如何让你的镜像尽可能的小?

在镜像制作的过程中每执行一次RUN命令,镜像里就会多一些内容,镜像就会多大一些

镜像要加载到容器中去运行,一个容器对应一个进程,而进程是需要消耗cpu和内存的

因此我们在制作镜像的时候,我们需要避免使用多条RUN命令,可以使用&&符号代替

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/664534.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

org.yaml.snakeyaml.parser.ParserException: while parsing a block mapping

一、yml解析异常问题 今天启动某开源项目时,碰到一个问题org.yaml.snakeyaml.parser.ParserException: while parsing a block mapping 。 二、解决 2.1 修改项目目录下缩进格式 在项目下的nacos目录中application-common.yml 文件中修改缩进格式,每…

15个最好的性能测试工具(软件测试工程师必备)

在软件测试日常工作中,大家接触得比较多的性能测试工具有LoadRunner和Jmeter,这里整理了web应用程序性能和负载压力能力的最广泛使用的性能测试工具的综合列表。 这些负载测试工具将确保您的应用程序在高峰流量和极端压力条件下的性能。 该列表包括开源…

Spring Security OAuth2.0(五)-----OAuth2实现自定义统一认证登录页/自定义授权页/基于mysql存储数据

本次实例涉及三个项目 核心项目工程unify_authorization_server(认证授权登录) 资源服务器项目unify_resource_server 测试项目是前面几篇写的项目 这里没有改动直接用来测试实例项目 (一)unify_authorization_server pom相关依赖 我采用的是spring-bo…

Ngnix网站服务

Ngnix网站服务 Ngnix网站服务 一、Ngnix服务基础:1.Ngnix的基本概述:2.简述Nginx和Apache的差异:3.Nginx和Apache的优点:4.应用场景:5.扩展: 二、编译安装Ngnix服务:1.编译安装:2.常…

基于matlab使用自校准来适应阵列不确定性(附源码)

一、前言 此示例显示了基于约束优化过程的自校准过程。利用机会来源同时估计阵列形状的不确定性和来源方向。此示例需要优化工具箱。 理论上,可以设计一个完美的均匀线性阵列(ULA)来执行各种处理,例如波束成形或到达方向估计。通常…

玩转ChatGPT:回答审稿人问题

一、写在前面 前段时间一篇时间序列预测的文章返修,还挺幸运的,给了个小修。 不过问题也问得有点刁钻,应该是个行家。 想到手头有小Chat,打算使用TA来辅助我回答审稿人问题。 以下展示仅仅提供一个工作流和思路,具体…

好程序员:逼自己看完并学会,你的Java会很牛!

打算学java的伙伴们,如果你们很迷茫焦虑的话,不妨看看好程序员的建议。好程序员作为行内人告诉大家,零基础也是可以学java的,而且不仅可以学会,还可以学的很好,并且能找到工作。 Java学习路线规划&#xff…

Day22 实战篇 ——Jmeter性能测试实战——JMeter执行原理、Jmeter性能测试实战、下载使用PerfMon插件、 Grafana可视化展示

Day22 实战篇 ——Jmeter性能测试实战——JMeter执行原理、Jmeter性能测试实战、下载使用PerfMon插件、 Grafana可视化展示 文章目录 Day22 实战篇 ——Jmeter性能测试实战——JMeter执行原理、Jmeter性能测试实战、下载使用PerfMon插件、 Grafana可视化展示一、Jmeter执行原理…

高性能通信库——nanomsg(含交叉编译)

一、nanomsg介绍 NanoMsg是一个Socket的通讯库,使用C语言编写实现的,这样就可以适用于多种操作系统,而且几乎不需要什么依赖,可扩展并且能易于使用。Nanomsg提供了几种常见的通信模式 ( 也称为“可扩展性协议” &#…

Flutter 小技巧之 InkWell Ink 你了解多少

今天要介绍一个「陈年」小技巧,主要是关于 InkWell 的基础科普,InkWell 控件相信大家不会陌生, 作为 Flutter 开发中最常用的点击 Widget ,配合 Flutter 自带的 Material ,可以轻松实现带有水波纹等的点击效果。 而之所…

VSCode 安装配置教程详解包含c++环境配置方法

vscode安装教程及c环境配置详解 vscode下载安装下载C扩展插件VScode C环境配置配置环境变量检查 MinGW 安装配置编译器:配置构建任务检查是否安装了编译器配置完毕 vscode下载安装 地址:官网下载地址 直接打开下载好的.exe文件进行安装即可&#xff0…

如何使用 PowerPoint 2021 制作演示文稿?

软件安装:办公神器office2021安装教程,让你快速上手_正经人_____的博客-CSDN博客 引言 PowerPoint 是一款非常常用的演示文稿制作工具,它可以帮助您创建漂亮的幻灯片,展示您的想法和信息。如果您是 PowerPoint 的新手&#xff…

xx客滑块

xx客滑块 网址流程1、访问首页,得到网页源代码得到 sessionId2、生成dInfo参数(getInfoTp接口使用到),是AES 加密(不校验)3、访问 /captcha/getInfoTp 得到responseId (可以认为是图片id&#x…

上海细化“元宇宙”概念 落地场景仍待破局

日前,一份关于“元宇宙”更加具体的行动方案引发业内高度关注:上海发布《上海市“元宇宙”关键技术攻关行动方案(2023—2025年)》的通知。 这说明政府层面开始进一步细化,以更好推动‘元宇宙’产业的发展。” 主攻沉…

【强烈推荐】基于STM32的TFT-LCD各种显示实现(内容详尽含代码)

前言:TFT-LCD模块作为人们日常生活中常见屏幕类型之一,使用的受众面非常广阔。例如:显示各个传感器数值,显示精美界面,多级化菜单系统等等都不离不开他的身影。可以说学会TFT-LCD模块是嵌入式开发必须掌握的驱动开发技…

AOP切面记录日志

AOP切面记录日志 一、导包 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>二、写一个注解 /*** 用于切面记录日志用的注解&#xff0c;只能加在方法中使用* a…

让性能腾飞!亚马逊云科技的 Java 云端之旅

在上篇文章中&#xff0c;我们为大家介绍了亚马逊的 Java 生态及丰富的开发工具、框架。本文将分享亚马逊的 Java 架构、迁移途径&#xff0c;并分享一个具体实例&#xff0c;介绍如何使用机器学习来构建 Java 应用和提升 Java 性能。 亚马逊云科技开发者社区为开发者们提供全…

vulhub-structs2-S2-009 远程代码执行漏洞复现

漏洞描述 影响版本: 2.1.0 - 2.3.1.1 漏洞原理 Struts2对s2-003的修复方法是禁止#号&#xff0c;于是s2-005通过使用编码\u0023或\43来绕过&#xff1b;于是Struts2对s2-005的修复方法是禁止\等特殊符号&#xff0c;使用户不能提交反斜线。 但是&#xff0c;如果当前action…

Java---第三章(选择,循环,二重循环语句,输入,调试,标签)

Java---第三章 一 流程图二 选择结构简单的if-else嵌套的if-else多重if的选择语句&#xff08;else-if&#xff09;switch语句 二 输入验证三 程序调试四 循环结构while循环do-while循环for循环流程控制二重循环&#xff08;重点&#xff09; 五 标签 label&#xff08;标号&am…

代码随想录二刷day27 | 回溯之 39. 组合总和 40.组合总和II 131.分割回文串

day27 39. 组合总和回溯三部曲剪枝优化 40.组合总和II回溯三部曲 131.分割回文串回溯三部曲判断回文子串 39. 组合总和 题目链接 解题思路&#xff1a; 本题没有数量要求&#xff0c;可以无限重复&#xff0c;但是有总和的限制&#xff0c;所以间接的也是有个数的限制。 本题搜…