containerd容器存储探究

ContainerD 容器目录结构探究

启动容器

作为开始,我们需要去启动一个容器。

你可以通过命令行的方式来启动一个容器,例如:

ctr i pull docker.io/library/nginx:alpine
ctr c create docker.io/library/nginx:alpine nginx
ctr task start -d nginx

或者一步到位:

ctr run -d docker.io/library/nginx:alpine nginx

也可以通过编程的方式来启动

import (
  "context"

  "github.com/containerd/containerd"
  "github.com/containerd/containerd/cio"
  "github.com/containerd/containerd/namespaces"
)


func main() {
	client, err := containerd.New("/run/containerd/containerd.sock")
	defer client.Close()
    
    context = context.Background()
    // create a context for docker
    redis, err := client.NewContainer(context, "redis-master")
    defer redis.Delete(context)
    // create a new task
    task, err := redis.NewTask(context, cio.NewCreator(cio.WithStdio))
    defer task.Delete(context)

    // the task is now running and has a pid that can be used to setup networking
    // or other runtime settings outside of containerd
    pid := task.Pid()

    // start the redis-server process inside the container
    err := task.Start(context)

    // wait for the task to exit and get the exit status
    status, err := task.Wait(context)
}

相关概念

在 containerd 中,container 这个概念特指一个元数据对象。诸如OCI运行时规范、镜像、根文件系统和其他元数据等资源可以附加到一个 container上。例如:

redis, err := client.NewContainer(context, "redis-master",
	containerd.WithNewSnapshot("redis-rootfs", image),
	containerd.WithNewSpec(oci.WithImageConfig(image)),
)

要启动像 docker 那样的容器,在 containerd 中称为 task ,一个 task 就是对进程(容器就是一个进程)的封装。所以在上述代码中,我们都是对一个 task 来进行这么一个 创建/进入/暂停/删除 等操作。

在第二个参考资料中有人探讨了为何这么设计。

容器存储

containerd 有两个不同的存储路径,一个用来持久化,一个用来保存运行时状态。

root = "/var/lib/containerd"
state = "/run/containerd"

我们知道docker使用的是overlayfs2,那containerd呢?官网有这么一句话:

\(\text{containerd allows you to use overlay or snapshot filesystems with your containers. It comes with built-in support for overlayfs and btrfs.}\)

containerd 内置支持 overlayfs 和 btrfs ,overlayfs我们再熟悉不过了, btrfs 可能不太熟悉,不用慌,下面稍微介绍一下 btrfs。

我们现在安装linux系统时有时会让你选择文件系统例如 ext2/ext3/ext4 等,而 btrfs 被 ext4 的作者称赞且认为其是下一代linux标准文件系统。但是目前 btrfs 还是在开发中,生产环境中 btrfs 还是很少。

对于 overlayfs ,我们知道docker的容器分为 LowerDir 和 UpperDir ,LowerDir 为镜像层文件,UpperDir 为容器目录,合起来就是 MergeDir ,就是最终看到的容器目录。那 containerd 的 LowerDir 和 UpperDir 分别在哪呢?

root@aliyun:~# mount | grep /var/lib/containerd
overlay on /run/containerd/io.containerd.runtime.v2.task/default/nginx/rootfs type overlay (rw,relatime,lowerdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/7/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/6/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/5/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/4/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/3/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/2/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/1/fs,upperdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/8/fs,workdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/8/work,xino=off)

使用 mount 命令,他直接就给你显示了

参考资料

  1. https://icloudnative.io/posts/getting-started-with-containerd
  2. https://github.com/containerd/containerd/discussions/4458
  3. [https://github.com/containerd/containerd
  4. https://blog.frognew.com/2021/06/relearning-container-09.html
posted @ 2022-12-31 23:59  xDaniel  阅读(573)  评论(0编辑  收藏  举报