首页 > 其他分享 >Docker 镜像的分层概念

Docker 镜像的分层概念

时间:2024-09-07 15:25:08浏览次数:11  
标签:容器 complete 文件系统 vim 分层 镜像 Docker

40.镜像的分层概念

来更深入地理解镜像的概念

镜像的分层

镜像,是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是 image 镜像文件。

只有通过这个镜像文件才能生成 Docker 容器实例(类似 Java 中 new 出来一个对象)。

那什么是分层呢?先来看一个现象,在下载 Tomcat 镜像的时候,好像是在一层一层的在下载:

$ docker pull tomcat
Using default tag: latest
latest: Pulling from library/tomcat
0e29546d541c: Pull complete 
9b829c73b52b: Pull complete 
cb5b7ae36172: Pull complete 
6494e4811622: Pull complete 
668f6fcc5fa5: Pull complete 
dc120c3e0290: Pull complete 
8f7c0eebb7b1: Downloading [=======================>                           ]  96.69MB/203.1MB
77b694f83996: Download complete 
0f611256ec3a: Download complete 
4f25def12f23: Download complete 

这是因为镜像文件,是分层的,基于 UnionFS。

UnionFS(联合文件系统):Union 文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像,类似 Java 中的 Object 类,是所有类的父类),可以制作各种具体的应用镜像。

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

镜像加载原理

镜像实际上由一层一层的文件系统组成,这种层级的文件系统 UnionFS。

bootfs(boot file system)主要包含 bootloader 和 kernel,bootloader 主要是引导加载 kernel,Linux 刚启动时会加载 bootfs 文件系统,在 Docker 镜像的最底层是引导文件系统 bootfs。这一层与我们典型的 Linux/Unix 系统是一样的,包含 boot 加载器和内核。当 boot 加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs 转交给内核,此时系统也会卸载 bootfs。

rootfs(root file system), 在 bootfs 之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs 就是各种不同的操作系统发行版,比如 Ubuntu,Centos 等等。

平时我们安装进虚拟机的 CentOS 都是好几个 G,为什么 docker 这里才 200M?

对于一个精简的 OS,rootfs 可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用 Host 的 kernel,自己只需要提供 rootfs 就行了。由此可见对于不同的 linux 发行版,bootfs 基本是一致的,rootfs 会有差别,因此不同的发行版可以公用 bootfs。

比如,启动一个 Ubuntu,进入到容器后,会发现 vim 等工具都是没有的

为什么要用分层结构

镜像分层最大的一个好处就是共享资源,方便复制迁移,就是为了复用。

比如说有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;

同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

例如,想要在一个 Ubuntu 镜像上添加一个 vim 功能,作为一个新的镜像,此时就用 Ubuntu 镜像上添加 vim 即可,不用自己从头搭建一个镜像。

重点理解:Docker 镜像层都是只读的,容器层是可写的。当容器启动时,一个新的可写层被加载到镜像的顶部。 这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。

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

Docker 镜像 commit 操作案例

接下来我们试着给 Ubuntu 添加 vim 功能,然后封装其为一个新的镜像。此时就可以用都 Docker 的 commit 命令,格式:

docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]

先启动一个 Ubuntu,然后安装 vim(安装时间可能会比较久):

$ docker run -it ubuntu
$ apt-get update
$ apt-get -y install vim

安装 vim 后,退出 Ubuntu,然后根据命令格式使用 docker commit,使之成为一个新镜像:

$ docker ps -a
CONTAINER ID   IMAGE     COMMAND  CREATED          STATUS       
b76722ca3c37   ubuntu    "bash"  18 minutes ago   Exited (0) 21 seconds ago 

$ docker commit -m="add vim" -a="peterjxl"  b76722ca3c37 peterjxl/myubuntu:1.1

可以看到新镜像比原本的 Ubuntu 大了不少:

$ docker images
REPOSITORY          TAG       IMAGE ID       CREATED         SIZE
peterjxl/myubuntu   1.1       0d0cf3b0417f   6 seconds ago   187MB
ubuntu              latest    ba6acccedd29   22 months ago   72.8MB

并且使用该镜像创建一个该容器,也能有 vim 命令:

$ docker run -it 0d0cf3b0417f

$ vim -version
VIM - Vi IMproved 8.1 (2018 May 18, compiled Aug 18 2023 03:41:54)
Garbage after option argument: "-version"
More info with: "vim -h"

总结

