轻量级工业级容器管理工具 Containerd

Kubernetes v1.24 之前的版本直接集成了 Docker Engine 的一个组件,名为 dockershim [用于调用Docker]。 这种特殊的直接整合不再是 Kubernetes 的一部分 (这次删除被作为 v1.20 发行版本的一部分宣布)。 这意味Kubernetes从版本1.24开始就弃用Docker作为容器运行时,取而代之的是更加轻量级的Containerd。

containerd可用作 Linux 和 Windows 的守护进程。它管理其主机系统的完整容器生命周期,从图像传输和存储到容器执行和监督,再到低级存储到网络附件等等。

1 Containerd 介绍


1.1、Containerd的由来


【Docker名噪一时,捐出runC】2013年docker公司在推出docker产品后,由于其对全球技术产生了一定的影响力,Google公司明显感觉到自己公司内部所使用的Brog系统江湖地位受到的威胁,希望Docker公司能够与自己联合打造一款开源的容器运行时作为Docker核心依赖,但Docker公司拒绝了;接着Google公司联合RedHat、IBM等公司说服Docker公司把其容器核心技术libcontainer捐给OCI(Open Container Intiative),并更名为runC。

【CNCF成立,kubernetes被迫开源】为了进一步遏制Docker在未来技术市场影响力,避免在容器市场上Docker一家独大,Google公司带领RedHat、IBM等成立了CNCF(Cloud Native Computing Fundation)基金会,即云原生计算基金会。CNCF的目标很明确,既然在容器应用领域无法与Docker相抗衡,那就做Google更有经验的技术市场——大规模容器编排应用场景。Google公司把自己内部使用的Brog系统开源——Kubernetes,也就是我们今天所说的云原生技术生态。

【Docker妥协,贡献出Containerd】2016年Docker公司推出了Docker Swarm,意在一统Docker生态,让Docker既可以实现容器应用管理,也可以实现大规模容器编排,经过近1年左右时间的市场验证后,发现在容器编排方面无法独立抗衡kubernetes,所以Docker公司于2017年正式宣布原生支持Kubernetes。至此,Docker在大规模容器编排应用市场败下阵来,但是Docker依然不甘心失败,把Docker核心依赖Containerd捐给了CNCF,依此说明Docker依旧是一个PaaS平台。

【k8s宣布不支持Docker,Containerd成为CRI主角】2020年CNCF基金会宣布Kubernetes 1.20版本将不再仅支持Docker容器管理工具,此事的起因主要也与Docker捐给CNCF基金会的Containerd有关,早期为了实现Kubernetes能够使用Docker实现容器管理,专门在Kubernetes组件中集成一个shim技术,用来将Kubernetes 容器运行时接口(CRI,Container Runntime Interface)调用翻译成Docker的API,这样就可以很好地使用Docker了。但是随着Kubernetes在全球技术市场的广泛应用,有更多的容器管理工具的出现,它们都想能够借助于Kubernetes被用户所使用,所以就提出标准化容器运行时接口,只要适配了这个接口就可以集成到Kubernetes生态当中,所以Kubernetes取消了对shim的维护,并且由于Containerd技术的成功,可以实现无缝对接Kubernetes,所以接下来Kubernetes容器运行时的主角是Containerd。

1.2、Containerd概念


早在2016年3月,Docker 1.11的Docker Engine里就包含了containerd,而现在则是把containerd从Docker Engine里彻底剥离出来,作为一个独立的开源项目独立发展,目标是提供一个更加开放、稳定的容器运行基础设施。

和原先包含在Docker Engine里containerd相比,独立的containerd将具有更多的功能,可以涵盖整个容器运行时管理的所有需求。另外独立之后containerd的特性演进可以和Docker Engine分开,专注容器运行时管理,可以更稳定。

Containerd是一个工业标准的容器运行时,重点是它简洁,健壮,便携,在Linux和window上可以作为一个守护进程运行,它可以管理主机系统上容器的完整的生命周期:镜像传输和存储,容器的执行和监控,低级别的存储和网络。

每个containerd只负责一台机器,Pull镜像,对容器的操作(启动、停止等),网络,存储都是由containerd完成。具体运行容器由runC负责,实际上只要是符合OCI规范的容器都可以支持。

Containerd和docker不同,containerd重点是集成在大规模的系统中,例如kubernetes、Swarm、Mesos等【对于容器编排服务来说,运行时只需要使用containerd+runC,更加轻量,容易管理。】。Containerd 被设计成嵌入到一个更大的系统中,而不是直接由开发人员或终端用户使用。

Containerd的特点:

  • 简洁的基于 gRPC 的 API 和 client library。

  • 完整的 OCI 支持(runtime 和 image spec)。

  • 同时具备稳定性和高性能的定义良好的容器核心功能。

  • 一个解耦的系统(让 image、filesystem、runtime 解耦合),实现插件式的扩展和重用。

Containerd的作用:

  • 管理容器的生命周期(从创建容器到销毁容器)。

  • 拉取/推送容器镜像。

  • 存储管理(管理镜像及容器数据的存储)。

  • 调用 runC 运行容器(与 runC 等容器运行时交互)。

  • 管理容器网络接口及网络。

使用 bucketbench 对 Docker、crio 和 Containerd 的性能测试结果,包括启动、停止和删除容器,以比较它们所耗的时间,可以发现Containerd 在各个方面都表现良好,总体性能优于 Docker 和 crio。

1.3、Containerd架构


Containerd 采用标准的 C/S 架构:服务端通过 GRPC 协议提供稳定的 API;客户端通过调用服务端的 API 进行高级的操作。

为了实现解耦,Containerd 将不同的职责划分给不同的组件,每个组件就相当于一个子系统(subsystem)。连接不同子系统的组件被称为模块。

Containerd 被分为三个大块: Storage 、 Metadata 和 Runtime。

Containerd 两大子系统为:

Bundle : 在 Containerd 中,Bundle 包含了配置、元数据和根文件系统数据,你可以理解为 容器的文件系统。而 Bundle 子系统允许用户从镜像中提取和打包 Bundles。

Runtime : Runtime 子系统用来执行 Bundles,比如创建容器。其中,每一个子系统的行为都由一个或多个模块协作完成(架构图中的 Core 部分)。

1.4、几个概念区分


containerd 是一个高级容器运行时,又名容器管理器。简单来说,它是一个守护进程,在单个主机上管理完整的容器生命周期:创建、启动、停止容器、拉取和存储镜像、配置挂载、网络等。

ctr 是作为 containerd 项目的一部分提供的命令行客户端。该ctr界面 [显然] 与 Docker CLI不兼容,乍一看,可能看起来不太用户友好。因为它的主要受众是测试守护进程的容器开发人员。ctr + containerd比docker + dockerd更接近实际的容器。

nerdctl 是一个相对较新的containerd命令行客户端。与ctr不同,nerdctl的目标是用户友好和docker兼容。在某种程度上,nerdctl + containerd可以无缝地替代docker + dockerd。

