Docker(二):Docker image Docker Container

news2025/1/11 8:54:57

本文将介绍 Docker 映像和容器以及 docker 文件之间的差异与联系,本文还将解释如何以及何时使用它们。

什么是 Dockerfile?

它是一个简单的文本文件,包含命令或过程的集合。我们运行的这些命令和准则作用于配置为创建新的 Docker 镜像的基本镜像。Dockerfile 是 Docker 镜像的源代码。Dockerfile 是包含各种指令和配置的文本文件。Dockerfile 中的 FROM 命令标识要从中构建的基础镜像。运行 Docker run 命令时,Docker 将使用此文件生成镜像本身。Dockerfile 包含映像的创建说明。与仅保留二进制镜像相比,使用 Dockerfile 的好处是自动构建可确保您始终拥有最新版本。这在安全性方面是有利的,因为您不想安装任何不安全的应用程序。(这里只做简单介绍,详细简述会篇幅过长的)

什么是 Docker Image & Docker Container ?

Docker镜像是静态的、只读的模板,包含了运行应用所需的一切。Docker容器是基于这些镜像创建的运行实例,它们是动态的、可修改的。镜像用于分发应用,而容器用于运行应用。理解这两者的关系对于有效使用Docker至关重要。

关系类比:

  • Docker Image:想象Docker镜像就像一个蛋糕的食谱。它包含了所有制作蛋糕所需的原料和步骤,但它本身不是蛋糕。
  • Docker Container:如果把Docker镜像比作蛋糕的食谱,那么Docker容器就是根据这个食谱实际烘焙出来的蛋糕。

1. Docker Image

Docker镜像是一个轻量级、可执行的独立软件包,包含运行某个软件所需的所有内容。它包括代码、运行时环境、系统工具、系统库和设置。

  • 定义:Docker 镜像是一个只读的模板,包含了运行某个应用程序所需的所有文件、环境变量、配置等。镜像是静态的,不会改变。
  • 构建:镜像通常是通过一个名为 Dockerfile 的文件构建的。Dockerfile 包含了一系列指令,描述了如何构建这个镜像,包括从哪个基础镜像开始、需要安装哪些软件包、需要复制哪些文件等。
  • 存储和分发:镜像可以存储在 Docker 仓库中(如 Docker Hub),便于分发和共享。用户可以从公共或私有仓库中拉取镜像,用于创建容器。
  • 可共享:不同镜像可以共享基础层,节省空间
  • 可移植:可以在任何支持Docker的环境中运行

2. Docker Container

Docker容器是镜像的运行实例。它是从镜像创建的可运行进程。

  • 定义:Docker 容器是镜像的一个运行实例。容器是动态的,可以启动、停止、移动和删除。每个容器都是独立的,有自己的文件系统、网络接口和进程空间。
  • 启动和运行:容器是从镜像启动的。当你运行一个容器时,Docker 会从指定的镜像创建一个可写层,并在这个可写层上运行应用程序。
  • 可变性:容器是可变的,运行时的数据和状态会存储在容器的可写层中。如果需要保存容器的数据,可以将其提交为一个新的镜像,或者使用数据卷(volumes)。
  • 轻量级:启动快速,资源占用少
  • 可移植:可以在任何支持Docker的环境中启动

3. Docker Image & Docker Container 的关系

docker run: 命令会将 docker image作为容器运行。

a) 镜像是容器的基础:容器是基于镜像创建的运行实例。

b) 一对多关系:一个镜像可以创建多个容器。

c) 镜像是静态的,容器是动态的:镜像是只读的模板,而容器在运行时可以被修改。

d) 容器可以创建新镜像:通过对容器的修改,我们可以创建新的镜像。

生命周期

  • 镜像的生命周期:构建 -> 分发 -> 运行 -> 更新
  • 容器的生命周期:创建 -> 运行 -> 暂停 -> 恢复 -> 停止 -> 删除

使用场景

  • 镜像:用于分发和部署应用程序。开发人员创建镜像,然后将其推送到镜像仓库。
  • 容器:用于运行应用程序。运维人员从镜像仓库拉取镜像,然后启动容器来运行应用。

