Docker(二):Docker image Docker Container

本文将介绍 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.mfbz.cn/a/777714.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

G1.【C语言】EasyX初步了解

1.介绍 EasyX 是针对 C/C 的图形库,可以帮助使用C/C语言的程序员快速上手图形和游戏编程。 2.安装 EasyX Graphics Library for CEasyX Graphics Library 是针对 Visual C 的绘图库,支持 VC6.0 ~ VC2019,简单易用,学习成本极低…

轻预压:滚珠丝杆精度与刚性的平衡点!

预压是指在所需的工作负荷下,使滚珠丝杆预先承受一定的负荷,从而使滚珠丝杆的轴向向心度和侧向偏差达到较小的偏差范围,保证了滚珠丝杆的准确性和稳定性,也确保机器的高精度和长期运作的可靠性。 预压是滚珠丝杆设计中的一个重要参…

vue3项目图片压缩+rem+自动重启等plugin使用与打包配置

一、Svg配置 每次引入一张 SVG 图片都需要写一次相对路径,并且对 SVG 图片进行压缩优化也不够方便。 vite-svg-loader插件加载SVG文件作为Vue组件,使用SVGO进行优化。 插件网站https://www.npmjs.com/package/vite-svg-loader 1. 安装 pnpm i vite-svg…

智能与伦理:Kimi与学术道德的和谐共舞

学境思源,一键生成论文初稿: AcademicIdeas - 学境思源AI论文写作 Kimi,由月之暗面科技有限公司开发的智能助手,擅长中英文对话,能处理多种文档和网页内容。在论文写作中,Kimi可提供资料查询、信息整理、语…

JavaWeb--jquery篇

概述 jQuery是一个快速、简洁的JavaScript框架,是一个优秀的JavaScript代码库(框架)于2006年1月由John Resig发布。它封装JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作、事件处理、动…

Faster-RCNN·代码解读系列01:Selective Search 和 R-CNN、Fast-CNN 简介

Selective Search 和 R-CNN、Fast-CNN 简介 1 目标检测算法简介1.0滑窗法的思路1.1 Selective Search 和 R-CNN 简介1.2.1 Selective Search简介1.1.1 Selective Search的思路1.1.2 Selective Search图解 1.2 Selective Search 和 Fast-CNN简介1.2.1 SPP和ROI Pooling简介1.2.2…

高级计算机体系结构--期末教材复习

Chap2 性能评测和并行编程性能评测并行编程为什么需要三次 barrier改进方法 Chap3 互连网络交换和路由二维网格中 XY 路由 死锁、活锁及饿死死锁避免的方法:虚通道、转弯模型二维网格中最小 西向优先、北向最后和负向优先算法转弯模型:超立方体的部分自适…

原生JavaScript实现录屏功能

1. 前言 使用JavaScript实现浏览器中打开系统录屏功能 示例图: 2. 源码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><…

深度学习——卷积神经网络(convolutional neural network)CNN详解(一)——概述. 步骤清晰0基础可看

在CNN的学习过程中我会提供相应的手算例子帮助理解训练过程。 其他关于神经网络的学习链接如下&#xff1a; 一、了解卷积神经网络 卷积神经网络的作用 总的来说&#xff0c;卷积神经网络的第一个主要作用是对图像进行特征提取&#xff0c;所谓特征提取&#xff0c;就是明白…

7.6第三天作业

一、在数据库中创建一个表student&#xff0c;用于存储学生信息 CREATE TABLE student( id INT PRIMARY KEY, name VARCHAR(20) NOT NULL, grade FLOAT ); &#xff08;1.&#xff09;先创建一个数据库 &#xff08;2.&#xff09;创建student表 查看是否创建成功 1、向studen…

QT c++函数模板与类模板的使用

QT c类模板的使用 #pragma once#include <QtWidgets/QMainWindow> #include "ui_QtWidgetsApplication5.h"class QtWidgetsApplication5 : public QMainWindow {Q_OBJECTpublic:QtWidgetsApplication5(QWidget *parent nullptr);~QtWidgetsApplication5();te…

代码随想录算法训练营第13天|二叉树的递归遍历、二叉树的迭代遍历、二叉树的统一迭代法、102.二叉树的层序遍历

打卡Day13 1.理论基础2.二叉树的递归遍历3.二叉树的迭代遍历3.二叉树的统一迭代法4.102.二叉树的层序遍历扩展107. 二叉树的层序遍历 II199.二叉树的右视图637.二叉树的层平均值429.N叉树的层序遍历515.在每个树行中找最大值116.填充每个节点的下一个右侧节点指针117. 填充每个…

嵌入式C语言面试相关知识——关键字(不定期更新)

嵌入式C语言面试相关知识——关键字 一、博客声明二、C语言关键字1、sizeof关键字2、static关键字3、const关键字4、volatile关键字5、extern关键字 一、博客声明 又是一年一度的秋招&#xff0c;怎么能只刷笔试题目呢&#xff0c;面试题目也得看&#xff0c;想当好厂的牛马其实…

数据可视化之智慧城市的脉动与洞察

在数字化转型的浪潮中,城市作为社会经济发展的核心单元,正经历着前所未有的变革。城市数据可视化大屏看板作为这一变革中的重要工具,不仅极大地提升了城市管理效率,还为公众提供了直观、全面的城市运行状态视图,成为智慧城市建设不可或缺的一部分。本文将深入探讨以“城市…

一文理解 Treelite,Treelite 为决策树集成模型的部署和推理提供了高效、灵活的解决方案

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、什么是 Treelite&#xff1f; Treelite 是一个专门用于将决策树集成模型高效部署到生产环境中的机器学习模型编译器&#xff0c;特别适合处理大批量数据的推理任务&#xff0c;能够显著提升推理性能…

Java之网络面试经典题(一)

目录 ​编辑 一.Session和cookie Cookie Session 二.HTTP和HTTPS的区别 三.浅谈HTTPS为什么是安全的&#xff1f; 四.TCP和UDP 五.GET和Post的区别 六.forward 和 redirect 的区别&#xff1f; 本专栏全是博主自己收集的面试题&#xff0c;仅可参考&#xff0c;不能相…

嵌入式Linux系统编程 — 7.2 进程的环境变量

目录 1 什么是进程的环境变量 2 环境变量的作用 3 应用程序中获取环境变量 3.1 environ全局变量 3.2 获取指定环境变量 getenv 4 添加/删除/修改环境变量 4.1 putenv()函数添加环境变量 4.2 setenv()函数 4.3 unsetenv()函数 1 什么是进程的环境变量 每一个进程都有一…

Android - Json/Gson

Json数据解析 json对象&#xff1a;花括号开头和结尾&#xff0c;中间是键值对形式————”属性”:属性值”” json数组&#xff1a;中括号里放置 json 数组&#xff0c;里面是多个json对象或者数字等 JSONObject 利用 JSONObject 解析 1.创建 JSONObject 对象&#xff0c;传…

快手大模型首次集体亮相,用AI重塑内容与商业生态

7月6日&#xff0c;在2024世界人工智能大会期间&#xff0c;快手举办了以“新AI新应用新生态”为主题的大模型论坛&#xff0c;会上&#xff0c;快手大模型首次集体亮相&#xff0c;视频生成大模型可灵、图像生成大模型可图等产品的多项新功能正式发布。 继图生视频、视频续写…

Appium启动APP时报错Security exception: Permission Denial

报错内容Security exception: Permission Denial: starting Intent 直接通过am命令尝试也是同样的报错 查阅资料了解到&#xff1a;android:exported | App quality | Android Developers exported属性默认false&#xff0c;所以android:exported"false"修改为t…