Docker 中的镜像分层,支持通过扩展现有镜像,创建新的镜像。类似 Java 继承于一个 Base 基础类,自己再按需扩展。

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

——完——

标签:容器,complete,文件系统,vim,分层,镜像,Docker
From: https://www.cnblogs.com/PeterJXL/p/18401721

相关文章

  • 使用docker-compose部署wordpress
    前期工作请参考我写的这篇文章docker-compose轻松部署jenkins1、创建项目目录[root@docker~]#mkdir-p/compose/wordpress2、yaml文件内容version:'3'services:mysql:image:mysql:5.7ports:-"3306:3306"environment:-"MYSQL_ROOT_......
  • docker开发环境迅速搭建
    官网下载dockerWindows上安装需要开启cpu的虚拟化,windows程序中开启多项功能1.进入bios开启cpu虚拟化1.2开启windows的服务1.3由于伟大祖国的政策,我们无法直接获取docker源镜像,需要配置阿里的镜像加速二.安装mysqldockerpullmysql:8.02.dockerrun-p3306:3306--......
  • python镜像库替换为国内镜像
    全局生效,而非单个项目!!windows系统使用命令:type%USERPROFILE%\pip\pip.ini查看是否有pip.ini文件,没有的话创建该文件,可以在C:\Users\username下使用notepad++等编辑pip.ini文件,添加下面代码:[global]index-url=https://mirrors.aliyun.com/pypi/simple/[install]trust......
  • 推荐5个可以免费使用GPT的镜像站
    1.Kimi链接:点击直达Kimi由月之暗面科技有限公司(MoonshotAI)开发,擅长中英文对话,能够提供安全、有帮助、准确的回答。2.灵办AI链接:点击直达免费一键改写润色爆款文案,总结文档内容,同时集对话、翻译、写作、搜索于一身的神器3.智能小G链接:点击直达“智能小G”是基......
  • 【第96课】云原生篇&Docker安全&系统内核&版本漏洞&CDK自动利用&容器逃逸
    免责声明本文发布的工具和脚本,仅用作测试和学习研究,禁止用于商业用途,不能保证其合法性,准确性,完整性和有效性,请根据情况自行判断。如果任何单位或个人认为该项目的脚本可能涉嫌侵犯其权利,则应及时通知并提供身份证明,所有权证明,我们将在收到认证文件后删除相关内容。文中所涉......
  • Docker安装zookeeper(zookeeper-latest)与Kafka(kafka-latest)
    一、Docker安装zookeeper1.准备工作(1)进入文件夹dockercd/usr/local/docker/(2)创建一个网络#app-tier:网络名称#–driver:网络类型为bridgedockernetworkcreateapp-kafka--driverbridge(3)在docker创建zookeeper文件夹//创建文件夹mkdirzookeeper//进入cd......
  • Ubuntu系统Docker中使用Anaconda环境运行Python项目方法
    宝藏网站:菜鸟教程-学的不仅是技术,更是梦想!安装Anaconda的镜像我是直接拉取的Anaconda的镜像,我不会dockerfile自己构建镜像。以下终端命令查找Anaconda的官方的一些镜像,拉取自己是想要的镜像。dockersearchanaconda#拉取镜像命令dockerpull(镜像名字)#查看Docker......
  • docker 安装 redis 集群
    集群搭建(三主三从)集群搭建集群中的节点都需要打开两个TCP连接。一个连接用于正常的给Client提供服务,比如6379,还有一个额外的端口(通过在这个端口号上加10000)作为数据端口,例如:redis的端口为6379,那么另外一个需要开通的端口是:6379+10000,即需要开启16379。16379端口用于......
  • 【K8s】专题十三:Kubernetes 容器运行时之 Docker 与 Containerd 详解
    本文内容均来自个人笔记并重新梳理,如有错误欢迎指正!如果对您有帮助,烦请点赞、关注、转发、订阅专栏!专栏订阅入口Linux专栏 | Docker专栏 | Kubernetes专栏往期精彩文章【Docker】(全网首发)KylinV10下MySQL容器内存占用异常的解决方法【Docker】(全网首发)Kyli......
  • Docker的镜像设置
    一、启动hello-world二、查看镜像dockerimages三、设置docker镜像地址打开阿里云网址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrorsbash执行这段命令sudomkdir-p/etc/dockersudotee/etc/docker/daemon.json<<-'EOF'{"registry-mirrors":[&qu......