主要命令

  • 镜像相关:docker build, docker push, docker pull, docker images
  • 容器相关:docker run, docker start, docker stop, docker rm, docker ps

数据持久化

  • 镜像本身不存储数据。
  • 容器可以写入数据,但默认情况下,当容器被删除时,数据也会丢失。
  • 为了持久化数据,我们使用Docker卷(Volumes)或绑定挂载(Bind Mounts)。

Docker Image实现原理

1. 联合文件系统(UnionFS)

联合文件系统是一种分层、轻量级且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。

想象一下,你有几张透明的塑料片,每张上面画了不同的图案。当你把这些塑料片叠在一起时,你会看到一个完整的图像,这就是联合文件系统的基本原理。

2. Docker镜像加载原理

Docker镜像加载原理: Docker镜像是由多个只读层叠加而成的。在拉取镜像时,Docker会从Docker Registry中下载这些层,并将它们缓存在本地。当运行容器时,Docker会将这些只读层组合成一个可写的容器层。这种分层设计使得镜像更加高效和灵活,因为不同的层可以被共享和复用。

Docker镜像是基于联合文件系统的概念构建的。每个Docker镜像由一系列层(layers)组成,这些层是只读的。当我们运行一个容器时,Docker会加载这些层,并在最顶部添加一个可写层(容器层)。

让我们用一个例子来解释这个过程:

        bootfs (boot file system)

bootfs是启动文件系统的缩写。它包含了bootloader和kernel(内核)。这是系统启动时最先加载的部分。

主要特点:

  • bootfs负责引导系统启动
  • 在系统启动完成后,整个bootfs会被卸载,以释放内存
  • 所有的Docker镜像都共享同一个bootfs

想象bootfs就像电脑的BIOS和操作系统引导程序。它的工作是启动系统,然后就"功成身退"了。

rootfs (root file system)

rootfs是根文件系统的缩写。它包含了典型Linux系统中的/dev, /proc, /bin, /etc等目录和文件。

主要特点:

  • rootfs位于bootfs之上
  • 不同的Linux发行版,如Ubuntu, CentOS等,有不同的rootfs
  • 在Docker中,不同的镜像可能有不同的rootfs

将rootfs想象成你在安装完操作系统后看到的文件系统结构。它包含了操作系统运行所需的所有基本目录和文件。

3. 理解docker于虚拟机的优势

知道了这些概念就可以理解,为什么Docker容器比传统虚拟机启动更快、占用资源更少

  1. bootfs通常非常小,仅包含bootloader和kernel。
  2. 当容器启动时,bootfs被加载到内存中,然后kernel启动。
  3. Docker容器的rootfs默认是只读的。当创建一个容器时,会在rootfs上添加一个读写层。
  4. 镜像的分层结构:当Docker加载镜像时,它会从底层开始,逐层向上加载。每一层都只包含与上一层的差异部分。这种方法大大减少了存储空间的使用和镜像的传输时间。
  • 基础镜像(如Ubuntu)包含bootfs和该发行版特定的rootfs。
  • 在此基础上,每安装一个程序,就在上面添加一个新层。
  • 这种分层结构使得Docker可以:
    • 快速构建镜像(只需加载变化的部分)
    • 节省存储空间(相同的层可以被多个镜像共享)
    • 快速传输镜像(只需传输变化的层)
    • 示例:
      当你运行docker run命令时,Docker会执行以下步骤:
      
      a) 检查本地是否有该镜像。如果没有,就从Docker Hub或指定的registry下载。
      
      b) 创建一个新的容器。
      
      c) 为容器分配一个文件系统,并在镜像的最顶层添加一个可写层。
      
      d) 分配网络/桥接接口。
      
      e) 设置IP地址。
      
      f) 执行你在docker run命令中指定的程序。
      
      g) 捕获并返回应用程序的输出。

这种结构带来了几个重要优势:

  • 共享资源:多个容器可以共享同一个bootfs,节省了内存。
  • 快速启动:由于bootfs很小且共享,容器可以非常快速地启动。
  • 层级管理:每一层的变化都可以被单独管理,便于版本控制和回滚。

通过这种方式,Docker实现了高效的镜像管理和快速的容器启动。


分层理解(镜像层 & 容器层)

1. 容器读写层(Container read-write layer)

