本文内容节选自 《containerd 原理剖析与实战》,本书正参加限时优惠内购,点击阅读原文,限时 69.9 元购买。
containerd 的整体架构
containerd 为典型的 C/S 架构,其中我们提到的 containerd 主要为 Server 端实现,架构图如下:
<p align=center>containerd API、Service、 MetaData 架构</p>
如图所示, containerd GRPC API、Service、 MetaData 为典型的 API 层、逻辑层、数据层架构。GRPC API 层为暴露服务的接口层,Service 层为具体的逻辑处理层,Metadata 为数据层,Service、 MetaData 两层为 Core 层。
MetaData
containerd 中的各个微服务插件的元数据都保存在 metadata 中,存储采用了 boltdb
开源数据库。
boltdb
是基于 Golang 实现的 KV 数据库。boltdb
提供最基本的存储功能,并不支持网络连接,不支持复杂的 SQL 查询。单个数据库数据存储在单个文件里,通过 API 的方式对数据文件读写,达到数据持久化的效果。bolt 通过嵌入在程序中进行使用,我们熟知的 ETCD 就是基于 boltdb
实现的。
containerd 通过 boltdb 对相关对象的的元数据进行存储,如 snapshots、image、container 等,同时 containerd 对 metadata 中的数据还会定期执行垃圾收集,用于自动清理过期不使用的资源。
containerd 中的对象在 boltdb
中保存格式如下。
<version>/<namespace>/<object>/<key> -> <field>
复制代码
其中:
<version>
: containerd 的版本,当前为 v1
<namespace>
: 对象所对应的 namespace
<object>
: 要保存在 boltdb 中的对象类型
<key>
: 用于指定特定对象的唯一值 containerd 中的 boltdb schema
数据结构可以参考 github.com/containerd/containerd/metadata/buckets.go
文件中的定义,如下。
└──v1 - Schema version bucket
├──version : <varint> - Latest version, see migrations
╘══*namespace*
├──labels
│ ╘══*key* : <string> - Label value
├──image
│ ╘══*image name*
│ ├──createdat : <binary time> - Created at
│ ├──updatedat : <binary time> - Updated at
│ ├──target
│ │ ├──digest : <digest> - Descriptor digest
│ │ ├──mediatype : <string> - Descriptor media type
│ │ └──size : <varint> - Descriptor size
│ └──labels
│ ╘══*key* : <string> - Label value
├──containers
│ ╘══*container id*
│ ├──createdat : <binary time> - Created at
│ ├──updatedat : <binary time> - Updated at
│ ├──spec : <binary> - Proto marshaled spec
│ ├──image : <string> - Image name
│ ├──snapshotter : <string> - Snapshotter name
│ ├──snapshotKey : <string> - Snapshot key
│ ├──runtime
│ │ ├──name : <string> - Runtime name
│ │ └──options : <binary> - Proto marshaled options
│ ├──extensions
│ │ ╘══*name* : <binary> - Proto marshaled extension
│ └──labels
│ ╘══*key* : <string> - Label value
├──snapshots
│ ╘══*snapshotter*
│ ╘══*snapshot key*
│ ├──name : <string> - Snapshot name in backend
│ ├──createdat : <binary time> - Created at
│ ├──updatedat : <binary time> - Updated at
│ ├──parent : <string> - Parent snapshot name
│ ├──children
│ │ ╘══*snapshot key* : <nil> - Child snapshot reference
│ └──labels
│ ╘══*key* : <string> - Label value
├──content
│ ├──blob
│ │ ╘══*blob digest*
│ │ ├──createdat : <binary time> - Created at
│ │ ├──updatedat : <binary time> - Updated at
│ │ ├──size : <varint> - Blob size
│ │ └──labels
│ │ ╘══*key* : <string> - Label value
│ └──ingests
│ ╘══*ingest reference*
│ ├──ref : <string> - Ingest reference in backend
│ ├──expireat : <binary time> - Time to expire ingest
│ └──expected : <digest> - Expected commit digest
├──sandboxes
│ ╘══*sandbox id*
│ ├──createdat : <binary time> - Created at
│ ├──updatedat : <binary time> - Updated at
│ ├──spec : <binary> - Proto marshaled spec
│ ├──runtime
│ │ ├──name : <string> - Runtime name
│ │ └──options : <binary> - Proto marshaled options
│ ├──extensions
│ │ ╘══*name* : <binary> - Proto marshaled extension
│ └──labels
│ ╘══*key* : <string> - Label value
└──leases
╘══*lease id*
├──createdat : <binary time> - Created at
├──labels
│ ╘══*key* : <string> - Label value
├──snapshots
│ ╘══*snapshotter*
│ ╘══*snapshot key* : <nil> - Snapshot reference
├──content
│ ╘══*blob digest* : <nil> - Content blob reference
└─────ingests
╘══*ingest reference* : <nil> - Content ingest reference
复制代码
可以看到 metadata
中保存了诸如 images
、containers
、snapshots
、content
、leases
等对象的基本信息。metadata 在宿主机上保存的路径为 /var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db
可以通过 boltbrowser
查看 boltdb
中的内容,操作如下。
1. 首先停止 containerd
通过 systemctl
来停止 containerd,命令如下。
systemctl stop containerd
2. 安装 boltbrowser
通过下面的命令下载并安装 boltbrowser,boltbrowser 是一款开源的 boltdb
数据库浏览器。
git clone https://github.com/br0xen/boltbrowser.git
cd boltbrowser
go build
复制代码
3. 查看对应的 blotdb
通过 boltbrowser
指令查看 boltdb
数据库。
boltbrowser /var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db
复制代码
boltbrowser
是可视化的界面,可以通过上线移动光标选中对象,按 enter
进入查看或者关闭查看。下面的输出是光标指在 "containers"
时的界面:
boltbrowser: /var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db
========================================|=================================
- v1 | Path: v1 → default → containers
+ buildkit | Buckets: 23
- default | Pairs: 0
- containers |
+ 14f6ea28faa77d4db41088e1a7f1f4cc2a |
+ 272587a117b8d2f1cb87489a78325c3fd4 |
+ 534ccbb979222b85190c1c5e6108e71ee7 |
+ 57510ed4290ca701447ea6686339909d23 |
+ 5a4cedbad48ce3028ae14424c70b5a0d3b |
+ ... 省略部分容器 ...
+ busybox1 |
+ nginx_1 |
+ zjz |
+ content |
+ images |
+ leases |
+ snapshots |
+ docker |
+ k8s.io |
+ moby |
version: 06 |
复制代码
上述介绍了 containerd 是如何利用 bbolt 保存 metadata 的,作为 典型的 C/S 架构,containerd 还有 API 层、Core 层、Backend 层,详细的解读可以参考 《containerd 原理剖析与实战》这本书。
containerd 系列文章参考
【史上最全】带你全方位了解containerd 的几种插件扩展模式
了解 containerd 中的 snapshotter,先从 native 开始
一文了解 containerd 中的 snapshot
一文读懂 containerd 中的 NRI 机制
一文了解 containerd 中的镜像加解密
本文使用 文章同步助手 同步
评论