containerd
- 2016年3月,Docker 1.11 已内置 containerd,如今它被彻底剥离为独立开源项目,旨在提供更开放、稳定的容器运行时基础设施
 - containerd是主要面向Kubernetes等上层编排系统的底层容器运行时,而非直接由最终用户操作
 - containerd以Daemon的形式运行在系统上,通过暴露底层的gRPC API,上层系统可以通过这些API管理机器上的容器
 
Docker与containerd的关系与区别
Docker:是一个完整的容器化平台,而 containerd 是一个专一的容器运行时(containerd是Docker的核心组件之一)
gRPC:是一个由 Google 开发的高性能、开源、跨语言的远程过程调用(RPC)框架
runC:是一个根据 OCI 标准创建和运行容器的底层命令行工具
container-shim:是一个垫片进程,用于在 runC 退出后保持容器运行并维持其 STDIO 流和状态收集,以实现容器运行时与守护进程的分离

主要区别
| 特点 | Docker | containerd | 
| 功能范围 | 完整的容器管理平台,包括容器构建、运行、镜像管理、编排等。 | 只关注容器运行和生命周期管理(启动、停止、管理容器),不提供镜像构建、编排等功能。 | 
| 适用场景 | 本地开发、CI/CD、单机容器管理、容器编排(Docker Compose) | Kubernetes、容器运行时环境,适合大规模生产环境。 | 
| 镜像构建 | 支持镜像构建(通过 docker build) | 不支持镜像构建,依赖 Docker 或其他工具来构建镜像。 | 
| 容器编排 | 支持 Docker Compose 和 Docker Swarm 编排。 | 不支持容器编排,通常由 Kubernetes 等管理容器编排。 | 
| 资源消耗 | 较重,包含了很多功能和工具,适合开发和测试 | 轻量级,专注于容器的运行时管理,资源消耗较少。 | 
| 开发者体验 | 提供完整的 CLI 和图形化工具,适合开发、调试、测试 | 提供简化的命令行接口,适合在生产环境中使用 | 
Kubernetes运行时选择
目前Kubernetes集群已经默认支持containerd容器运行时

基于yum方式安装containerd
# 1.获取软件源 [root@elk91 ~]# yum install -y yum-utils # 安装一些必要的系统工具 [root@elk91 ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 2.查看yum源中containerd软件版本 [root@elk91 ~]# yum list |grep containerd containerd.io.x86_64 1.6.33-3.1.el7 docker-ce-stable # 3.安装containerd、查看对应的版本 [root@elk91 ~]# yum install -y containerd.io.x86_64 [root@elk91 ~]# ctr --version ctr containerd.io 1.6.33 # 4.设置containerd开机自启动 [root@elk91 ~]# systemctl enable --now containerd [root@elk91 ~]# systemctl status containerd
二进制安装containerd
containerd有两种安装包: - containerd-xxx: 这种安装包用于单机测试没问题,不包含runC,需要提前安装。 - cri-containerd-cni-xxx: 包含runc及符合K8S的CNI接口的相关软件包。 虽然包含runC,但是为了获得独立的版本控制和更新灵活性,避免被捆绑在特定软件包\
的发布周期中,因此建议大家手动安装runC
https://github.com/containerd/containerd/releases/download/v1.7.13/cri-containerd-cni-1.7.13-linux-amd64.tar.gz
# 进行解压操作 [root@elk92 ~]# tar xf cri-containerd-cni-1.7.13-linux-amd64.tar.gz # 解压完成后会自动生成三个目录 etc: # 存放的是containerd服务管理配置文件及cni虚拟网卡配置文件 cni crictl.yaml systemd opt: # 存放的是GCE环境中使用containerd配置文件及CNI插件 cni containerd usr: # 存放的是containerd运行时文件,包含runC local # 拷贝containerd运行时文件到宿主机指定路径 [root@elk92 ~]# cp /root/usr/local/bin/containerd /usr/local/bin/ # 拷贝containerd的systemd的配置文件 [root@elk92 ~]# cp /root/etc/systemd/system/containerd.service /usr/lib/systemd/system/
生成配置文件
# 1.创建配置文件目录 [root@elk92 ~]# mkdir /etc/containerd # 2.生成默认的配置文件 [root@elk92 ~]# containerd config default > /etc/containerd/config.toml # 3.修改Cgroup的管理者为systemd组件 [root@elk92 ~]# grep SystemdCgroup /etc/containerd/config.toml SystemdCgroup = false [root@elk92 ~]# sed -ri 's#(SystemdCgroup = )false#\1true#' /etc/containerd/config.toml [root@elk92 ~]# grep SystemdCgroup /etc/containerd/config.toml SystemdCgroup = true # 4.修改pause的基础镜像名称 [root@elk92 ~]# grep sandbox_image /etc/containerd/config.toml sandbox_image = "registry.k8s.io/pause:3.8" [root@elk92 ~]# sed -i 's#registry.k8s.io/pause:3.8#registry.cn-hangzhou.aliyuncs.com\
/google_containers/pause:3.8#' /etc/containerd/config.toml [root@elk92 ~]# grep sandbox_image /etc/containerd/config.toml sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.8" # 5.添加私有仓库信息
[root@elk92 ~]# grep -n -e "registry.mirrors" -e "endpoint" /etc/containerd/config.toml
168:      [plugins."io.containerd.grpc.v1.cri".registry.mirrors."harbor.yuanxiaojiang.com"]
251:    endpoint = "https://harbor.yuanxiaojiang.com"
 