后续就叫容器层了方便理解。当你基于一个镜像启动一个容器时,Docker会在镜像的最顶层添加一个可写的容器层。

2. 镜像层 (Image Layers)

镜像层是构建Docker镜像的基础。每个镜像由多个只读层组成,这些层堆叠在一起形成最终的镜像。

3. 镜像层和容器层的关系

  • 镜像层提供了容器的基础文件系统。
  • 容器层允许对运行中的容器进行修改,而不影响底层的镜像。
  • 当需要修改一个文件时,Docker使用写时复制(Copy-on-Write)策略:
    1. 首先,Docker从镜像层复制文件到容器层。
    2. 然后,在容器层中进行修改。
    3. 后续的读取操作会从容器层获取修改后的文件。

4. Copy-on-Write 策略

这是Docker用来优化存储空间和提高性能的一种重要机制。

定义

Copy-on-Write是一种延迟复制的优化策略。当多个进程共享同一块数据时,如果某个进程需要进行修改,系统只有在真正写入时才会复制一份数据

5. 工作原理

  • 读取文件:如果文件存在于容器层,直接读取;如果不存在,则从镜像层读取。
  • 写入文件:如果文件不在容器层,Docker会将文件复制到容器层然后修改。如果文件已在容器层,直接在容器层修改。这就是"写时复制"的由来。
  • 删除文件:Docker在容器层创建一个特殊的删除标记,遮蔽下层的同名文件。

6. 优势

  • 空间效率:多个容器可以共享相同的底层镜像层,只存储差异部分。
  • 快速启动:创建新容器时,无需复制整个文件系统。启动新容器只需添加一个新的容器层,非常快速。
  • 性能优化:读操作性能良好,因为大多数文件不会被修改。
  • 增量更新:更新镜像只需要添加或替换特定的层。

7. 注意事项

  • 写操作可能会带来性能开销,特别是对大文件的首次写入。
  • 需要合理规划镜像层,以平衡层数和文件更新频率。过多的层可能会影响性能,因此在构建镜像时应该适当控制层数。
  • 容器层中的更改在容器被删除后就会消失。如果需要持久化数据,应该使用Docker卷(Volumes)。

杂项补充

Docker Commit

docker commit 命令会从一个运行中(或停止)的容器创建一个新的镜像。这个新镜像包含了原始镜像的内容,以及在容器中所做的所有更改。

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

常用选项包括:

  • -a, --author: 指定作者
  • -m, --message: 提交信息
  • -p, --pause: 在提交时暂停容器(默认行为)

使用场景

  • 开发过程中保存中间状态
  • 调试和故障排除
  • 创建自定义镜像
  • 将运行时配置保存到新镜像中

最佳实践

  • 优先使用 Dockerfile 来创建镜像
  • 仅在必要时使用 docker commit
  • 在提交前,停止容器并删除不必要的文件
  • 为新创建的镜像添加清晰的标签和描述

虽然 docker commit 是一个有用的工具,但在生产环境中,通常推荐使用 Dockerfile 来创建可重现的镜像构建过程。docker commit 主要用于开发、测试和调试阶段。

Docker Image Tags

使用镜像标签是 Docker 最佳实践的重要部分。它们帮助我们有效地管理镜像版本,便于回滚和部署特定版本的应用。通过合理使用标签,我们可以更好地控制应用的生命周期和版本历史。

标签的类型

  • 版本标签:如 v1.0, 2.1.3
  • 描述性标签:如 latest, stable, dev
  • 日期标签:如 20230701

相关命令

  • docker tag: 为镜像添加新标签
  • docker rmi: 删除镜像(可以指定标签)
  • docker inspect: 查看镜像详细信息
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

docker rmi [OPTIONS] IMAGE [IMAGE...]

docker inspect [OPTIONS] NAME|ID [NAME|ID...]

Docker ID

理解和正确使用 Docker ID 对于有效管理 Docker 环境、确保操作的精确性和提高工作流程的自动化程度非常重要。无论是在开发、测试还是生产环境中,熟练运用 Docker ID 都能帮助您更好地控制和管理 Docker 资源。

Docker ID 主要指两个概念:

