yuanxiaojiang
人的放纵是本能,自律才是修行

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 流和状态收集,以实现容器运行时与守护进程的分离

2469482-20241216195013757-553940971

主要区别

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

Kubernetes运行时选择

目前Kubernetes集群已经默认支持containerd容器运行时

image

基于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"

启动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

 
在指定namespace中下载容器镜像,如果namespace不存在则会直接创建
[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    

 

[root@elk92 ~]# ctr container create --with-ns "pid:/proc/2914/ns/pid" docker.io/library/alpine:latest c3

--with-ns "pid:/proc/2914/ns/pid"

 

作用: 指定容器共享现有进程的 PID 命名空间

 

 

含义:

 

 

pid: 表示 PID 命名空间

 

/proc/23103/ns/pid: 指向进程 ID 为 23103 的进程的 PID 命名空间

 

        7.1 终端1执行
[root@docker202 ~]# ctr -n yinzhengjie task ls
TASK    PID      STATUS    
c1      23103    RUNNING
[root@docker202 ~]# 
[root@docker202 ~]# ctr -n yinzhengjie tasks exec --exec-id $RANDOM -t c1 sh
/usr/local/stress # ps -ef
PID   USER     TIME  COMMAND
    1 root      0:00 /bin/sh
   53 root      0:00 sh
   59 root      0:00 ps -ef
/usr/local/stress # 
/usr/local/stress # exit
[root@docker202 ~]# 
[root@docker202 ~]# ctr container create --with-ns "pid:/proc/23103/ns/pid" docker.io/library/nginx:1.21.6-alpine  c4
[root@docker202 ~]# 
[root@docker202 ~]# ctr tasks ls
TASK    PID      STATUS    
c2      22694    RUNNING
[root@docker202 ~]# 
[root@docker202 ~]# ctr tasks start -d c4 
[root@docker202 ~]# 
[root@docker202 ~]# ctr tasks ls
TASK    PID      STATUS    
c2      22694    RUNNING
c4      23723    RUNNING
[root@docker202 ~]# 
[root@docker202 ~]# ctr tasks exec --exec-id $RANDOM c4 sleep 300

        7.2 终端2执行
[root@docker202 ~]# ctr tasks exec --exec-id $RANDOM -t c4 sh
/ # ps -ef
PID   USER     TIME  COMMAND
    1 root      0:00 /bin/sh
   94 root      0:00 nginx: master process nginx -g daemon off;
  125 nginx     0:00 nginx: worker process
  126 nginx     0:00 nginx: worker process
  127 root      0:00 sleep 300
  134 root      0:00 sh
  141 root      0:00 ps -ef
/ # 

 

容器数据持久化

下载镜像

[root@elk92 ~]# ctr -n yuan01 images pull docker.io/library/alpine:latest
[root@elk92 ~]# ctr -n yuan01 images ls
docker.io/library/alpine:latest

 

创建容器
[root@elk92 ~]# ctr -n yuan01 container create  --mount type=bind,src=/yuan/games,\
dst=/usr/local/nginx/html,options=rbind:rw docker.io/library/alpine:latest games
type=bind: 挂载类型为绑定挂载 src=/yuan/games: 宿主机源目录路径 dst=/usr/local/nginx/html: 容器内目标路径 options=rbind:rw: 挂载选项 rbind: 递归绑定挂载 rw: 读写权限

启动容器

[root@elk92 ~]# mkdir -p /yuan/games
[root@elk92 ~]# ctr -n yuan01 tasks start -d games
[root@elk92 ~]# ctr -n yuan01 tasks ls
TASK     PID     STATUS    
games    3956    RUNNING

 

进入容器,查看是否挂载成功,并写入测试数据
 
[root@elk92 ~]# cp /etc/os-release /yuan/games/
[root@elk92 ~]# ctr -n yuan01 tasks exec --exec-id $RANDOM -t games sh
/ # ls -l /usr/local/nginx/html/
-rw-r--r--    1 root     root           393 Nov  4 06:37 os-release
/ # echo "https://www.cnblogs.com/yuanxiaojiang" > /usr/local/nginx/html/blog.txt

 

查看宿主机的目录,观察数据是否持久化

[root@elk92 ~]# ll /yuan/games/
-rw-r--r-- 1 root root  38 Nov  4 14:41 blog.txt
-rw-r--r-- 1 root root 393 Nov  4 14:37 os-release

 删除容器,验证存储卷是否存在

[root@elk92 ~]# ctr -n yuan01 task ls  # docker ps
TASK     PID     STATUS    
games    3956    RUNNING
[root@elk92 ~]# ctr -n yuan01 container ls  # docker ps -a
CONTAINER    IMAGE                              RUNTIME                  
games        docker.io/library/alpine:latest    io.containerd.runc.v2 

# 容器需要先停止才能删除

[root@elk92 ~]# ctr -n yuan01 task kill --signal SIGKILL games
[root@elk92 ~]# ctr -n yuan01 container rm games

[root@elk92 ~]# ll /yuan/games/
-rw-r--r-- 1 root root  38 Nov  4 14:41 blog.txt
-rw-r--r-- 1 root root 393 Nov  4 14:37 os-release

  containerd实现镜像推送到harbor仓库

http的配置

[root@elk92 ~]# vim /etc/containerd/config.toml
      [plugins."io.containerd.grpc.v1.cri".registry.mirrors."harbor.yuanxiaojiang.cn"]
        endpoint = [
          "http://harbor.yuanxiaojiang.cn"
        ]

https的配置

[root@elk92 ~]# vim /etc/containerd/config.toml
        [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.yuanxiaojiang.cn:443".tls]
          insecure_skip_verify = true
        [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.yuanxiaojiang.cn:443".auth]
          username = "admin"
          password = "yuanxiaojiang"
      [plugins."io.containerd.grpc.v1.cri".registry.mirrors."harbor.yuanxiaojiang.cn:443"]
        endpoint = [
          "https://harbor.yuanxiaojiang.cn:443"
        ]

 

 

 
 
重新生成新的tag
[root@elk92 ~]# ctr -n yuan01 images tag docker.io/library/alpine:latest harbor.yuanxiaojiang.cn/library/containerd_alpine:latest 
harbor.yuanxiaojiang.cn/library/containerd_alpine:latest

推送容器镜像至Harbor

[root@elk92 ~]# cat /etc/hosts

10.0.0.82 harbor.yuanxiaojiang.cn
[root@elk92 ~]# ctr -n yuan01 images push --platform linux/amd64 --plain-http \
-u admin:yuanxiaojiang harbor.yuanxiaojiang.cn/library/containerd_alpine:latest

温馨提示: 1.如果咱们的harbor仓库是基于https配置的,只需要多加一个跳过认证的参数"--skip-verify"即可。 2.如果说你的harbor是基于http配置的,则需要使用"--plain-http"选项声明你是http协议; 推送https的镜像案例,harbor的效果如下图所示: [root@worker243 ~]# ctr -n yinzhengjie images push --platform linux/amd64 -u admin:1 --skip-verify harbor.yinzhengjie.com/library/nginx:1.25.4-alpine

拉取私有仓库镜像

[root@elk92 ~]# ctr images pull --plain-http harbor.yuanxiaojiang.cn/library/containerd_alpine:latest
 

Docker集成Containerd实现容器管理

目前Containerd主要任务还在于解决容器运行时的问题,对于其周边生态还不完善。 所以可以借助Docker结合Containerd来实现Docker完整的功能应用。
 
1.安装docker
[root@elk92 ~]# yum install -y yum-utils
[root@elk92 ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
[root@elk92 ~]# yum install -y docker-ce

 2.修改docker启动脚本

[root@elk92 ~]# vim /usr/lib/systemd/system/docker.service 
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --cri-containerd --debug
    # 为其新增--contanerd启动项 --containerd /run/containerd/containerd.sock
[root@elk92 ~]# systemctl daemon-reload
[root@elk92 ~]# systemctl enable docker && systemctl start docker && systemctl status docker

3.基于docker启动容器

[root@elk92 ~]# docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
alpine       latest    706db57fb206   3 weeks ago   8.32MB

[root@elk92 ~]# ctr namespace ls
default        
[root@elk92 ~]# docker run  -d --name c1 alpine:latest sleep 3600
[root@elk92 ~]# ctr namespace ls
default        
moby 

 

4.查看容器的运行信息及查看container对应的关系
[root@elk92 ~]# docker ps -l --no-trunc
CONTAINER ID 
f5cf65d4df63b0baadb5773022cf30b13281428247ee27db55b1e82a21aa4d03   
[root@elk92 ~]# ctr -n moby container ls
CONTAINER                                                       
f5cf65d4df63b0baadb5773022cf30b13281428247ee27db55b1e82a21aa4d03
说明了 Docker 容器底层是通过 containerd 进行管理的,docker ps 显示的容器在 containerd 的命名空间(moby)中也能找到对应记录

5.docker删除容器查看containerd的对应关系

[root@elk92 ~]# ctr -n moby tasks ls
TASK
f5cf65d4df63b0baadb5773022cf30b13281428247ee27db55b1e82a21aa4d03
[root@elk92 ~]# docker rm -f f5cf65d4df63b0baadb5773022cf30b13281428247ee27db55b1e82a21aa4d03
[root@elk92 ~]# ctr -n moby tasks ls
TASK    PID    STATUS 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted on 2025-11-03 09:31  猿小姜  阅读(14)  评论(0)    收藏  举报

levels of contents