启动containerd服务
# 1.启动containerd服务 [root@elk92 ~]# systemctl enable --now containerd # 2.查看服务的状态 [root@elk92 ~]# systemctl status containerd
拷贝ctr客户端工具及containerd-shim代理垫片
# 1.拷贝ctr客户端工具到PATH环境变量 [root@elk92 ~]# cp /root/usr/local/bin/ctr /usr/bin/
[root@elk92 ~]# source ~/.bashrc
[root@elk92 ~]# ctr --version ctr github.com/containerd/containerd v1.7.13
[root@elk92 ~]# cp /root/usr/local/bin/containerd-shim-runc-v2 /usr/bin/
安装runC
建议单独下载 runC 二进制包安装,因为二进制包自带的 runC 可能缺少 seccomp 支持或版本要求不匹配,导致无法正常使用
https://github.com/opencontainers/runc/releases/download/v1.1.12/runc.amd64
1.查看runC软件包大小 [root@elk92 ~]# ll -h runc.amd64 -rw-r--r--. 1 root root 11M Feb 17 19:16 runc.amd64 2.移动runc软件包到PATH环境变量 [root@elk92 ~]# mv runc.amd64 /usr/sbin/runc 3.为runc程序添加执行权限 [root@elk92 ~]# chmod +x /usr/sbin/runc 4.查看runC的版本信息 [root@elk92 ~]# runc -v runc version 1.1.12 commit: v1.1.12-0-g51d5e946 spec: 1.0.2-dev go: go1.20.13 libseccomp: 2.5.4
containerd管理
镜像管理
ctr 默认不会从本地 Docker 存储库拉取镜像
# 下载指定镜像
[root@elk92 ~]# ctr images pull docker.io/library/alpine:latest 下载镜像必须指定镜像的仓库地址,不能向我们之前docker那样使用,可以省略镜像服务器地址。 docker服务我们不写镜像服务器地址默认就是docker HUB的官方仓库 ctr工具并没有对docker的hub官方镜像地址做特殊处理
# 查看镜像列表
[root@elk92 ~]# ctr images ls
#
挂载镜像以查看镜像内容
[root@elk92 ~]# ll /mnt/ total 0 [root@elk92 ~]# ctr image mount docker.io/library/alpine:latest /mnt/ sha256:256f393e029fa2063d8c93720da36a74a032bed3355a2bc3e313ad12f8bde9d1 /mnt/ [root@elk92 ~]# ll /mnt/ total 12 drwxr-xr-x 2 root root 4096 Oct 8 17:28 bin drwxr-xr-x 2 root root 6 Oct 8 17:28 dev drwxr-xr-x 17 root root 4096 Oct 8 17:28 etc drwxr-xr-x 2 root root 6 Oct 8 17:28 home drwxr-xr-x 6 root root 127 Oct 8 17:28 lib drwxr-xr-x 5 root root 44 Oct 8 17:28 media drwxr-xr-x 2 root root 6 Oct 8 17:28 mnt drwxr-xr-x 2 root root 6 Oct 8 17:28 opt dr-xr-xr-x 2 root root 6 Oct 8 17:28 proc drwx------ 2 root root 6 Oct 8 17:28 root drwxr-xr-x 3 root root 18 Oct 8 17:28 run drwxr-xr-x 2 root root 4096 Oct 8 17:28 sbin drwxr-xr-x 2 root root 6 Oct 8 17:28 srv drwxr-xr-x 2 root root 6 Oct 8 17:28 sys drwxrwxrwt 2 root root 6 Oct 8 17:28 tmp drwxr-xr-x 7 root root 66 Oct 8 17:28 usr drwxr-xr-x 11 root root 137 Oct 8 17:28 var [root@elk92 ~]# umount /mnt [root@elk92 ~]# ll munt ls: cannot access munt: No such file or directory [root@elk92 ~]# ll /mnt/ total 0
镜像导出
[root@elk92 ~]# ctr images export --platform linux/amd64 alpine_latest.tar docker.io/library/alpine:latest
删除镜像
[root@elk92 ~]# ctr image rm docker.io/library/alpine:latest
导入镜像
[root@elk92 ~]# ctr image ls REF TYPE DIGEST SIZE PLATFORMS LABELS [root@elk92 ~]# ctr images import --platform linux/amd64 alpine_latest.tar [root@elk92 ~]# ctr image ls REF TYPE DIGEST SIZE PLATFORMS LABELS docker.io/library/alpine:latest
给镜像打tag
[root@elk92 ~]# ctr image tag docker.io/library/alpine:latest alpine:latest REF TYPE DIGEST SIZE PLATFORMS LABELS alpine:latest
容器管理
[root@elk92 ~]# ctr containers create docker.io/library/alpine:latest c1
[root@elk92 ~]# ctr containers ls
CONTAINER    IMAGE                              RUNTIME                  
c1           docker.io/library/alpine:latest    io.containerd.runc.v2
[root@elk92 ~]# ctr container info c1
启动容器
[root@docker92 ~]# ctr containers ls # 注意观察,c1容器的运行时为"io.containerd.runc.v2" CONTAINER IMAGE RUNTIME c1 docker.io/library/nginx:1.21.6-alpine io.containerd.runc.v2 [root@docker92 ~]# ll /usr/bin/containerd-shim-runc-v2 -rwxr-xr-x 1 root root 12189696 Mar 6 23:32 /usr/bin/containerd-shim-runc-v2* [root@docker92 ~]# ctr task start -d c1 # 请确保"/usr/bin/containerd-shim-runc-v2"文件存在,否则无法启动容器"-d"表示后台运行容器容器
查看容器的pid
[root@elk92 ~]# ctr task ls # 查看每个容器的主进程PID TASK PID STATUS c1 2120 RUNNING
[root@elk92 ~]# ctr task ps c1 # 查看容器内所有进程的PID
PID INFO
2120    -
在容器中执行命令
[root@elk92 ~]# ctr task exec --exec-id 1 c1 ifconfig -a
 --exec-id 这个数字 1 是一个随机生成的会话ID,用于唯一标识这次正在执行的exec任务,以便管理和区分同一容器内可能并发的多个执行会话。
