containerd 容器概述
官方文档:
https://containerd.io
在 2016 年 12 月 14 日,Docker 公司宣布将 containerd 从 Docker 中分离,由开源社区独立发展和
运营。Containerd 完全可以单独运行并管理容器,而 Containerd 的主要职责是镜像管理和容器执
行。同时,Containerd 提供了 containerd-shim 接口封装层,向下继续对接 runC 项目,使得容器
引擎 Docker Daemon 可以独立升级。
Containerd 可以在宿主机中管理完整的容器生命周期:容器镜像的传输和存储、容器的执行和管
理、存储和网络等。总结一下,它主要负责干以下事情
• 管理容器的生命周期(从创建容器到销毁容器)
• 拉取/推送容器镜像
• 存储管理(管理镜像及容器数据的存储)
• 调用 runC 运行容器(与 runC 等容器运行时交互)
• 管理容器网络接口及网络
ctr:containerd 的命令行客户端。
1、Containerd 和 Docker 之间的关系
1、Containerd 和 Docker 之间的关系
Docker 包含 Containerd,Containerd 专注于运行时的容器管理,而 Docker 除了容器管理之
外,还可以完成镜像构建之类的功能。
Containerd 提供的 API 偏底层,不是给普通用户直接用的,容器编排的开发者才需要
Containerd。
2、Containerd 在容器生态中扮演的角色
Containerd 并不是直接面向最终用户的,而是主要用于集成到更上层的系统里,比如 Kubernetes
等容器编排系统。
Containerd 以 daemon 的形式运行在系统上,通过 unix domain socket 暴露底层的 grpc
API,上层系统可以通过这些 API 管理机器上的容器。
**互动 1:**K8S 为什么要放弃使用 Docker 作为容器运行时,而使用 containerd 呢?
知道:1
不:2
Docker,Kubernetes 等工具来运行一个容器时会调用容器运行时(CRI),比如 containerd,CRIO,通过容器运行时来完成容器的创建、运行、销毁等实际工作,Docker 使用的是 containerd 作为
其运行时;Kubernetes 支持 docker(在 k8s1.24 版本之前用,1.24 开始废弃了)、containerd,
CRI-O 等多种容器运行时,这些容器运行时都遵循了 OCI 规范,并通过 runc 来实现与操作系统内核
交互来完成容器的创建和运行
备注:CRI
CRI 是一个插件接口,它使 kubelet 能够使用各种容器运行时,你需要在集群中的每个节点上都有一个
可以正常工作的容器运行时, 这样 kubelet 能启动 Pod 及其容器。容器运行时接口(CRI)是
kubelet 和容器运行时之间通信的主要协议。
OCI:
OCI, Open Container Initiative ,是一个轻量级,开放的治理结构(项目),在 Linux 基金会的支
持下成立,致力于围绕容器格式和运行时创建开放的行业标准。 OCI 项目由 Docker,CoreOS(后来
被 Red Hat 收购了,相应的席位被 Red Hat 继承)和容器行业中的其他领导者在 2015 年 6 月的时
候启动。
如果你使用 Docker 作为 K8S 容器运行时的话,kubelet 需要先要通过 dockershim 去调用 Docker,
再通过 Docker 去调用 containerd。
如果你使用 containerd 作为 K8S 容器运行时的话, kubelet 可以直接调用 containerd。
containerd对比docker优点
使用 containerd 不仅性能提高了(调用链变短了),而且资源占用也会变小(Docker 不是一个纯粹的
容器运行时,具有大量其他功能)。
调用链
Docker 作为 k8s 容器运行时,调用关系如下:
kubelet --> docker shim (在 kubelet 进程中) --> dockerd --> containerd
Containerd 作为 k8s 容器运行时,调用关系如下:
kubelet --> cri plugin(在 containerd 进程中) --> containerd
containerd 安装和配置
安装 docker 会自动把 containerd 安装出来,也可以通过如下命令直接安装 containerd
需要配置 docker-ce.repo 这个 yum 源:
[root@xianchaomaster1 ~]#yum install yum-utils -y
[root@xianchaomaster1 ~]#yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
[root@xianchaomaster1 ~]# yum install containerd -y
[root@xianchaomaster1 ~]# systemctl enable containerd
[root@xianchaomaster1 ~]# systemctl start containerd
初始化 Containerd 配置
[root@xianchaomaster1 ~]# containerd config default > /etc/containerd/config.toml
[root@xianchaomaster1 ~]# systemctl enable containerd
[root@xianchaomaster1 ~]# systemctl start containerd
替换 containerd 默认的 sand_box 镜像,编辑/etc/containerd/config.toml 文件:
sandbox_image = "k8s.gcr.io/pause:3.2" 替换成 registry.cnhangzhou.aliyuncs.com/google_containers/pause-amd64:3.2
应用配置并重新运行 containerd 服务
[root@xianchaomaster1 ~]# systemctl daemon-reload
[root@xianchaomaster1 ~]# systemctl restart containerd
[root@xianchaomaster1 ~]# systemctl status containerd
[root@xianchaomaster1 ~]# ctr images pull registry.cnhangzhou.aliyuncs.com/google_containers/pause-amd64:3.2
containerd 容器相关操作
#查看 containerd 命名空间
[root@xianchaomaster1 ~]# ctr namespace ls
ctr 有命名空间 namespace 来指定类似于工作空间的隔离区域。使用方法 ctr -n default images ls
来查看 default 命名空间的镜像,不加 -n 参数,默认也是使用 default 的命名空间。
#查看默认名称空间镜像有哪些
[root@xianchaomaster1 ~]# ctr image ls
#查看 k8s 命名空间下的镜像
[root@xianchaomaster1 ~]# ctr -n=k8s.io images ls
#拉取 busybox 镜像
[root@xianchaomaster1 ~]# ctr image pull docker.io/library/busybox:latest
注:必须全路径,从 dockerhub 上下载默认 busybox 镜像。
[root@xianchaomaster1 ~]# ctr images rm 删除镜像
#压缩镜像
[root@xianchaomaster1 ~]# ctr images pull docker.io/library/mysql:latest
[root@xianchaomaster1 ~]# ctr images export mysql.tar.gz
docker.io/library/mysql:latest
#导出镜像
[root@xianchaomaster1 ~]# ctr images import mysql.tar.gz
互动 1:docker 的镜像和 containerd 镜像通用吗?
答:通用的,docker save -o 生成的镜像文件,可以基于 ctr images import 导出来
基于 containerd 运行一个容器
这里要解释一个概念 containers 和 task ,在 docker 里面 container 概念被弱化 ,将 containers 和
task 整合在一起,基于 docker run 可以运行容器。
ctr 中 containers 是镜像实例化的一个虚拟环境,提供一个磁盘,模拟空间,就好比你电脑处于关机状
态一样。
ctr 中 tasks 是将容器运行起来,电脑开机了 ,初始化进程等 ,task 就是的这么个形式。
创建 task,运行容器
[root@xianchaomaster1 ~]# ctr run -d docker.io/library/busybox:latest busybox-v1
#查看该容器在宿主机的 PID:
[root@xianchaomaster1 ~]# ctr task ls
[root@xianchaomaster1 ~]# ctr task exec --exec-id 3118 -t busybox-v1 sh
#删除 task:
[root@xianchaomaster1 ~]# ctr task rm -f busybox-v1
删除容器:
[root@ xianchaomaster1 ~]# ctr c ls
CONTAINER IMAGE RUNTIME
busybox-v1 docker.io/library/busybox:latest io.containerd.runc.v2
[root@ xianchaomaster1 ~]# ctr c rm busybox-v1
#查看帮助命令:
[root@xianchaomaster1 ~]# ctr task --help
扩展:ctr 命令练习
列出镜像:
[root@xianchaomaster1 ~]# ctr image ls
给镜像打标签:
[root@xianchaomaster1 ~]# ctr i tag docker.io/library/busybox:latest
docker.io/library/busybox:v1
注意:如果 docker.io/library/busybox:v1 存在,可以强制替换
[root@xianchaomaster1 ~]# ctr i tag --force docker.io/library/busybox:latest
docker.io/library/busybox:v1
删除镜像:
[root@xianchaomaster1 ~]# ctr i rm docker.io/library/busybox:v1
查看容器:
[root@xianchaomaster1 ~]# ctr c ls
删除容器:
删除容器之前需要先停掉容器的 task
[root@ xianchaomaster1 ~]# ctr run -d docker.io/library/busybox:latest busybox-v1
[root@xianchaomaster1 ~]# ctr task ls
TASK PID STATUS
busybox-v1 38486 RUNNING
[root@xianchaomaster1 ~]# ctr c ls
CONTAINER IMAGE RUNTIME
busybox docker.io/library/busybox:latest io.containerd.runc.v2
busybox-v1 docker.io/library/busybox:latest io.containerd.runc.v2
停掉 task
[root@xianchaomaster1 ~]# ctr tasks kill --signal 9 busybox-v1
[root@xianchaomaster1 ~]# ctr task ls
TASK PID STATUS
busybox-v1 38486 STOPPED
[root@xianchaomaster1 ~]# ctr c delete busybox-v1
ctr 和 docker 命令比较
备注: ctr 并没有创建原始镜像的能力,也就是说无法进行 docker 的 build 和 commit 操作。
docker build 基于 dockerfile 可以构建镜像
ctr 命令无法构建镜像
配置 containerd 使用 harbor 私有镜像仓库
[root@xianchaomaster1 ~]# vim /etc/containerd/config.toml
修改 containerd 配置文件:
找到[plugins."io.containerd.grpc.v1.cri".registry.configs]这个位置,增加如下内容:
[plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.40.181:80".tls]
insecure_skip_verify = true # 是否跳过安全认证
[plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.40.181:80".auth]
username = "admin"
password = "Harbor12345"
找到[plugins."io.containerd.grpc.v1.cri".registry.mirrors]这个位置,增加如下内容:
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://registry.docker-cn.com"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."192.168.40.181:80"]
endpoint = ["http://192.168.40.181:80"]
如下:
修改完配置,重启 containerd:
[root@xianchaomaster1 ~]# systemctl restart containerd
从 harbor 里拉取镜像:
[root@xianchaomaster1 ~]# ctr images pull 192.168.40.181/test/tomcat:v1 --skipverify --user=admin:Harbor12345
把镜像传到 harbor 镜像仓库:
[root@xianchaomaster1 ~]# ctr images pull --all-platforms
docker.io/library/nginx:latest
[root@xianchaomaster1 ~]# ctr images tag docker.io/library/nginx:latest
192.168.40.181/test/nginx:v1
[root@xianchaomaster1 ~]# ctr images push 192.168.40.181/test/nginx:v1 --skipverify --user=admin:Harbor12345
chaomaster1 ~]# ctr images pull --all-platforms
docker.io/library/nginx:latest
[root@xianchaomaster1 ~]# ctr images tag docker.io/library/nginx:latest
192.168.40.181/test/nginx:v1
[root@xianchaomaster1 ~]# ctr images push 192.168.40.181/test/nginx:v1 --skipverify --user=admin:Harbor12345