a) 用户账户标识符:用于 Docker Hub 和其他 Docker 服务的唯一用户标识。

b) 容器或镜像的唯一标识符:用于在本地 Docker 环境中标识特定的容器或镜像。

Docker 用户账户 ID

  • 这是您在 Docker Hub 注册时创建的唯一用户名。
  • 用于登录 Docker Hub、拉取私有镜像、推送镜像等操作。

容器 ID

  • 每个 Docker 容器都有一个唯一的 ID。
  • 通常是一个长的十六进制字符串。
  • 也有短 ID,是完整 ID 的前 12 个字符。

        容器管理

docker start 1234abcd
docker stop 1234abcd
docker restart 1234abcd
docker rm 1234abcd
docker logs 1234abcd

镜像 ID

  • 每个 Docker 镜像也有一个唯一的 ID。
  • 同样是一个长的十六进制字符串,也有短 ID 版本。

        镜像管理

删除镜像:docker rmi 5678efgh

基于特定镜像创建容器:docker run -d 5678efgh

参考

https://cto.ai/blog/docker-image-vs-container-vs-dockerfile/

https://docs.docker.com/build/guide/layers/

18、镜像原理之联合文件系统_哔哩哔哩_bilibili

19、镜像原理之分层理解_哔哩哔哩_bilibili

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

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

相关文章

【linux学习---1】点亮一个LED---驱动一个GPIO

文章目录 1、原理图找对应引脚2、IO复用3、IO配置4、GPIO配置5、GPIO时钟使能6、总结 1、原理图找对应引脚 从上图 可以看出, 蜂鸣器 接到了 BEEP 上, BEEP 就是 GPIO5_IO05 2、IO复用 查找IMX6UL参考手册 和 STM32一样,如果某个 IO 要作为…

[不可抗拒的吸引]韩漫日漫无删减完整版,免费在线观看漫画

[不可抗拒的吸引]韩漫日漫无删减完整版,免费在线观看漫画 不能多说,怕审-核不过,自己看图吧。 食用方法: https://blog.csdn.net/qq_42098517/article/details/140079915 https://gitee.com/zzwuweijun/manhua/blob/master/READ…

入门Axure:快速掌握原型设计技能

2002 年,维克托和马丁在旧金山湾区的一家初创公司工作,发现自己一再被软件开发生命周期的限制所困扰,而且产品团队在编写规范之前很难评估他们的解决方案,开发人员经常不理解(或不阅读)给出的规范&#xff…

springboot城市菜园共享系统00524

目 录 摘要 1 绪论 1.1 研究背景与意义 1.2 国内外研究现状和发展趋势 1.3论文结构与章节安排 2 城市菜园共享系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.…

Guitar Pro怎么把和弦图放在谱子上方 Guitar Pro怎么设置和弦

在音乐中,和弦是音乐的基本单位。而吉他和弦是指在吉他上按压弦与弹奏弦的组合,我们可以在乐谱中通过和弦图来表现吉他的按压点位,以及弹奏的弦。下面我们看看Guitar Pro怎么把和弦图放在谱子上方,Guitar Pro怎么设置和弦的相关内…

Python+pytest接口自动化之token关联登录的实现

在PC端登录公司的后台管理系统或在手机上登录某个APP时,经常会发现登录成功后,返回参数中会包含token,它的值为一段较长的字符串,而后续去请求的请求头中都需要带上这个token作为参数,否则就提示需要先登录。 这其实就…

【Python】从文本字符串中提取数字、电话号码、日期、网址的方法汇总(全!)

我们在做数据清洗的时候,有时候会遇到将一堆文本中提取我们需要的内容,最常见的是,从一大段文本中提取出数字、电话号码、日期、网址等。而在Python中,正则表达式re,则可以满足我们从文本中提取数字、电话号码和日期等…

测试Andrew NG的语言翻译Agent

我正在测试 Andrew Ng 的语言翻译 A​​I 代理系统及其在逆变换下的稳定性。 给定源语言的文本,我们应用翻译函数 f,然后应用 f 的逆。它应该是不变的: 但是,数学与语言翻译有什么关系? 在完美的系统中,从…

德翔海运核心盈利指标大幅下滑,大额分红56亿不缺钱仍募资补流