crictl 是一个命令行客户端,用于 [kubernetes] CRI兼容的容器运行时。引入 Kubernetes 容器运行时接口 (CRI)以使 Kubernetes 容器运行时不可知。Kubernetes节点代理kubelet实现了 CRI客户端 API,可以使用任何实现 CRI 服务器 API的容器运行时来管理其节点上的容器和 Pod。

2 Containerd 安装


2.1 Yum 方式安装


2.1.1 获取 Yum 源

# 获取阿里云YUW源
$ wget-o /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 查看Yum源中的Containerd软件
$ yum list | grep containerd
containerd.io.x86_64                     1.6.9-3.1.el7                docker

2.1.2 使用 Yum 命令安装

# 安装Containerd.io软件,即可安装Containerd
yum install -y containerd.io

2.1.3 验证安装及启动服务

# 使用rpm -qa命令查看是否安装
$ rpm-qa | grep containerd
containerd.io-1.6.9-3.1.el7.x86_64
# 使用containerd服务启动及开机自启动
systemctl enable --now containerd
​
# systemctl enable containerd
# systemctl start containerd
# 查看 Containerd 服务启动状态
$ systemctl status containerd.service
● containerd.service - containerd container runtime
   Loaded: loaded (/usr/lib/systemd/system/containerd.service; disabled; vendor preset: disabled)
   Active: active (running) since Tue 2022-11-2222:45:06 CST; 3 months 0 days ago # 此行第二列及第三列表示其正在运行状态
     Docs: https://containerd.io
 Main PID: 590 (containerd)
    Tasks: 17
   Memory: 65.1M
   CGroup: /system.slice/containerd.service
           └─590 /usr/bin/containerd
[......]

2.1.4 验证可用性

# 安装Containerd时ctr命令亦可使用,ctr命令主要用于管理容器及容器镜像等。
# 使用ctr命令查看containerd客户端及服务演相关信息。
$ ctr version
Client:
  Version:  1.6.9
  Revision: 1c90a442489720eec95342e1789ee8a5e1b9536f
  Go version: go1.18.7
​
Server:
  Version:  1.6.9
  Revision: 1c90a442489720eec95342e1789ee8a5e1b9536f
  UUID: 959685ab-9bd6-4dce-96a3-d059b70a63c1

2.2 二进制方式安装


Containerd有两种安装包:

  • 第一种是 containerd-[version],这种包用于单机测试没问题,不包含runC,需要提前安装。

  • 第二种是 cri-containerd-cni-[version],包含runC和Kubernetes里的所需要的相关文件。Kubernetes集群里需要用到此包。虽然包含runC,但是依赖系统中的seccomp (安全计算模式,是一种限制容器调用系统资源的模式。)

2.2.1 获取安装包

Containerd官网:https://containerd.io/

Containerd官方安装步骤:https://github.com/containerd/containerd/blob/main/docs/getting-started.md

下载好相应的安装部署包 [ 所有安装包都可在github上进行下载 ] 如下:

# 下载Containerd安装包
wget https://github.com/containerd/containerd/releases/download/v1.6.8/cri-containerd-1.6.8-linux-amd64.tar.gz

2.2.2 安装并测试可用性

2.2.2.1 Containerd

二进制安装不用这么麻烦,官网看到直接解压缩到根目录就行了$ tar -zxf cri-containerd-cni-1.6.8-linux-amd64.tar.gz -C /

