containerd源码-snapshots
snapshots主要负责存储解压层之后的存储
代码版本为v.17.5
snapshot和content的结构类似,其接口定义如下
接口定义
1 | // snapshots/snapshotter.go |
snapshot grpc类型
- 注册插件,他依赖于service类型,同样实现了Register方法调用了grpc进行api注册服务
1 | // services/snapshots/service.go |
- snapshot的service有个map,因为snapshotter有很多实现,比如默认的
overlayfs
还有devmapper
等
1 | type service struct { |
- 我们看下其中一个api的实现,主要是处理grpc的请求和响应操作,需要注意的是传入的参数中有
Snapshotter
id,然后执行对应的snap的api,后面就到了service层处理
1 | func (s *service) Prepare(ctx context.Context, pr *snapshotsapi.PrepareSnapshotRequest) (*snapshotsapi.PrepareSnapshotResponse, error) { |
snapshot service类型
- 依赖MetadataPlugin类型吗,调用
db.Snapshotters()
拿到snap,meterdata里通过NewDB()传值
1 | func init() { |
- 实际调用了metedata的
Prepare()
,这里进行了大量的数据库操作
1 | func (s *snapshotter) Prepare(ctx context.Context, key, parent string, opts ...snapshots.Opt) ([]mount.Mount, error) { |
- 这可以可以看到prepare和view实现都是一样的只不过view是只读的
- 源码很长这里不放了,其主要在数据存记录snap相关信息
- 随后调用真正的snap实现
1 | // containerd/metadata/snapshot.go |
snapshot类型
- 直接返回了
overlay.NewSnapshotter()
1 | // snapshots/overlay/plugin/plugin.go |
- New函数中依然执行opt相关的操作,然后创建了目录随后创建数据库文件到这个目录中,注意这个数据库不metedata的数据库而是snap自己的数据库
- 读取了一些overlay相关参数
1 | // snapshots/overlay/overlay.go |
- 和前面调用的PrePare结构很相似,也只是传递的是否只读不一样
1 | func (o *snapshotter) Prepare(ctx context.Context, key, parent string, opts ...snapshots.Opt) ([]mount.Mount, error) { |
- 首先创建一个临时目录然后数据中创建snap记录,如果有parent则修改guid,然后修改名字为正式的snap目录
- 最后通过mount函数返回
1 | // snapshots/overlay/overlay.go |
- mount函数根据snapshotter的ParentIDs来判断是否返回读写的bind类型挂载
- 通过判断是否是active来返回只读的bind类型挂载
- 最后通过ParentIDs组合overlay的参数
1 | // snapshots/overlay/overlay.go |
bind mount
- bind的mount类型是linux内核实现的一种挂载他和链接(
link
)实现的功能很像,但是他实现更底层在vfs之下 - 参数rbind表示目录下的目录递归挂载到而不是这是这个一个,
- ro则表示只读
- bind相当于修改了文件的inode到挂载的目录上
1 | mkdir test1 test2 |
参考
https://blog.csdn.net/weixin_40864891/article/details/107330218