Docke基础之docker镜像存储

一、docker镜像存储分析

Docker 在管理镜像层元数据时采用的是从上至下 repository、image 和 layer 三个层次,分别对应存储库、镜像和层三个层面。

二、 repository

docker的仓库(Repository)是集中存放镜像的地方,我们可以分为公共和私有的,Docker为用户创建了一个仓库地址:https://hub.docker.com 我们可以在Docker的hub上创建自己的仓库,这里为Docker用户提供了很多现有的镜像资源,这些都是官方提供的资源库,如下图所示:
在这里插入图片描述
同时,我们还可以建立自己的私有仓库,私有仓库的建立主要将打包文件存放在本地。因此,仓库顾名思义就是存储镜像的地方,无论是公共仓库还是私有仓库都是为了存放打包好的镜像文件。

三、镜像文件(image)

说到镜像文件,我们就会想到window的镜像文件,这些文件基本上是以ISO为结尾的文件,这些文件内部集成了这个系统安装所需的所有文件。image目录下会根据底层存储驱动的类型进行分类,我们现在是overlay,在overlay目录下,有着以下的文件和目录:
1、distribution 目录
2、repositories.json 文件, 入口文件,imagedb 目录的索引
3、 imagedb 目录,Image数据库,从中获取一个镜像的config文件,根据这个文件计算出layerdb 目录中的信息
4、 layerdb 目录,记录着一个镜像的各个layer层信息,根据这可以获取到一个layer真正存储的物理目录
下面,我将详细介绍各个文件目录的功能及其作用
1、repositories.json 文件
repositories.json 文件是记录着目前系统中一共有几个镜像,镜像的tag,镜像ID等内容;repositories.json的文件格式如下:

{
    "Repositories": {
        "镜像1": {
           相关信息;
        }
        "镜像2": {
           相关信息;
        }
    }
}

2、imagedb 目录

  • content 目录,有个config文件记录着镜像详细信息
  • metadata 目录,查看命令如下:
tree /unix:///var/run/docker.sock/image/overlay/imagedb

Rootfs:代表一个Docker Container在启动时(而非运行后)其内部进程可见的文件系统视角,或者是Docker Container的根目录。容器中的进程对其只有只读的权限。其文件格式如下:

 "rootfs": {
        "编号": [
            相关配置信息;
        ],
        "类型": "层级"
    }

3、关于镜像ID的计算
假设计算dd6f76d9cc90f3ec2bded9e1c970bb6a8c5259e05401b52df42c997dec1e79be 文件内容的sha256编码即可得到镜像ID。其具体计算指令如下所示:

sha256sum ./dd6f76d9cc90f3ec2bded9e1c970bb6a8c5259e05401b52df42c997dec1e79be 

四、层级layer

在Docker中的镜像是由多个layer组成,多个文件之间有相互检验的部分。当启动docker服务时,对镜像文件的操作都会被记录下来。下面我将介绍层级的文件以及相关操作
1、layerdb 目录
目前只有两个目录:

  • sha256 目录: 存储layer信息;
  • tmp: 临时目录
    关于查看layerdb 目录文件结构命令如下:
tree /unix:///var/run/docker.sock/image/overlay/layerdb

2、计算一个镜像的所有层级ChainID
关于镜像的所有层级ChainID的计算,下面我简略介绍计算的过程:
1、根据镜像的rootfs信息,查看有多少个diff_ids值,如下所示:
2、 假设第一个 diff_id 值是0f5ff0cf6a1c53f94b15f03536c490040f233bc455f1232f54cc8eb344a3a368,那么该镜像的第一层的 ChainID 就是 0f5ff0cf6a1c53f94b15f03536c490040f233bc455f1232f54cc8eb344a3a368。
3、因此,第二个 diff_id 值是 f1c896f31e4935defe0f9714c011ee31b3179ac745a4ed04e07c2e6ef2a7c349,这里要分两步来进行计算。

  • 第一步,和前一个 ChainID 合并(前一层的ChainID + " " +本层的diff_id)
"sha256:0f5ff0cf6a1c53f94b15f03536c490040f233bc455f1232f54cc8eb344a3a368 sha256:f1c896f31e4935defe0f9714c011ee31b3179ac745a4ed04e07c2e6ef2a7c349"
  • 第二步,对合并后的值进行计算sha256编码得出ubuntu镜像第二层的 ChainID, 这里需要用"crypto/sha256"来进行计算。用sha256sum求与GO语言求得到的结果不一样,因为cat或echo会在字符串后加’\n’。
package main
import (
	sha256 "crypto/sha256"
	"fmt"
)
func main() {
	s := "sha256:0f5ff0cf6a1c53f94b15f03536c490040f233bc455f1232f54cc8eb344a3a368 sha256:f1c896f31e4935defe0f9714c011ee31b3179ac745a4ed04e07c2e6ef2a7c349"
	h := sha256.New()
	h.Write([]byte(s))
	bs := h.Sum(nil)
	fmt.Printf("%x", bs)
}
  • 输出内容如下,这就是ubuntu镜像的第二层
a25db7dbfd3205a483f67bfaa81de9924b6c687c4f1b3ccf6bd42da9bc7387ad

4、以此类推就可以计算出ubuntu镜像5个层级ChainID了。

3、通过ChainID找到真正的存储目录
以该layer的ChainID来作为目录的名字,具体查询指令如下:

pwd /unix:///var/run/docker.sock/image/overlay/layerdb/sha256/diff_id 值
ls

之后我们会得到一些字段,他们按照cache-id diff parent size tar-split.json.gz的顺序排列,其中:1.cache-id :记录着本层内容真正存储的位置;2.diff :本层的diff_id;3. size :本层的大小;4. tar-split.json.gz;5.parent : 上一层的ChainID,如果本层是一个镜像的第一层,不会有parent文件

最后根据cache-id来查找一层内容真正存储的地方,其具体指令如下:

pwd /unix:///var/run/docker.sock/overlay
ls

指令输入完毕,我们可以发现目录和cache-id的值都是一一对应的。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

绝域时空

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值