# 查看已经获取的安装包
$ ls
cri-containerd-1.6.8-linux-amd64.tar.gz
# 解压已经下载的软件包
$ tar-zxvf cri-containerd-1.6.8-linux-amd64.tar.gz
# 查看解压后的目录
$ ls-l
total 89880
-rw-r--r--1 root root 92034038 Aug  9  2022 cri-containerd-1.6.8-linux-amd64.tar.gz
drwxr-xr-x 3 root root       40 Feb 2222:46 etc
drwxr-xr-x 3 root root       24 Feb 2222:46 opt
drwxr-xr-x 3 root root       19 Aug  9  2022 usr
# 查看etc目录,主要为containerd服务管理配置文件及cni虚拟网卡配置文件
$ ls-lR etc/
etc/:
total 4
-rw-r--r--1 root root 57 Aug  9  2022 crictl.yaml
drwxr-xr-x 3 root root 20 Aug  9  2022 systemd
​
etc/systemd:
total 0
drwxr-xr-x 2 root root 32 Aug  9  2022 system
​
etc/systemd/system:
total 4
-rw-r--r--1 root root 1270 Aug  9  2022 containerd.service
​
# 查看opt目录,主要为GCC环境中使用containerd配置文件及cni插件
$ ls-lR opt/
opt/:
total 0
drwxr-xr-x 3 root root 21 Aug  9  2022 containerd
​
opt/containerd:
total 0
drwxr-xr-x 3 root root 32 Aug  9  2022 cluster
​
opt/containerd/cluster:
total 4
drwxr-xr-x 3 root root 75 Aug  9  2022 gce
-rw-r--r--1 root root 28 Aug  9  2022 version
​
opt/containerd/cluster/gce:
total 20
drwxr-xr-x 2 root root   42 Aug  9  2022 cloud-init
-rw-r--r--1 root root  491 Aug  9  2022 cni.template
-rwxr-xr-x1 root root 9370 Aug  9  2022 configure.sh
-rw-r--r--1 root root 1173 Aug  9  2022 env
​
opt/containerd/cluster/gce/cloud-init:
total 16
-rw-r--r--1 root root 6255 Aug  9  2022 master.yaml
-rw-r--r--1 root root 6149 Aug  9  2022node.yaml
​
# 查看usr目录,主要为containerd运行时文件,包含runC
$ ls-lR usr/
usr/:
total 0
drwxr-xr-x 4 root root 29 Aug  9  2022 local
​
usr/local:
total 0
drwxr-xr-x 2 root root 193 Aug  9  2022 bin
drwxr-xr-x 2 root root  18 Aug  9  2022 sbin
​
usr/local/bin:
total 229676
-rwxr-xr-x1 root root 59608896 Aug  9  2022 containerd
-rwxr-xr-x1 root root  7389184 Aug  9  2022 containerd-shim
-rwxr-xr-x1 root root  9555968 Aug  9  2022 containerd-shim-runc-v1
-rwxr-xr-x1 root root  9580544 Aug  9  2022 containerd-shim-runc-v2
-rwxr-xr-x1 root root 25739552 Aug  9  2022 containerd-stress
-rwxr-xr-x1 root root 33114367 Aug  9  2022 crictl
-rwxr-xr-x1 root root 34326986 Aug  9  2022 critest
-rwxr-xr-x1 root root 25586864 Aug  9  2022 ctd-decoder
-rwxr-xr-x1 root root 30277472 Aug  9  2022 ctr
​
usr/local/sbin:
total 14180
-rwxr-xr-x1 root root 14518072 Aug  9  2022 runc
2.2.2.2 查看Containerd 安装位置
# 查看containerd.service文件,了解containerd文件保存位置
$ cat etc/systemd/system/containerd.service
# Copyright The containerd Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
​
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target
​
[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/containerd # 查看此位置,把containerd二进制文件放置于此处即可完成安装
​
Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=infinity
# Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this version.
TasksMax=infinity
OOMScoreAdjust=-999
​
[Install]
WantedBy=multi-user.target
2.2.2.3 复制 containerd 运行时文件至系统
# 查看主机/usr/local/bin目录,。里面没有任何内容。
$ ls /usr/local/bin/
​
# 查看解压后usr/local/bin目录,里面包含containerd运行时文件
$ ls usr/local/bin/
containerd       containerd-shim-runc-v1  containerd-stress  critest      ctr
containerd-shim  containerd-shim-runc-v2  crictl             ctd-decoder
​
# 复制containerd文件至/usr/local/bin目录中,本次可仅复制containerd一个文件也可复制全部文件。
$ cp usr/local/bin/containerd /usr/local/bin/
$ ls-l /usr/local/bin/containerd
2.2.2.4 添加containerd.service文件至系统
# 查看解压后的etc/system目录
$ ls etc/systemd/system/
containerd.service
​
# 复制containerd股务管理配置文件至/usr/lib/systemd/system/目录中
$ cp etc/systemd/system/containerd.service /usr/lib/systemd/system/containerd.service
​
# 查看复制后结果
$ ls-l /usr/lib/systemd/system/containerd.service
2.2.2.5 查看containerd 使用帮助
$ containerd--help
NAME:
   containerd -
                    __        _                     __
  _________  ____  / /_____ _(_)___  ___  _________/ /
 / ___/ __ \/ __ \/ __/ __ `/ / __ \/ _ \/ ___/ __  /
/ /__/ /_/ / / / / /_/ /_/ / / / / /  __/ /  / /_/ /
\___/\____/_/ /_/\__/\__,_/_/_/ /_/\___/_/   \__,_/
​
high performance container runtime
​
​
USAGE:
   containerd [global options] command [command options] [arguments...]
​
VERSION:
   v1.6.8
​
DESCRIPTION:
​
containerd is a high performance container runtime whose daemon can be started
by using this command. If none of the *config*, *publish*, or *help* commands
are specified, the default action of the **containerd** command is to start the
containerd daemon in the foreground.
​
​
A default configuration is used if no TOML configuration is specified or located
at the default file location. The *containerd config* command can be used to
generate the default configuration for containerd. The output of that command
can be used and modified as necessary as a custom configuration.
​
COMMANDS:
   config    information on the containerd config
   publish   binary to publish events to containerd
   oci-hook  provides a base for OCI runtime hooks to allow arguments to be injected.
   help, h   Shows a list of commands or help for one command
​
GLOBAL OPTIONS:
   --config value, -c value     path to the configuration file (default: "/etc/containerd/config.toml")
   --log-level value, -l value  set the logging level [trace, debug, info, warn, error, fatal, panic]
   --address value, -a value    address for containerd's GRPC server
   --root value                 containerd root directory
   --state value                containerd state directory
   --help, -h                   show help
   --version, -v                print the version
2.2.2.6 生成containerd模块配置文件
2.2.2.6.1 生成默认模块配置文件

Containerd的式认配置文件为/etc/containerd/config.toml,可以使用containerd config default > /etc/containerd/config.toml合合创建一份模块配著文件

# 创建配置文件目录
$ mkdir-pv /etc/containerd
​
# 生成配置文件
$ containerd config default > /etc/containerd/config.toml
​
# 查看配置文件
$ cat /etc/containerd/config.toml
disabled_plugins = []
imports = []
oom_score =0
plugin_dir =""
required_plugins = []
root ="/var/lib/containerd"# Containerd 运行相关的状态所在的目录
state ="/run/containerd"
temp =""
version =2
​
[grpc]
  address ="/run/containerd/containerd.sock"
  gid =0
  max_recv_message_size =16777216
  max_send_message_size =16777216
  tcp_address =""
  tcp_tls_ca =""
  tcp_tls_cert =""
  tcp_tls_key =""
  uid =0
​
# Containerd 的插件
[plugins]
    [plugins."io.containerd.grpc.v1.cri"]
        [......]
    sandbox_image ="k8s.gcr.io/pause:3.6"# 由于网络原因,此处需要替换 dragonzw/pause-amd64:3.6
[......]
2.2.2.6.2 替换默认模块配置文件

但上述配置文件后期改动的地方较多,K8s 环境使用的配置文件并配置好镜像加速器。

$ vim /etc/containerd/config.toml
      sandbox_image ="dragonzw/pause-amd64:3.6"
    [plugins.cri.registry.mirrors."harbor.ks.com"] # 此处添加了本地容器镜像仓库Harbor,作为本地容器镜像仓库
      endpoint = [
            "http://harbor.ks.com"
        ]
2.2.2.7 启动Containerd 服务并设置开机自启动
$ systemctl enable --now containerd
​
# systemctl enable containerd
# systemctl start containerd
​
# 查看Containerd服务状态
$ systemctl status containerd
● containerd.service - containerd container runtime
   Loaded: loaded (/usr/lib/systemd/system/containerd.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2023-02-2223:27:53 CST; 17s ago
     Docs: https://containerd.io
  Process: 9739ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
 Main PID: 9741 (containerd)
    Tasks: 11
   Memory: 26.1M
   CGroup: /system.slice/containerd.service
           └─9741 /usr/local/bin/containerd
[......]
2.2.2.8 复制ctr命令至系统
cp usr/local/bin/ctr /usr/bin
2.2.2.9 查看已安装containerd服务版本
$ ctr version
Client:
  Version:  v1.6.8
  Revision: 9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6
  Go version: go1.17.13
​
Server:
  Version:  v1.6.8
  Revision: 9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6
  UUID: c42e46cd-4a10-4ea1-94b6-a79299cf1178
​
# 至此,containerd安装完成。

Containerd 用来做容器管理的,例如容器的生命周期管理,容器的镜像,容器的相关网络配置

runC 用来真正运行容器的

2.2.2.10 安装 runC

由于二进制也中提供的runC默认需要系统中安装seccomp支持。需要单独安装,且不同版本runC对seccomp版本要求一致,所以建议单独下载runC二进制包进行安装,里面包含了seccomp模块支持。

2.2.2.10.1 获取 runC

# 使用 wget 下载

wget https://github.com/opencontainers/runc/releases/download/v1.1.4/runc.amd64
2.2.2.10.2 安装runC并验证安装结果
# 查看已经下载文件
$ ls-l runc.amd64
​
# 安装runC
$ mv runc.amd64 /usr/sbin/runc
​
# 为runC添加可执行权限
$ chmod+x /usr/sbin/runc
​
# 使用runC命令验证是否安装成功
$ runc-v
runc version 1.1.4
commit: v1.1.4-0-g5fd4c4d1
spec: 1.0.2-dev
go: go1.17.10
libseccomp: 2.5.4
2.2.2.11 安装cni插件和cni工具包
$ mkdir-p /home/cni-plugins
$ wget https://github.com/containernetworking/plugins/releases/download/v1.0.1/cni-plugins-linux-amd64-v1.0.1.tgz
$ tar-zxvf cni-plugins-linux-amd64-v1.0.1.tgz -C /home/cni-plugins
$ ls /home/cni-plugins/
bandwidth  dhcp      host-device  ipvlan    macvlan  ptp  static  vlan
bridge     firewall  host-local   loopback  portmap  sbr  tuning  vrf
​
# 该二进制文件是静态构建的,可以在任何 Linux 发行版上运行
# cni工具1.1.2兼容cni插件1.0.0
$ mkdir-p /home/cni-tools
$ wget https://github.com/containernetworking/cni/archive/refs/tags/v1.1.2.tar.gz
$ tar-xzvf cni-1.1.2.tar.gz -C /home/cni-tools # --strip-components=1 

3 Containerd 容器镜像管理


ctr是作为 containerd 项目的一部分提供的命令行客户端。

该ctr界面 [显然] 与 Docker CLI不兼容,,可能看起来不太用户友好。显然,它的主要受众是测试守护进程的容器开发人员。但是,由于它最接近实际的 containerd API,因此它可以作为一种很好的探索手段 --- 通过检查可用命令,可以大致了解 containerd 可以做什么和不可以做什么。

3.1 Containerd 容器镜像管理命令


  • docker使用docker images命令管理镜像

  • 单机containerd使用ctr images命令管理境像,containerd 本身的CLI

  • Kubernetes 中 containerd使用crictl images合令管理提像,Kubernetes社区的专用CLI工具

# 获取命令帮助
$ ctr--help
NAME:
   ctr -
        __
  _____/ /______
 / ___/ __/ ___/
/ /__/ /_/ /
\___/\__/_/
​
containerd CLI
​
​
USAGE:
   ctr [global options] command [command options] [arguments...]
​
VERSION:
   v1.6.8
​
DESCRIPTION:
​
ctr is an unsupported debug and administrative client for interacting
with the containerd daemon. Because it is unsupported, the commands,
options, and operations are not guaranteed to be backward compatible or
stable from release to release of the containerd project.
​
COMMANDS:
   plugins, plugin            provides information about containerd plugins
   version                    print the client and server versions
   containers, c, container   manage containers
   content                    manage content
   events, event              display containerd events
   images, image, i           manage images
   leases                     manage leases
   namespaces, namespace, ns  manage namespaces
   pprof                      provide golang pprof outputs for containerd
   run                        run a container
   snapshots, snapshot        manage snapshots
   tasks, t, task             manage tasks
   install                    install a new package
   oci                        OCI tools
   shim                       interact with a shim directly
   help, h                    Shows a list of commands or help for one command
​
GLOBAL OPTIONS:
   --debug                      enable debug output in logs
   --address value, -a value    address for containerd's GRPC server (default: "/run/containerd/containerd.sock") [$CONTAINERD_ADDRESS]
   --timeout value              total timeout for ctr commands (default: 0s)
   --connect-timeout value      timeout for connecting to containerd (default: 0s)
   --namespace value, -n value  namespace to use with commands (default: "default") [$CONTAINERD_NAMESPACE]
   --help, -h                   show help
   --version, -v                print the version

3.2 查看镜像


$ ctr images ls# ctr images list
REF TYPE DIGEST SIZE PLATFORMS LABELS

3.3 下载镜像


containerd支持oci标准的提像,所以可以直接使用Docker官方或Dockerfile构建的镜像
# 拉取镜像  拉取镜像,完全合格的参考似乎是必需的,所以不能忽略镜像仓库或标签部分。
$ ctr images pull --all-platforms docker.io/library/nginx:alpine
# --all-platforms  指定所有平台镜像  
# --platform       指定系统平台
​
# 查看系统的架构
$ uname-a
Linux k8s-master 3.10.0-1160.71.1.el7.x86_64 #1 SMP Tue Jun 28 15:37:28 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
​
# 如果不指定,默认就是当前系统的架构来拉取
$ ctr images pull --platform linux/amd64 docker.io/library/nginx:latest
说明:ctr命令pull镜像时,不能直接把领像名字写成"nginx:alpine"
# 查看已经下载容器镜像
$ ctr images ls
REF                            TYPE                                                      DIGEST                                                                  SIZE     PLATFORMS                                                                                               LABELS
docker.io/library/nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:6f94b7f4208b5d5391246c83a96246ca204f15eaf7e636cefda4e6348c8f6101 15.9 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x                -
docker.io/library/nginx:latest application/vnd.docker.distribution.manifest.list.v2+json sha256:6650513efd1d27c1f8a5351cbd33edf85cc7e0d9d0fcb4ffb23d8fa89b601ba8 54.3 MiB linux/386,linux/amd64,linux/arm/v5,linux/arm/v7,linux/arm64/v8,linux/mips64le,linux/ppc64le,linux/s390x -

REF

TYPE

DIGEST

SIZE

PLATFORMS

LABELS

docker.io/library/nginx:alpine

application/vnd.docker.distribution.manifest.list.v2+json

6f94b7f4208b5d5391246c83a96246ca204f15eaf7e636cefda4e6348c8f6101

15.9 MiB

linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x

-

# 指定平台下载容器镜像
$ ctr images pull --platform linux/amd64 docker.io/library/nginx:latest

3.4 镜像挂载


方便查看镜像中包含的内容。
# 把已下载的容器镜像挂载至当前文件系统
$ ctr images mount docker.io/library/nginx:alpine /mnt
sha256:9ca6be4cd63171f17f0a5e2ea28d5361a299672f41bd65223e7eac7d3d57e76d
/mnt
​
# 查看挂载内容
$ ls /mnt
bin  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
# 卸载
$ umount /mnt
# ctr images unmount /mnt

3.5 镜像导出


# 把容器镜像导出
$ ctr image export--all-platforms nginx.img docker.io/library/nginx:alpine
说明:--all-platforms,导出所有平台镜像,本版本为1.6版本,1.4版本不需要添加此选项。
# 查看已经导出容器镜像
$ ls-lh nginx.img
-rw-r--r--1 root root 105M Feb 2300:57 nginx.img

3.6 镜像删除


# 删除指定容器镜像
$ ctr image rm docker.io/library/nginx:alpine
​
# 再次查看容器镜像
$ ctr images ls# ctr images list
REF TYPE DIGEST SIZE PLATFORMS LABELS

3.7 镜像导入


# 导入容器镜像
$ ctr image import nginx.img
unpacking docker.io/library/nginx:alpine (sha256:6f94b7f4208b5d5391246c83a96246ca204f15eaf7e636cefda4e6348c8f6101)...done
​
$ ctr image ls
REF                            TYPE                                                      DIGEST                                                                  SIZE     PLATFORMS                                                                                               LABELS
docker.io/library/nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:6f94b7f4208b5d5391246c83a96246ca204f15eaf7e636cefda4e6348c8f6101 15.9 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x                -

3.8 修改镜像Tag


$ ctr image tag docker.io/library/nginx:alpine nginx:alpine
nginx:alpine
​
$ ctr image tag docker.io/library/nginx:alpine harbor.kubesphere.com/library/nginx:alpine
harbor.kubesphere.com/library/nginx:alpine
说明:把docker.io/library/nginx:alpine修改为nginx:alpine
# 查看修改后的容器镜像
$  ctr image ls
REF                            TYPE                                                      DIGEST                                                                  SIZE     PLATFORMS                                                                                               LABELS
docker.io/library/nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:6f94b7f4208b5d5391246c83a96246ca204f15eaf7e636cefda4e6348c8f6101 15.9 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x                -
nginx:alpine                   application/vnd.docker.distribution.manifest.list.v2+json sha256:6f94b7f4208b5d5391246c83a96246ca204f15eaf7e636cefda4e6348c8f6101 15.9 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x
​
# 修改后对容器镜像做检查对比
$ ctr images check
REF                            TYPE                                                      DIGEST                                                                  STATUS         SIZE              UNPACKED
docker.io/library/nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:6f94b7f4208b5d5391246c83a96246ca204f15eaf7e636cefda4e6348c8f6101 complete (8/8) 15.9 MiB/15.9 MiB true
nginx:alpine                   application/vnd.docker.distribution.manifest.list.v2+json sha256:6f94b7f4208b5d5391246c83a96246ca204f15eaf7e636cefda4e6348c8f6101 complete (8/8) 15.9 MiB/15.9 MiB true

3.9 镜像对比


# 镜像对比
$ ctr images check

3.10 配置镜像加速


3.10.1 修改config.toml 配置文件

$ vim /etc/containerd/config.toml
    [plugins."io.containerd.grpc.v1.cri".registry]
      config_path ="/etc/containerd/certs.d"  # 镜像地址配置文件
​
      [plugins."io.containerd.grpc.v1.cri".registry.auths]
​
      [plugins."io.containerd.grpc.v1.cri".registry.configs]
​
      [plugins."io.containerd.grpc.v1.cri".registry.headers]
​
      [plugins."io.containerd.grpc.v1.cri".registry.mirrors]

3.10.2 创建相应的目录

mkdir-pv /etc/containerd/certs.d

3.10.3 配置加速

mkdir-pv /etc/containerd/certs.d/docker.io
cat > /etc/containerd/certs.d/docker.io/hosts.toml << EOF
server ="https://docker.io"
[host."https://po13h3y1.mirror.aliyuncs.com"]
  capabilities = ["pull", "resolve"]
EOF

3.10.4 重启Containerd

systemctl restart containerd

4 Containerd 容器管理


4.1 获取命令帮助


4.1.1 获取 ctr 命令帮助

$ ctr--help
NAME:
   ctr -
        __
  _____/ /______
 / ___/ __/ ___/
/ /__/ /_/ /
\___/\__/_/
​
containerd CLI
​
​
USAGE:
   ctr [global options] command [command options] [arguments...]
​
VERSION:
   v1.6.8
​
DESCRIPTION:
​
ctr is an unsupported debug and administrative client for interacting
with the containerd daemon. Because it is unsupported, the commands,
options, and operations are not guaranteed to be backward compatible or
stable from release to release of the containerd project.
​
COMMANDS:
   plugins, plugin            provides information about containerd plugins
   version                    print the client and server versions
   containers, c, container   manage containers
   content                    manage content
   events, event              display containerd events
   images, image, i           manage images
   leases                     manage leases
   namespaces, namespace, ns  manage namespaces
   pprof                      provide golang pprof outputs for containerd
   run                        run a container
   snapshots, snapshot        manage snapshots
   tasks, t, task             manage tasks
   install                    install a new package
   oci                        OCI tools
   shim                       interact with a shim directly
   help, h                    Shows a list of commands or help for one command
​
GLOBAL OPTIONS:
   --debug                      enable debug output in logs
   --address value, -a value    address for containerd's GRPC server (default: "/run/containerd/containerd.sock") [$CONTAINERD_ADDRESS]
   --timeout value              total timeout for ctr commands (default: 0s)
   --connect-timeout value      timeout for connecting to containerd (default: 0s)
   --namespace value, -n value  namespace to use with commands (default: "default") [$CONTAINERD_NAMESPACE]
   --help, -h                   show help
   --version, -v                print the version

4.1.2 获取创建静态容器命令帮助

$ ctr container --help
NAME:
   ctr containers - manage containers
​
USAGE:
   ctr containers command [command options] [arguments...]
​
COMMANDS:
   create                   create container
   delete, del, remove, rm  delete one or more existing containers
   info                     get info about a container
   list, ls                 list containers
   label                    set and clear labels for a container
   checkpoint               checkpoint a container
   restore                  restore a container from checkpoint
​
OPTIONS:
   --help, -h  show help
说明:
使用 "ctr container create"命令创建容器后,容器并没有处于运行状态,其只是一个静态的容器。这个container对象只是包含了运行一个容器所需的资源及配置的数据结构,例如:namespaces,rootfs和容器的配置信息都已经初始化成功了,只是用户进程 (本案例说为nginx) 还没有启动。需要使用"ctr tasks”命令才能获取一个动态容器。

4.1.3 获取动态容器命令帮助

$ ctr run --help
NAME:
   ctr run - run a container
​
USAGE:
   ctr run [command options] [flags] Image|RootFS ID [COMMAND] [ARG...]
​
OPTIONS:
   --rm                                    remove the container after running
   --null-io                               send all IO to /dev/null
   --log-uri value                         log uri
   --detach, -d                            detach from the task after it has started execution
   --fifo-dir value                        directory used for storing IO FIFOs
   --cgroup value                          cgroup path (To disable use of cgroup, set to "" explicitly)
   --platform value                        run image for specific platform
   --cni                                   enable cni networking for the container
   --runc-binary value                     specify runc-compatible binary
   --runc-root value                       specify runc-compatible root
   --runc-systemd-cgroup                   start runc with systemd cgroup manager
   --uidmap container-uid:host-uid:length  run inside a user namespace with the specified UID mapping range; specified with the format container-uid:host-uid:length
   --gidmap container-gid:host-gid:length  run inside a user namespace with the specified GID mapping range; specified with the format container-gid:host-gid:length
   --remap-labels                          provide the user namespace ID remapping to the snapshotter via label options; requires snapshotter support
   --cpus value                            set the CFS cpu quota (default: 0)
   --cpu-shares value                      set the cpu shares (default: 1024)
   --snapshotter value                     snapshotter name. Empty value stands for the default value. [$CONTAINERD_SNAPSHOTTER]
   --snapshotter-label value               labels added to the new snapshot for this container.
   --config value, -c value                path to the runtime-specific spec config file
   --cwd value                             specify the working directory of the process
   --env value                             specify additional container environment variables (e.g. FOO=bar)
   --env-file value                        specify additional container environment variables in a file(e.g. FOO=bar, one per line)
   --label value                           specify additional labels (e.g. foo=bar)
   --mount value                           specify additional container mount (e.g. type=bind,src=/tmp,dst=/host,options=rbind:ro)
   --net-host                              enable host networking for the container
   --privileged                            run privileged container
   --read-only                             set the containers filesystem as readonly
   --runtime value                         runtime name (default: "io.containerd.runc.v2")
   --runtime-config-path value             optional runtime config path
   --tty, -t                               allocate a TTY for the container
   --with-ns value                         specify existing Linux namespaces to join at container runtime (format '<nstype>:<path>')
   --pid-file value                        file path to write the task's pid
   --gpus value                            add gpus to the container
   --allow-new-privs                       turn off OCI spec's NoNewPrivileges feature flag
   --memory-limit value                    memory limit (in bytes) for the container (default: 0)
   --device value                          file path to a device to add to the container; or a path to a directory tree of devices to add to the container
   --cap-add value                         add Linux capabilities (Set capabilities with 'CAP_' prefix)
   --cap-drop value                        drop Linux capabilities (Set capabilities with 'CAP_' prefix)
   --seccomp                               enable the default seccomp profile
   --seccomp-profile value                 file path to custom seccomp profile. seccomp must be set to true, before using seccomp-profile
   --apparmor-default-profile value        enable AppArmor with the default profile with the specified name, e.g. "cri-containerd.apparmor.d"
   --apparmor-profile value                enable AppArmor with an existing custom profile
   --rdt-class value                       name of the RDT class to associate the container with. Specifies a Class of Service (CLOS) for cache and memory bandwidth management.
   --rootfs                                use custom rootfs that is not managed by containerd snapshotter
   --no-pivot                              disable use of pivot-root (linux only)
   --cpu-quota value                       Limit CPU CFS quota (default: -1)
   --cpu-period value                      Limit CPU CFS period (default: 0)
   --rootfs-propagation value              set the propagation of the container rootfs
说明:
使用"ctr run"命令可以创建一个静态容器并使其运行。一步到位运行容器。

4.2 查看容器


container 表示静态容器,可用 c 缩写代表container
$ ctr container ls
CONTAINER    IMAGE    RUNTIME
​
# 或者
$ ctr c ls
CONTAINER    IMAGE    RUNTIME

4.3 查看任务


task 表示容器里跑的进程,可用 t 缩写代表task
$ ctr task ls
TASK    PID    STATUS
​
# 或者
$ ctr t ls
TASK    PID    STATUS

4.4 创建静态容器


# 创建[静态]容器
# ctr containers create [command options] [flags] Image|RootFS CONTAINER [COMMAND] [ARG...]
$ ctr container create docker.io/library/nginx:alpine nginx1
# 一定要有镜像,才能创建容器
​
# 查看[静态]容器列表
$ ctr container ls
CONTAINER    IMAGE                             RUNTIME
nginx1       docker.io/library/nginx:alpine    io.containerd.runc.v2
​
# 查看容器的详细信息显示
$ ctr container info nginx1

4.5 静态容器启动为动态容器


# 复制containerd连接runc垫片工具至系统
# 若没有这个垫片就会使得静态容器启动为动态容器报错失败
$ ls usr/local/bin/
containerd       containerd-shim-runc-v1  containerd-stress  critest      ctr
containerd-shim  containerd-shim-runc-v2  crictl             ctd-decoder
$ cp usr/local/bin/containerd-shim-runc-v2 /usr/bin 
​
# 启动[动态]容器  创建容器和任务子命令分离
# 启动task,即表示在容器中运行了进程,即为动态容器
# -d 后台运行
$ ctr task start-d nginx1
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
​
# 查看动态容器列表
$ ctr task ls
TASK      PID      STATUS
nginx1    12920    RUNNING
​
# 直接运行一个动态容器[容器的IP就是宿主机的IP]
# ctr运行命令实际上是ctr容器创建 + ctr任务启动的快捷方式
$ ctr run -d--net-host docker.io/library/nginx:alpine nginx2
说明:-d表示daemon或者后台的意思,否则会卡住终端
# 查看容器所在宿主机的进程,是以宿主机进程的方式存在的
$ ctr task ls
TASK      PID      STATUS
nginx1    12920    RUNNING
# 查看容器的进程(都是物理机的进程)
$ ctr task ps nginx1
PID      INFO
12920    -
12956    -
12957    -
12958    -
12959    -
​
# 在物理机上查看进程
$ ps-ef | grep nginx
root      12890      1  003:11 ?        00:00:00 /usr/local/bin/containerd-shim-runc-v2 -namespace default -id nginx1 -address /run/containerd/containerd.sock
root      12920  12890  003:11 ?        00:00:00 nginx: master process nginx -g daemon off;
101       12956  12920  003:11 ?        00:00:00 nginx: worker process
101       12957  12920  003:11 ?        00:00:00 nginx: worker process
101       12958  12920  003:11 ?        00:00:00 nginx: worker process
101       12959  12920  003:11 ?        00:00:00 nginx: worker process

4.6 进入到容器操作


$ ctr task exec --exec-id1 nginx1 /bin/sh
# 直接在换行中输入命令即可,就可以操作容器
# 查看网卡信息
ifconfig
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
​
# 访问本地提供的Web服务
curl http://127.0.0.1
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0--:--:-- --:--:-- --:--:--     0<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
​
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
​
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
100   615  100   615    0     0   272k      0--:--:-- --:--:-- --:--:--  300k
​
# 为容器中运行的网站添加网站文件
echo"hello ksnginx" > /usr/share/nginx/html/index.html
​
# 在容器里访问Web服务
curl http://127.0.0.1
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    14  100    14    0     0  20497      0--:--:-- --:--:-- --:--:-- 14000
hello ksnginx
​
# 退出容器
exit
说明:
为exec进程设定一个id,可以随意能入,只要保证唯一即可,也可使用$RANDOM变量。

4.7 直接运行一个动态容器


$ ctr run -d--net-host docker.io/library/nginx:alpine nginx2
说明:
-d 代表 dameon,后台运行
--net-host 代表容器的IP就是宿主机的IP(相当于 docker 里的 host 类型网络)
# 查看已经运行的容器
$ ctr container ls
CONTAINER    IMAGE                             RUNTIME
nginx2       docker.io/library/nginx:alpine    io.containerd.runc.v2
​
# 查看已经运行容器中的进程,即task
$ ctr task ls
TASK      PID      STATUS
nginx2    15648    RUNNING
​
# 进入容器
$ ctr task exec --exec-id1 nginx2 /bin/sh
# 可以查看到获取的是宿主机的网络命名空间的信息
ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:FE:D2:0A:E2
          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
​
ens33     Link encap:Ethernet  HWaddr 00:0C:29:60:A9:17
          inet addr:10.0.0.30  Bcast:10.0.0.255  Mask:255.255.255.0
          inet6 addr: fe80::2ee1:c8f5:d4ec:224f/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:802384 errors:0 dropped:0 overruns:0 frame:0
          TX packets:405698 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:763172724 (727.8 MiB)  TX bytes:26556125 (25.3 MiB)
​
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:192 errors:0 dropped:0 overruns:0 frame:0
          TX packets:192 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:16320 (15.9 KiB)  TX bytes:16320 (15.9 KiB)
​
# 为容器中运行的网站添加网站文件
echo"hello containerd page" > /usr/share/nginx/html/index.html
# 退出容器
exit
​
# 在宿主机上访问网站
$ curl http://127.0.0.1
hello containerd page

4.8 暂停容器


# 查看容器状态
$ ctr tasks ls
TASK      PID      STATUS
nginx1    12920    RUNNING
​
# 暂停容器: 是暂停了用户进程在容器中的运行
$ ctr tasks pause nginx1
​
# 再次查看容器状态,看到其状态是PAUSED,表示停止
$ ctr tasks ls
TASK      PID      STATUS
nginx1    12920    PAUSED

4.9 恢复容器


# 使用resume命令恢复容器
$ ctr tasks resume nginx1
​
# 查看恢复后的状态
$ ctr tasks ls
TASK      PID      STATUS
nginx1    12920    RUNNING

4.10 停止容器


$ ctr tasks --help
NAME:
   ctr tasks - manage tasks
​
USAGE:
   ctr tasks command [command options] [arguments...]
​
COMMANDS:
   attach                   attach to the IO of a running container
   checkpoint               checkpoint a container
   delete, del, remove, rm  delete one or more tasks
   exec                     execute additional processes in an existing container
   list, ls                 list tasks
   kill                     signal a container (default: SIGTERM)
   pause                    pause an existing container
   ps                       list processes for container
   resume                   resume a paused container
   start                    start a container that has been created
   metrics, metric          get a single data point of metrics for a task with the built-in Linux runtime
​
OPTIONS:
   --help, -h  show help
# 使用 kill 命令停止容器中运行的进程,即为停止容器
$ ctr tasks kill nginx2
​
# 查看容器停止状态:
$ ctr tasks ls
TASK      PID      STATUS
nginx2    15648    STOPPED

4.11 删除容器


# 删除动态容器[必须先停止task或者先删除task]
$ ctr task delete nginx2
​
# 查看静态容器,确认其还在系统中
$ ctr container ls
CONTAINER    IMAGE                             RUNTIME
nginx2       docker.io/library/nginx:alpine    io.containerd.runc.v2
​
# 删除静态容器
$ ctr container delete nginx2

5 Containerd 使用私有容器镜像仓库Harbor


6 Containerd NameSpace 管理


containerd 中 namespace 的作用为:隔离运行的容器,可以实现运行多个容器。

# 查看NameSpace帮助命令
$  ctr namespace --help
NAME:
   ctr namespaces - manage namespaces
​
USAGE:
   ctr namespaces command [command options] [arguments...]
​
COMMANDS:
   create, c   create a new namespace
   list, ls    list namespaces
   remove, rm  remove one or more namespaces
   label       set and clear labels for a namespace
​
OPTIONS:
   --help, -h  show help
​
# 创建命名空间
$ ctr namespace create testns
​
# 查看命名空间
$ ctr namespace ls
NAME    LABELS
default
testns
​
# 在命名空间中进行镜像,容器等相关操作
# --namespace value, -n value  namespace to use with commands (default: "default") [$CONTAINERD_NAMESPACE
$ ctr--namespace testns images pull docker.io/library/nginx:latest
$ ctr--namespace testns images ls
$ ctr--namespace testns container create docker.io/library/nginx:latest
$ ctr--namespace testns container ls
​
# 删除命名空间
# 前提需要将该命名空间的镜像,容器等信息删除,即可删除命名空间
$ ctr namespace rm"testns"

7 Containerd Network 管理


默认Containerd管理的容器仅有lo网络,无法访问容器之外的网络,可以为其添加网络插件,使用容器可以连接外网,CNI(Container Network Interface)

cni-plugins插件和cni工具包已经部署完毕。
# cni插件目录
$ ls /home/cni-plugins/
bandwidth  bridge  dhcp  firewall  host-device  host-local  ipvlan  loopback  macvlan  portmap  ptp  sbr  static  tuning  vlan  vrf
​
# cni工具包目录
$ ls /home/cni-tools/
cni-1.1.2
# cni工具1.1.2兼容cni插件1.0.0
下面先开始准备容器网络配置文件,用于为容器提供网关、IP地址等。
cat <<-'EOF' > /etc/cni/net.d/10-mynet.conf
{
    "cniVersion": "1.0.0",
    "name": "mynet",
    "type": "bridge",
    "bridge": "cni0",
    "isGateway": true,
    "ipMasq": true,
    "ipam": {
        "type": "host-local",
        "subnet": "10.66.0.0/16",
        "routes": [
            {
                "dst": "0.0.0.0/0"
            }
        ]
    }
}
EOF
​
cat <<-'EOF' > /etc/cni/net.d/99-loopback.conf
{
    "cniVerion": "1.0.0",
    "name": "lo",
    "type": "loopback"
}
EOF
生成cni网络
# 获取epel源
$ wget-O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
​
#安装jq [ jq是一个'出色'的'针对-->JSON处理器'的命令行 ]
$ yum-y install jq
​
# 进入cni工具目录
$ cd /home/cni-tools/cni-1.1.2
​
# 执行脚本文件,基于/etc/cni/net.d/目录中的*.conf配置文件生成容器网络
# CNI_PATH是cni插件安装的目录
$ cp-av scripts/* .
$ CNI_PATH=/home/cni-plugins ./priv-net-run.sh echo"Hello World"
# cni插件和cni工具包版本要兼容,否则可能会报错如下:
mynet : error executing ADD: {
    "code": 1,
    "msg": "incompatible CNI versions",
    "details": "config is \"1.0.0\", plugin supports [\"0.1.0\" \"0.2.0\" \"0.3.0\" \"0.3.1\" \"0.4.0\"]"
}
​
# 安装成功后,在宿主机上查看是否生成容器网络名为cni0的网桥
$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
[......]
7: cni0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 6a:32:bc:eb:0f:23 brd ff:ff:ff:ff:ff:ff
    inet 10.66.0.1/16 brd 10.66.255.255 scope global cni0
       valid_lft forever preferred_lft forever
    inet6 fe80::6832:bcff:feeb:f23/64 scope link 
       valid_lft forever preferred_lft forever
创建容器
$ ctr images pull docker.io/library/busybox:latest
$ ctr run -d docker.io/library/busybox:latest busybox
$ ctr tasks exec --exec-id$RANDOM-t busybox sh
/ # ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
​
#获取容器进程ID及其网络命名空间
$ pid=$(ctr tasks ls | grep busybox | awk '{print $2}') && echo$pid
39287
$ netnspath=/proc/$pid/ns/net && echo$netnspath
/proc/39287/ns/net
​
# 进入目录为指定容器添加网络配置
$ cd /home/cni-tools/cni-1.1.2/scripts/
$ CNI_PATH=/home/cni-plugins ./exec-plugins.sh add $pid$netnspath
验证容器网络于宿主机网络的互访功能
# 验证
# 进入容器确认是否添加网卡信息
$ ctr tasks exec --exec-id$RANDOM-t busybox sh
/ # ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 1e:8c:80:51:fc:be brd ff:ff:ff:ff:ff:ff
    inet 10.66.0.3/16 brd 10.66.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::1c8c:80ff:fe51:fcbe/64 scope link
       valid_lft forever preferred_lft forever
​
# 在容器中ping容器宿主机IP地址
/ # ping -c 2 10.0.0.30
PING 10.0.0.30 (10.0.0.30): 56 data bytes
64 bytes from 10.0.0.30: seq=0ttl=64time=0.280 ms
64 bytes from 10.0.0.30: seq=1ttl=64time=0.286 ms
​
---10.0.0.30 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max =0.280/0.283/0.286 ms
​
# 在容器中开启httpd服务
/ # echo "containerd net web test" > /tmp/index.html
/ # httpd -h /tmp
/ # wget -O- -q 127.0.0.1
containerd net web test
/ # exit
​
#在宿主机访问容器提供的httpd服务
$ curl10.66.0.3
containerd net web test

8 Containerd 容器数据持久化存储


实现把宿主机目录挂载至Containerd容器中,实现容器数据持久化存储

# 创建一个静态容器,实现宿主机目录与容器挂载,src=/tmp 为宿主机目录 dst=/hostdir 为容器中目录
$ ctr container create docker.io/library/busybox:latest busybox2 --mounttype=bind,src=/tmp,dst=/hostdir,options=rbind:rw
​
# 运行用户进程
$ ctr tasks start-d busybox2 bash
$ ctr task ls
TASK        PID      STATUS
busybox     18898    RUNNING
busybox2    24238    RUNNING
​
# 进入容器,查看是否挂载成功
$ ctr tasks exec --exec-id$RANDOM-t busybox2 sh
/ # ls /hostdir/
ks-script-GSRMK8                                                         vmware-root_6389-1958486695
systemd-private-cc74dd8802f0428490924757e690c750-chronyd.service-9TDICh  vmware-root_6511-1689719547
vmware-root_6359-1949639453                                              yum.log
# 向容器中挂载目录中添加文件
/ # echo "hello world" > /hostdir/test.txt
/ # ls /hostdir/
ks-script-GSRMK8                                                         vmware-root_6389-1958486695
systemd-private-cc74dd8802f0428490924757e690c750-chronyd.service-9TDICh  vmware-root_6511-1689719547
test.txt                                                                 yum.log
vmware-root_6359-1949639453
​
# 在宿主机上查看被容器挂载的目录中是否添加了新的文件,已添加表明被容器挂载成功,并可以读写此目录中内容。
$ cat /tmp/test.txt 
hello world

9 与其他Containerd容器共享命名空间


10 Docker 集成 Containerd 实现管理管理


目前Containerd主要任务还在于解决容器运行时的问题,对于其周边生态还不完善,所以有时需要借助:Docker结合Containerd来实现Docker完整的功能应用。

Docker 安装部署脚本:

# 安装Docker脚本
$ vim install_docker.sh
#!/bin/bash
# step 1: 安装必要的一些系统工具
echo-e"==> 安装必要的系统工具"
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# Step 2: 添加软件源信息
echo-e"==> 添加软件源信息"
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# Step 3
echo-e"==> 修改配置文件"
sudosed-i's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
# Step 4: 更新并安装Docker-CE
echo-e"==> 安装更新Docker"
sudo yum makecache fast
sudo yum -y install docker-ce-20.10.7 docker-ce-cli-20.10.7 containerd.io-1.4.6
# Step 5: 配置加速器以及docker参数
echo-e"==> 配置加速器以及docker参数"
sudomkdir-p /etc/docker
# 配置多个镜像加速地址
sudotee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://po13h3y1.mirror.aliyuncs.com","http://hub-mirror.c.163.com","https://mirror.ccs.tencentyun.com","http://f1361db2.m.daocloud.io"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF
# Step 6: 加载服务
echo-e"==> 加载服务"
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl enable docker
# 查看Docker服务信息
echo-e"==> 查看Docker服务信息"
docker info
Docker运行的容器默认在moby命名空间下。
# 安装docker
$ yum-y install docker
# 启动docker
$ systemctl enable --now docker

​Docker 运行的容器默认在moby命名空间下。

# 下载nginx容器镜像
$ docker pull nginx:latest
# 运行nginx容器
$ docker run -it-d--name nginx-docker nginx:latest
# 查看Docker容器进程
$ dockerps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
2dc3a6364d0e        nginx:latest        "/docker-entrypoin..."   6 seconds ago       Up 3 seconds        80/tcp              nginx-docker
​
# 查看ctr命令下的namespace,发现多了一个moby命名空间。moby即为docker使用的命名空间。
$ ctr namespace ls
NAME    LABELS 
default          
moby
​
# 查看moby命名空间下的容器和任务
$ ctr--namespace moby container ls
$ ctr--namespace moby tasks ls

### ContainerdDocker容器运行时的差异及关系 #### 定义与角色 ContainerdDocker 是两个不同的项目,但在容器生态系统中扮演着互补的角色。Docker一个完整的平台,用于开发、部署和管理应用程序容器化环境;而 containerd 则是一个工业级标准的容器运行时,专注于安全可靠地执行容器。 #### 架构区别 Docker 的架构更为复杂,包含了更多的组件和服务来支持其丰富的功能集。相比之下,containerd 设计得更加轻量级和模块化[^1]: - **Docker**: 提供了一个全面的应用程序接口 (API),图形用户界面工具和其他高级特性,使得开发者可以更容易地上手并使用容器技术。 - **containerd**: 主要关注于提供核心容器生命周期管理和镜像传输服务,具有较低级别的 API 接口,适合集成到其他系统或由更高层次的服务调用。 #### 功能对比 尽管两者都能处理基本的容器操作如启动、停止等,但它们的功能侧重点有所不同: - **网络配置**:对于端口绑定,在 Docker 中可以通过 `-p` 或 `--publish` 参数指定主机与容器间的特定端口映射关系[^2]。然而这种设置并不适用于 containerd,因为后者不直接参与此类高层应用层面的操作。 - **存储驱动**:Docker 支持多种文件系统的挂载方式以及卷插件机制,允许灵活定义数据持久化的策略。containerd 同样具备类似的抽象层——即通过 OCI 配置规范实现对不同类型的根文件系统的支持,不过具体细节交给了上层框架去决定。 #### 关系说明 实际上,自 Docker v17.06 版本起,默认情况下已经采用 containerd 作为底层容器运行时引擎之一。这意味着当用户安装最新版本Docker Engine 之后,实际负责创建和管理容器实例的工作是由 containerd 来完成的。因此可以说,现代版 Docker 实际上依赖于 containerd 来履行部分职责,并在其基础上构建起了更广泛的生态体系。 ```bash docker run -it --rm busybox sh # 上述命令最终会委托给 containerd 执行具体的容器初始化过程 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dark_Ice_

你的支持是我创作的核动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值