[root@elk92 ~]# ctr run -d --net-host docker.io/library/alpine:latest c2
暂停容器
[root@elk92 ~]# ctr tasks pause c1 [root@elk92 ~]# ctr tasks ls TASK PID STATUS c1 2120 PAUSED c2 2524 RUNNING
恢复容器
[root@elk92 ~]# ctr tasks ls TASK PID STATUS c1 2120 PAUSED c2 2524 RUNNING [root@elk92 ~]# ctr tasks resume c1 [root@elk92 ~]# ctr tasks ls TASK PID STATUS c1 2120 RUNNING c2 2524 RUNNING
停止容器
[root@elk92 ~]# ctr tasks ls TASK PID STATUS c1 2120 RUNNING c2 2524 RUNNING [root@elk92 ~]# ctr tasks kill c1 [root@elk92 ~]# ctr tasks kill --signal SIGKILL c1 # 强制停止 [root@elk92 ~]# ctr tasks ls TASK PID STATUS c1 2120 STOPPED c2 2524 RUNNING
删除容器
[root@elk92 ~]# ctr tasks rm c1 WARN[0000] task c1 exit with non-zero exit code 137 [root@elk92 ~]# ctr tasks ls TASK PID STATUS c2 2524 RUNNING
Containerd NameSpace管理
containerd中namespace的作用是为了隔离运行的容器,可以实现在不同的名称空间运行多个同名的容器。
创建namespace
[root@elk92 ~]# ctr namespace create yuan01
[root@elk92 ~]# ctr namespace ls
NAME    LABELS 
default        
yuan01   
删除namespace
[root@elk92 ~]# ctr namespace rm yuan01
yuan01
[root@elk92 ~]# ctr namespace ls
NAME    LABELS 
default  
[root@elk92 ~]# ctr -n yuan01 image ls REF TYPE DIGEST SIZE PLATFORMS LABELS [root@elk92 ~]# ctr -n yuan01 images pull docker.io/library/alpine:latest # 会自动创建namespace [root@elk92 ~]# ctr namespace ls NAME LABELS yuan01 [root@elk92 ~]# ctr -n yuan01 image ls docker.io/library/alpine:latest-n选项的作用是指定要操作的命名空间。
在指定的namespace中运行容器
[root@elk92 ~]# ctr containers ls CONTAINER IMAGE RUNTIME c1 docker.io/library/alpine:latest io.containerd.runc.v2 c2 docker.io/library/alpine:latest io.containerd.runc.v2 [root@elk92 ~]# ctr -n yuan01 run -d --net-host docker.io/library/alpine:latest c1 [root@elk92 ~]# ctr -n yuan01 containers ls CONTAINER IMAGE RUNTIME c1 docker.io/library/alpine:latest io.containerd.runc.v2
                    
                
                
            
        
浙公网安备 33010602011771号