《港湾商业观察》黄懿 5月30日,航运公司德翔海运(TS Lines,下称“德翔海运”)再一次向港交所递交招股书,计划在主板挂牌上市,由摩根大通和招商证券国际担任联席保荐人。 据悉,2022年至2023年&…

【js】数组元素拼接、数组元素类型转换

一、数组元素拼接 二、数组元素类型转换 1、字符串数组 转换成 数字型数组 [1, 2, 3].map(Number) // [1,2,3] 2、数字型数组 转换成 字符串数组 [1, 2, 3].map(String) // [1, 2, 3]

Java语法 小白入门参考资料 数组

数组的基本概念 数组:可以看成是相同类型元素的一个集合。在内存中是一段连续的空间。 比如现实中的车库: 在java中,包含6个整形类型元素的数组,就相当于上图中连在一起的6个车位,从上图中可以看到: 数组…

【C++】开源:量化金融计算库QuantLib配置与使用

😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍量化交易库QuantLib配置与使用。 无专精则不能成,无涉猎则不能通。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下&#…

【linux】网络基础(3)——tcp协议

文章目录 TCP协议概括TCP头部格式TCP连接管理建立连接(三次握手)数据传输确认应答机制捎带应答 滑动窗口丢包问题 拥塞控制延时应达 终止连接(四次挥手) TCP协议概括 TCP是一个面向连接的协议,在传输数据之前需要建立连…

Zabbix 配置进程监控

Zabbix 进程监控介绍 Zabbix可以很方便地监控服务器上的各种进程。在使用Zabbix进行进程监控时,被监控的节点通常需要安装Zabbix Agent。Zabbix Agent 是一个轻量级的代理程序,安装在被监控的主机上,用于收集系统的各种性能数据和指标&#…

OpenBMB × Hugging Face × THUNLP,大模型课开班丨伙伴活动推荐

2022 年,OpenBMB 开源社区联合 THUNLP 开国内大模型公开课先河,全网百万级播放量,已帮助无数大模型爱好者从入门到精通。 这个夏天,OpenBMB 携手 HuggingFace、THUNLP 和面壁智能,推出大模型公开课第二季。全球知名开…

vue实现一个简单的审批绘制功能

1、vue代码 <div class"approval"><div class"approval_ul" v-for"(item,key) in approvalList" :key"key"><div><el-radio-group v-model"item.jointlySign"><el-radio label"1">…

人大出品!最适合大模型初学者人手的LLM大语言模型综述,爆火全网

今天给大家推荐一本大模型&#xff08;LLM&#xff09;这块的一本外文书&#xff0c;经过整理已经出中文版了&#xff0c;就是这本《大型语言模型综述》&#xff01;本书在git上有9.2k star&#xff0c;还是很不错的一本大模型方面的书。 本教程内容主要内容&#xff1a;中文版…

外挂级OCR神器:免费文档解析、表格识别、手写识别、古籍识别、PDF转Word

智能文档解析&#xff1a;大模型友好的文档解析工具 PDF转Markdown 支持将任意格式的文件&#xff08;图片、PDF、Doc&#xff0f;Docx、网页等&#xff09;解析为Markdown或Json格式&#xff0c;以对LLM友好的方式呈现。 更高速度&#xff1a;100页PDF最快1.5s完成解析 更大…

Qt/C++编写地图应用/离线地图下载/路径规划/轨迹回放/海量点/坐标转换

一、前言说明 这个地图组件写了很多年了&#xff0c;最初设计的比较粗糙&#xff0c;最开始只是为了满足项目需要&#xff0c;并没有考虑太多拓展性&#xff0c;比如最初都是按照百度地图写死在代码中&#xff0c;经过这几年大量的现场实际应用&#xff0c;以及大量的用户提出…

1.7-自然语言的分布式表示-skip-gram模型代码实现

文章目录 1 skip-gram模型的实现1.1模型结构的实现1.2前向传播的实现1.3反向传播的实现 2 skip-gram模型的计算与学习3总结 书上提供了skip-gram模型的代码实现&#xff0c;但是没有去讲解&#xff1b;这里我们自己来看看他提供的代码&#xff1b;看代码的时候&#xff0c;尤其…