Containerd初体验

一、Containerd概述

1.什么是Containerd

        Containerd(container Daemon)是一个开源的容器运行时,它提供了一种标准化的方式来管理容器的生命周期。该项目最初是由 Docker 开发团队创建的,并在后来成为一个独立的项目,被纳入了 cloudNative computing Foundation(云原生计算基金会 CNCF)的孵化项目中。

        以下是 containerd 的主要特点和功能:

  • 容器生命周期管理:(Containerd 管理容器的生命周期,包括容器的创建、运行、暂停、恢复、停止和销毁等操作。
  • 标准化接口: Containerd 提供了一个标准化的容器运行时接口,使得它可以与多个容器编排系统和工具集成,例如 Kubernetes、Docker compose 等。
  • 镜像管理: 它支持容器镜像的拉取、推送、保存和加载等操作。Containerd 使用 0CI(openContainer Initiative)规范定义容器镜像的格式。
  • 插件体系结构: containerd 具有可扩展的插件体系结构,允许用户通过插件来扩展其功能,例如存储驱动、网络插件等。
  • 跨平台支持:Containerd 可以在不同的操作系统上运行,从而提供了跨平台的支持。
  • 与 Kubernetes 集成: Containerd 作为 Kubernetes 的默认容器运行时,与 Kubernetes 紧密集成,为容器工作负载的管理提供了良好的支持。
  • 安全性和隔离:Containerd 实现了严格的容器隔离和安全性措施,确保容器之间的隔离性以及对主机系统的安全性。

        总体而言,Containerd 提供了一个轻量级、高度可定制的容器运行时,为容器生态系统的发展提供了一个稳定和可靠的基础。它在容器生命周期管理、镜像管理和插件支持等方面为用户提供了丰富的功能。

2.Containerd 的起源与背景

        Containerd 的起源可以追溯到 Docker 项目。Docker 最初作为一个开源项目推出,旨在简化应用程序的打包、分发和部署过程。Docker 引入了容器的概念,将应用程序和其依赖项打包到一个容器中,使得应用在不同环境中可以一致地运行。

        随着 Docker 的发展,其架构逐渐变得复杂,包含了许多功能,如镜像构建、服务编排等。为了更好地组织和管理这些功能,Docker 团队决定将 Docker引擎拆分成多个组件,其中一个关键的组件就是Containerd.

  • Docker 架构拆分: Docker 从单一的大型引擎拆分为一系列小型、可复用的组件。这种拆分的目标是提高可维护性、模块化和可扩展性。
  • Containerd 作为核心运行时:在 Docker 架构拆分后,containerd 被定位为 Docker 的核心容器运行时。它负责管理容器的生命周期、镜像操作和基本运行时功能。
  • 贡献给 CNCF:为了推动 Containerd 的发展,Docker 团队将 containerd 的代码捐赠给了Cloud Native computing Foundation(CNCF),使其成为 CNCF 的孵化项目。
  • 容器生态系统的标准化:Containerd 的设计遵循 Open container Initiative(开放容器倡议OCI)规范,这是一个关注容器运行时和镜像格式标准化的开放标准组织。这意味着 containerd 可以与符合 OCI 规范的其他容器工具和运行时进行互操作。
  • 独立的容器运行时: containerd 不仅仅局限于 Docker,它可以作为独立的容器运行时,与多个容器编排系统和工具集成,从而为用户提供更多选择。

        总体而言,containerd 的起源是为了简化容器运行时的管理,并为容器生态系统提供一个开放、标准化的基础。其发展不仅服务于 Docker生态系统,还为整个容器领域提供了一个通用的、可扩展的容器运行时。

二、Containerd 架构

1.Containerd 架构概述

        Containerd 的架构是 modularity(模块化)和可扩展性的体现,它被设计为一个轻量级、高度可定制的容器运行时。

        可以看出 Containerd 采用的也是 C/S 架构,服务端通过 unix domain socket 暴露低层的 gRPCAPI 接口出去,客户端通过这些 API 管理节点上的容器,每个 Containerd 只负责一台机器,Pu11 镜像,对容器的操作(启动、停止等),网络,存储都是由 containerd 完成。具体运行容器由 runc 负责。
        为了解耦,Containerd 将系统划分成了不同的组件,每个组件都由一个或多个模块协作完成(core部分),每一种类型的模块都以插件的形式集成到 containerd 中。

2.核心组件解析

        Containerd 组件大致分为 Storage、Metadata 和 Runtime 这三个主要方面。

(1)storage(存储)
Content(内容)

功能:Content存储了容器镜像的实际数据。这包括文件系统层和元数据,用于创建和管理容器的基础文件系统。

Snapshot(快照)

功能:Snapshot 存储容器的快照数据。每个容器都可以有一个或多个快照,允许它们共享相同的文件系统层,提高效率。

Diff(差异)

功能: Diff 存储容器文件系统层之间的差异。当容器运行时需要修改文件系统时,会在已有的文件系统层上创建一个差异层,以保存变更。

(2)Metadata(元数据)
Images(镜像)

功能:Images 存储容器镜像的元数据,包括镜像的标签、大小、创建时间等信息。Metadata 中的 Images组件允许容器对镜像进行管理和操作。

Containers(容器)

功能: Containers 存储容器的元数据,包括容器的状态、配置信息、网络设置等。这部分元数据使得容器能够有效地管理容器的生命周期。

(3)Runtime(运行时)
Tasks(任务)

功能:Tasks 包含容器内的进程组。每个容器运行时都有关联的 Task,它负责管理容器内的所有进程。Tasks 与 Shim 一起工作,维护容器的状态。

Events(事件)

功能: Events 组件记录了容器的各种事件,如容器的创建、启动、停止等。这些事件可以用于监控和日志记录,帮助用户了解容器系统的运行状况。

三、安装配置 Containerd

1.安装 Containerd

rm -rf /etc/yum.repos.d/*
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
yum clean all
# step 1: 安装必要的一些系统工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# Step 2: 添加软件源信息
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# Step 3
sudo sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
# 列出可用版本
yum list containerd.io --showuplicates
# 安装containerd
yum -y install containerd.io

2.配置containerd

(1)生成配置文件
mkdir -p /etc/containerd
containerd config defaultsudo tee /etc/containerd/config.toml

备注:

  • sudo tee /etc/containerd/config.toml:
  • tee 命令通常用来读取标准输入,并将其内容写入文件和输出到终端。
  • /etc/containerd/config.tom1是 containerd的配置文件路径,这里指定了配置文件的具体位置。
  • 使用 containerd config default 命令获取 containerd 的默认配置信息;
  • 通过管道|将这些配置信息传递给 tee 命令;
  • 使用 sudo tee /etc/containerd/config.toml以管理员权限创建或覆盖/etc/containerd/config.tom1 文件,并将之前获取的配置信息写入其中。
(2)配置镜像加速
# 使用 vi 打开配置文件
vim /etc/containerd/config.toml
# 找到[plugins."io.containerd.grpc.v1.cri".registry.mirrors]在下面添加
#添加阿里云的镜像源
[plugins."io.containerd.grpc.vl.cri".registry.mirrors
[plugins."io.containerd.grpc.vl.cri".registry.config."docker.io"]
endpoint = ["https://registry.cn-hangzhou.aliyuncs.com","https://registry-1.docker.io"]
#查看添加的信息
root@localhost ~l# grep -A 2 'mirrors" /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".registry.mirrors][plugins."io.containerd.grpc.v1.cri".registry.config."docker.io"]
endpoint = ["https://registry.cn-hangzhou.aliyuncs.com" ,"https://registry-1.docker.io"1
(3)启动服务
systemctl enable containerd
systemctl start containerd
[root@localhost ~]# ctr version
Client:
Version:1.6.6
Revision:10c12954828e7c7c9b6e0ea9b0c02b01407d3ae1
Go version: go1.17.11
Server :
Version:1.6.6
Revision:10c12954828e7c7c9b6e0ea9b0c02b01407d3ae1
UUID:067172f0-071d-44c2-bdea-9c402ad39745

四、containerd基本操作

1.镜像类操作

(1)拉取镜像

使用 ctr images pull 命令可以下载镜像
命令格式:
ctr images pull 镜像名称:[镜像标签]

[root@localhost ~]# ctr images pull hub.atomgit.com/amd64/nginx:1.25.2-perl
(2)查看镜像

查看本地有哪些镜像可以使用 ctr images ls

[root@localhost ~]# ctr images ls
REF
DIGEST
TYPE
SIZE
PLATFORMS
LABELS
docker.io/library/nginx:latest
application/vnd.docker.distribution.manifest.list.v2+jsonsha256:10d1f5b58f74683ad34eb29287e07dab1e90f10af243f151bb50aa5dbb4d62ee 67.3 MiBlinux/386,linux/amd64,linux/arm/v5,linux/arm/v7,linux/arm64/v8,linux/mips64le,linux/ppc64le,linux/s390x-
(3)检测本地镜像

主要査看其中的 STATUS,complete 表示镜像是完整可用的状态

命令格式:
ctr images check

root@localhost ~# ctr images check
REF                        TYPE
DIGEST                    STATUS
SIZE                        UNPACKED
docker.io/library/nginx:latest
application/vnd.docker.distribution.manifest.list.v2+jsonsha256:10d1f5b58f74683ad34eb29287e07dab1e90f10af243f151bb50aa5dbb4d62ee
complete(8/8)67.3 MiB/67.3 MiB true
(4)重新打标签

命令格式:
ctr images tag 当前镜像名称 新镜像名称

ctr images tag hub.atomgit.com/amd64/nginx:1.25.2-perl nginx:v1
ctr images tag hub.atomgit.com/amd64/nginx:1.25.2-perl nginx:v2
(5)删除镜像

命令格式:
ctr images rm 镜像名称:[镜像标签]

[root@localhost ~]# ctr images rm nginx:v2docker.io/library/nginx new:v1
(6)镜像挂载到主机目录

Containerd 可以把镜像直接挂载到宿主机的某个目录

命令格式:
ctr images mount 镜像 挂载点

[root@localhost ~]# ctr images mount nginx:v1 /mnt
sha256:fe7723b2df19ccf75328cb1f39c90c2332679144231501f3d4d0f51b16c2867
/mnt
[root@localhost ~]# ls -l /mnt/
total 8
7 Nov 19 19:00 bin ->usr/binlrwxrwxrwx 1 root root
drwxr-xr-x 2 root root6 Sep 29 16:04 boot
drwxr-xr-x 2 root root6 Nov 19 19:00 dev
41 Nov 21 04:05 docker-entrypoint.ddrwxr-xr-x 1root root-rwxrwxr-x 1 root root 1620 Nov 21 04:05 docker-entrypoint.shdrwxr-xr-x 1 root root 4096 Nov 21 04:05 etc6 Sep 29 16:04 homedrwxr-xr-x 2 root root
lrwxrwxrwx 1 root root7 Nov 19 19:00 lib ->usr/lib
9 Nov 19 19:00 lib32 ->usr/lib32lrwxrwxrwx 1root root
lrwxrwxrwx 1root root9 Nov 19 19:00 lib64 ->usr/lib64
lrwxrwxrwx 1root root
drwxr-xr-x 2 root root6 Nov 19 19:00 media
6 Nov 19 19:00 mntdrwxr-xr-x 2 root root
6 Nov 19 19:00 optdrwxr-xr-x 2 root root
6 Sep 29 16:04 procdrwxr-xr-x 2 root root
2 root root37 Nov 19 19:00 rootdrWX------
drwxr-xr-x 3 rootroote18 Nov 19 19:00 run
lrwxrwxrwx 1 root root8 Nov 19 19:00 sbin ->usr/sbin
6 Nov 19 19:00 srvdrwxr-xr-x 2 root root
6 Sep 29 16:04 sysdrwxr-xr-x 2 root root
drwxrwxrwt 1 root root6 Nov 21 84:05 tmp
66 Nov 19 19:00 usrdrwxr-xr-x 1 root root
drwxr-xr-x 1 root root41 Nov 19 19:00 var
(7)镜像从主机目录卸载

用于将挂载到宿主机的镜像卸载下来
命令格式:
ctr images unmount 挂载点

[root@localhost ~l# ctr images unmount /mnt/
/mnt/
(8)镜像导出

该命令主要用于把镜像保存成文件命令格式:
ctr images export --all-platforms 文件名 镜像名称:[镜像标签]

ctr images export --all-platforms nginx vl.tar nginx:v1
ctr:                content                    digest
sha256:b50f4e222b2d749d6a999baf30df1d6090d47f2ae855ae80ede69d6dddf5b58c: not found

#有时候镜像导入导出的时候会有报错,ctr:content digest sha256:xxxxxx not found
# 解决办法如下

[root@localhost ~]# ctr images rm nginx:v1
[root@localhost ~]# ctr images pull --all-platforms nginx:v1
[root@localhost ~]# ctr images export --all-platforms nginx latest.tar nginx:v1docker.io/library/nginx:latest
(9)镜像导入

该命令主要用于把文件加载为镜像
命令格式:
ctr images import 文件名

[root@localhost ~]# ctr images import nginx_v1.tar
unpacking                                docker.io/library/nginx:latest
(sha256:10d1f5b58f74683ad34eb29287e07dab1e90f10af243f151bb50aa5dbb4d62ee)...done

2.容器类操作

        Containerd 本身并没有直接支持端口映射的功能。端口映射通常是由容器运行时(比如 Docker、CRI-0)负责的,而不是容器的底层运行时(containerd)。

(1)创建容器
# 基于 docker,io/library/nginx:latest 镜像创建一个叫 nginx 的容器
[root@localhost ~l# ctr containers create nginx:vl nginx
(2)列出容器
[root@localhost ~]# ctr containers ls
CONTAINER    IMAGE                RUNTIME
nginxdocker.io/library/nginx:latest        io.containerd.runc.v2
(3)查看容器的详细信息
[root@localhost ~l# ctr containers info nginx
(4)删除容器
[root@localhost ~]# ctr containers ls
CONTAINER            IMAGE                RUNTIME
nginx            docker.io/library/nginx:latest            io.containerd.runc.v2
[root@localhost ~]# ctr containers rm nginx
[root@localhost ~]# ctr containers ls
CONTAINER            IMAGE                RUNTIME

3.任务类操作

        我们通过 container create 命令创建的容器,并没有处于运行状态,只是一个静态的容器(仅仅只是一个创建容器的声明)。一个 container 对象只是包含了运行一个容器所需的资源及相关配置数据,表示 namespaces、rootfs 和容器的配置都已经初始化成功了,只是用户进程还没有启动。        

        一个容器真正运行起来是由 Task 任务实现的。

(1)启动容器
#启动任务的时候要先有容器
[root@localhost ~l# ctr containers create nginx:vl nginx
[root@localhost ~l# ctr containers ls
CONTAINER            IMAGE            RUNTIME
nginx                nginx:v1                    io.containerd.runc.v2
#-d 放入后台
root@localhost ~# ctr task start:-d nginx
(2)查看容器
[root@localhost ~]# ctr task ls
TASK                PID                STATUS
nginx                12774                RUNNING
(3)进入容器里面
#进入到容器里面
#不过这里需要注意必须要指定 --exec-id 参数,这个 id 可以随便写,只要唯一就行
[root@localhost ~]# ctr task exec --exec-id 0 -t nginx sh
(4)暂停容器
root@localhost ~]# ctr task pause nginX
[root@localhost ~]# ctr task ls
TASK            PID            STATUS
nginx            12774            PAUSED
(5)恢复容器
[root@localhost ~]# ctr task resume nginx
[root@localhost ~]# ctr task ls
TASK            PID            STATUS
nginx           12774            RUNNING
(6)杀死容器
#杀死容器,ctr 没有 stop 容器的功能,只能暂停或者杀死容器
[root@localhost ~]# ctr task kill nginx
[root@localhost ~]# ctr task ls
TASK            PID            STATUS
nginx           12774           STOPPED
(7)删除任务
[root@localhost ~l# ctr task rm nginx

注意:
虽然已经删除了任务,但是创建容器的时候,也创建了一个同名的快照,即便已经删除了任务,也可以使用“ctr task start -d nginx”命令,利用此快照将已删除的任务启动起来,使得此容器恢复运行。

(8)删除容器
[root@localhost ~]# ctr task kill nginx
[root@localhost ~l# ctr container rmnginx

注意:
删除容器后快照也就没有了

(9)获取容器的内存、CPU 和 PID 的限额与使用量
[root@localhost ~]# ctr containers create nginx:vl nginx
[root@localhost ~]# ctrtask start -d nginx
[root@localhost ~# ctr task metrics nginx
ID            TIMESTAMP

nginx    2023-11-27 08:58:19.17333324 +0000 UTC
METRIC        VALUE
memory.usage in bytes        0
memory.limit in bytes        9223372036854771712
memory.stat.cache            0
cpuacct.usage                36365002
cpuacct.usage percpu        [16788433 19576569]
pids.current                    0
pids.limit                    0

#memory.usage_in_bytes:容器使用的内存大小,以字节为单位。在这个例子中,内存使用量为 0 字节。
# memory.limit in bytes:容器的内存限制,以字节为单位。在这个例子中,内存限制为9223372036854771712 字节(这是一个很大的数值,通常表示无限制)。

# memory.stat.cache:内存中的缓存大小,以字节为单位。在这个例子中,缓存大小为 8 字节。

#cpuacct.usage:CPu 使用的时间,以纳秒为单位。在这个例子中,CPU 使用时间为 36365002 纳秒。#cpuacct.usage_percpu:每个 CPU 核的 CPU 使用时间,以纳秒为单位。在这个例子中,有两个 CPU核,它们的使用时间分别为16788433 纳秒和 19576569 纳秒。

# pids.current:当前正在容器中运行的进程数量。在这个例子中,进程数为 0。

# pids.limit:容器的进程数限制。在这个例子中,进程数限制为 8(通常表示没有限制)。

(10)查看容器中所有进程在宿主机中的PID
#先启动一个容器
[root@localhost ~l# ctr task start -d nginx/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to performconfiguration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
#查看所有进程在宿主机的 pid
[root@localhost ~]# ctr task ps nginx
PID                INFO
12980                -
13007                -
13008                -
[root@localhost ~]# ps -ef|grep 12980
root        12961 0 04:00?12980            00:00:00 nginx:master processnginx-gdaemon
off;
101        13007 12980 004:00?            00:00:00 nginx:worker process
101        13008 12980 004:00 ?            00:00:00 nginx:worker process
root       130341512 0 04:01 pts/0        00:00:00 grep--color=auto 12980

4.其他操作

(1)插件

        在 Containerd 中,插件是一种机制,允许你通过加载和卸载插件来扩展 Containerd 的功能。插件可以提供不同的功能,例如容器存储、网络、监控等。containerd 使用插件化的设计,使其可以适应各种不同的容器运行时和容器生态系统需求。

        以下是 Containerd 中的一些常见插件类型:
        shim 插件: shim 插件负责管理容器的生命周期。当一个容器任务启动时,containerd 会调用相应的 shim 插件来创建并监管容器进程。shim 插件负责与容器进程的通信,以及监控容器的状态。
        Snapshotter 插件: Snapshotter 插件处理容器的文件系统快照(Snapshots)。它定义了容器文件系统的结构,支持创建、管理和销毁快照,以及在不同容器之间共享文件系统层。
        Task 插件: Task 插件用于管理容器中的任务(Task)。任务表示容器内运行的一个或多个进程。
它与容器的生命周期直接相关。
        Image 插件: Image 插件负责处理容器镜像的拉取、推送、删除等操作。它定义了容器镜像的存储和元数据结构。
        Content store 插件: Content store 插件管理容器内容(content),包括镜像层和元数据它定义了内容的存储和检索方式。

        这些插件允许用户根据实际需求选择性地配置 Containerd,并与其他容器运行时和编排系统进行集成。例如,通过选择不同的快照插件,你可以定制Containerd 的文件系统管理方式。通过选择不同的网络插件,你可以适应不同的网络模型和需求。
        插件化的设计使得 Containerd 可以灵活地适应不同的使用场景,并且可以方便地进行定制和扩展每个插件都提供了标准化的接口,使得插件可以被轻松地替换或新增,从而满足不同用户和组织的需求。

[root@localhost ~]# ctr plugins ls
TYPE                                    TD            PLATFORMS            STATUS
io.containerd.content.v1        content                  -                  ok
(2)命名空间

        在 Containerd 中,命名空间(Namespace)是一种用于隔离资源和进程视图的 Linux 内核特性。命名空间允许在同一主机上运行的进程拥有不同的资源视图,从而实现资源隔离Containerd 利用 Linux 的命名空间实现容器的隔离。
        以下是 Containerd 中使用的一些主要命名空间类型:
        PID 命名空间: 它隔离了进程 D 空间,使得在不同 PID 命名空间中的进程看起来像是在独立的系统中运行一样。这有助于确保容器中的进程无法看到或影响主机系统上的其他进程。
        Network 命名空间: 它隔离了网络栈,使得容器内的网络环境独立于主机系统。每个容器可以有自己的网络接口、IP 地址和端口等,而不会影响其他容器或主机上的网络配置。

        Mount 命名空间: 它隔离了文件系统挂载点,使得容器拥有自己的文件系统视图。这样,每个容器
都可以有自己的文件系统,不受其他容器的影响。
        UTS 命名空间:它隔离了主机名和域名,允许容器具有自己的主机名和域名。

        IPC 命名空间: 它隔离了进程间通信(IPC)资源,使得容器内的进程无法直接与主机系统或其他容器共享 IPC 资源。

        User 命名空间: 它隔离了用户和用户组的视图,使得容器中的进程可以在容器内部以不同的用户和组身份运行,而在主机系统上的实际用户和组不受影响。
        这些命名空间的组合使得容器可以在相对独立的环境中运行,避免了与主机系统或其他容器的干扰。Containerd 利用这些命名空间实现容器的隔离和资源管理,确保容器化应用在共享主机资源的同时获得适当的隔离。

#查看都有哪些命名空间
[root@localhost ~]# ctr ns ls
NAME        LABELS
default
# 创建命名空间
root@localhost ~# ctrns create test
[root@localhost ~]# ctr ns ls
NAME    LABELS
default
test
# 删除命名空间
root@localhost ~# ctr nsrm test
test
#在做操作的时候可以使用-n来指定命名空间,如果不指定表示操作的是默认的命名空间,比如查看k8s.io 命名空间的镜像
ctr -n test images pull hub.atomgit.com/amd64/nginx:1.25.2-per1
ctr -n test images tag hub.atomgit.com/amd64/nginx:1.25.2-perl nginx:v1
ctr -n test images ls
ctr -n test containers createnginx:v1 nginx03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值