43.容器管理工具Containerd
摘要: Containerd是CNCF旗下的轻量级容器运行时工具,专注于容器生命周期管理。它采用C/S架构,通过gRPC API提供服务,支持OCI标准,性能优于Docker和CRI-O。Containerd最初由Docker开发,后独立发展并成为Kubernetes默认运行时。其模块化设计包含Storage、Metadata和Runtime三大子系统,通过插件实现镜像管理、快照等功能。安装时可通
文章目录
容器管理工具Containerd
一、Containerd介绍
1.前言
- 早在2016年3月,Docker 1.11的Docker Engine里就包含了containerd,而现在则是把containerd 从Docker Engine里彻底剥离出来,作为一个独立的开源项目独立发展,目标是提供一个更加开 放、稳定的容器运行基础设施。和原先包含在Docker Engine里containerd相比,独立的 containerd将具有更多的功能,可以涵盖整个容器运行时管理的所有需求。
- containerd并不是直接面向最终用户的,而是主要用于集成到更上层的系统里,比如Swarm, Kubernetes, Mesos等容器编排系统。
- containerd以Daemon的形式运行在系统上,通过暴露底层的gRPC API,上层系统可以通过这些 API管理机器上的容器。
- 每个containerd只负责一台机器,Pull镜像,对容器的操作(启动、停止等),网络,存储都是由 containerd完成。具体运行容器由runC负责,实际上只要是符合OCI规范的容器都可以支持。
- 对于容器编排服务来说,运行时只需要使用containerd+runC,更加轻量,容易管理。
- 独立之后containerd的特性演进可以和Docker Engine分开,专注容器运行时管理,可以更稳定。

2.Containerd前世今生
2013年docker公司在推出docker产品后,由于其对全球技术产生了一定的影响力,Google公司明显感觉 到自己公司内部所使用的Brog系统江湖地位受到的威胁,希望Docker公司能够与自己联合打造一款开源 的容器运行时作为Docker核心依赖,但Docker公司拒绝了;接着Google公司联合RedHat、IBM等公司 说服Docker公司把其容器核心技术libcontainer捐给中立社区(OCI,Open Container Intiative),并更名为 runC。 为了进一步遏制Docker在未来技术市场影响力,避免在容器市场上Docker一家独大,Google公 司带领导RedHat、IBM等成立了CNCF(Cloud Native Computing Fundation)基金会,即云原生计算基金 会。CNCF的目标很明确,既然在容器应用领域无法与Docker相抗衡,那就做Google更有经验的技术市 场------大规模容器编排应用场景,Google公司把自己内部使用的Brog系统开源------Kubernetes,也就是 我们今天所说的云原生技术生态。
2016年Docker公司推出了Docker Swarm,意在一统Docker生态,让Docker既可以实现容器应用管 理,也可以实现大规模容器编排,经过近1年左右时间的市场验证后,发现在容器编排方面无法独立抗衡 kubernetes,所以Docker公司于2017年正式宣布原生支持Kubernetes,至此,Docker在大规模容器编排 应用市场败下阵来,但是Docker依然不甘心失败,把Docker核心依赖Containerd捐给了CNCF,依此说 明Docker依旧是一个PaaS平台。
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。
3.Containerd架构
3.1 架构图
Containerd设计的目的是为了嵌入到Kubernetes中使用,它是一个工业级的容器运行时,不提供给开发 人员和终端用户直接使用,这样就避免了与Docker产生竞争,但事实上,Containerd已经实现大多数容 器管理功能,例如:容器生命周期管理、容器镜像传输和管理、容器存储与网络管理等。

-
Containerd 采用标准的 C/S 架构
- 服务端通过 GRPC 协议提供稳定的 API
- 客户端通过调用服务端的 API 进行高级的操作
-
为了实现解耦,Containerd 将不同的职责划分给不同的组件,每个组件就相当于一个子系统 (subsystem)。连接不同子系统的组件被称为模块。
-
Containerd 两大子系统为:
- Bundle : 在 Containerd 中,Bundle 包含了配置、元数据和根文件系统数据,你可以理解为 容器的文件系统。而 Bundle 子系统允许用户从镜像中提取和打包 Bundles。
- Runtime : Runtime 子系统用来执行 Bundles,比如创建容器。
-
其中,每一个子系统的行为都由一个或多个模块协作完成(架构图中的 Core 部分)。每一种类型 的模块都以插件的形式集成到 Containerd 中,而且插件之间是相互依赖的。 例如,上图中的每一个长虚线的方框都表示一种类型的插件,包括 Service Plugin、Metadata Plugin、GC Plugin、Runtime Plugin 等,其中 Service Plugin 又会依赖 Metadata Plugin、GC Plugin 和 Runtime Plugin。每一个小方框都表示一个细分的插件,例如 Metadata Plugin 依赖 Containers Plugin、Content Plugin 等。
3.2 常用插件
-
Content Plugin : 提供对镜像中可寻址内容的访问,所有不可变的内容都被存储在这里。
-
Snapshot Plugin : 用来管理容器镜像的文件系统快照。镜像中的每一个 layer 都会被解压成文件系统快照,类似于 Docker 中的 graphdriver 。
-
Metrics : 暴露各个组件的监控指标。

3.3 架构缩略图
Containerd 被分为三个大块: Storage 、 Metadata 和 Runtime

3.4 与其它容器运行时工具性能对比
这是使用 bucketbench 对 Docker、crio 和 Containerd 的性能测试结果,包括启动、停止和删除容器, 以比较它们所耗的时间:

结论: Containerd 在各个方面都表现良好,总体性能优于 Docker 和 crio 。
二、Containerd安装
操作系统: CentOS Stream 8
1.YUM方式安装
基于 CentOS-Stream-8模板制作.md制作的模板克隆一台虚拟机命名为Containerd
安装必要工具
[root@containerd ~ 13:42:05]# yum install -y yum-utils device-mapper-persistent-data lvm2 vim
安装Containerd
#1.增加aliyun的仓库
[root@containerd ~ 13:43:46]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#2.查找关于containerd的安装包
[root@containerd ~ 13:44:44]# yum list | grep containerd
containerd.io.x86_64 1.6.32-3.1.el8 docker-ce-stable
#3.安装containerd
[root@containerd ~ 13:45:01]# yum -y install containerd.io
#4.查看安装包
[root@containerd ~ 13:46:52]# rpm -aq | grep containerd
containerd.io-1.6.32-3.1.el8.x86_64
#查看所有已经安装的安装包中过滤出containerd
[root@containerd ~ 13:47:21]# rpm -q containerd.io
containerd.io-1.6.32-3.1.el8.x86_64
#需要将名称写齐
#5.设置containerd服务开机自启动
[root@containerd ~ 13:48:02]# systemctl enable containerd --now
Created symlink /etc/systemd/system/multi-user.target.wants/containerd.service → /usr/lib/systemd/system/containerd.service.
[root@containerd ~ 13:48:21]# systemctl status containerd.service
● containerd.service - containerd container runtime
Loaded: loaded (/usr/lib/systemd/system/containerd.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2025-11-24 13:48:21 CST;
# 6.验证
# 安装Containerd时ctr命令亦可使用,ctr命令主要用于管理容器及容器镜像等。
# 使用ctr命令查看Containerd客户端及服务端相关信息
[root@containerd ~ 13:48:24]# ctr version
Client:
Version: 1.6.32
Revision: 8b3b7ca2e5ce38e8f31a34f35b2b68ceb8470d89
Go version: go1.21.10
Server:
Version: 1.6.32
Revision: 8b3b7ca2e5ce38e8f31a34f35b2b68ceb8470d89
UUID: bcdcb1ce-3e6f-4d2a-95f6-84ca7977588b
2.二进制方式安装
Containerd有两种安装包:
- 第一种是containerd-xxx,这种包用于单机测试没问题,不包含runC,需要提前安装。
- 第二种是cri-containerd-cni-xxxx,包含runc和k8s里的所需要的相关文件。k8s集群里需要用到此 包。虽然包含runC,但是依赖系统中的seccomp(安全计算模式,是一种限制容器调用系统资源的 模式。)
2.1 安装Containerd
打开github官网,搜索containerd项目



找到1.6.32

往下翻,找到软件包下载,然后上传到centos
也可以右击,复制链接,wget下载
https://github.com/containerd/containerd/releases/download/v1.6.32/cri-containerd-cni-1.6.32-linux-amd64.tar.gz

#1.利用xftp 上传压缩包:
`cri-containerd-cni-1.6.32-linux-amd64.tar.gz`
[root@containerd ~ 14:19:10]# ls
anaconda-ks.cfg
cri-containerd-cni-1.6.32-linux-amd64.tar.gz
#2.安装containerd
[root@containerd ~ 14:20:47]# mkdir containerd
[root@containerd ~ 14:21:01]# tar -xf cri-containerd-cni-1.6.32-linux-amd64.tar.gz -C containerd/
[root@containerd ~ 14:21:14]# cd containerd/
[root@containerd containerd 14:21:25]# ls
cri-containerd.DEPRECATED.txt etc opt usr
[root@containerd containerd 14:22:22]# yum install -y tree
[root@containerd containerd 14:22:31]# tree
.
├── cri-containerd.DEPRECATED.txt
├── etc
│ ├── cni
│ │ └── net.d
│ │ └── 10-containerd-net.conflist
│ ├── crictl.yaml
│ └── systemd
│ └── system
│ └── containerd.service
├── opt
│ ├── cni
│ │ └── bin
│ │ ├── bandwidth
│ │ ├── bridge
│ │ ├── dhcp
│ │ ├── firewall
│ │ ├── host-device
│ │ ├── host-local
│ │ ├── ipvlan
│ │ ├── loopback
│ │ ├── macvlan
│ │ ├── portmap
│ │ ├── ptp
│ │ ├── sbr
│ │ ├── static
│ │ ├── tuning
│ │ ├── vlan
│ │ └── vrf
│ └── containerd
│ └── cluster
│ ├── gce
│ │ ├── cloud-init
│ │ │ ├── master.yaml
│ │ │ └── node.yaml
│ │ ├── cni.template
│ │ ├── configure.sh
│ │ └── env
│ └── version
└── usr
└── local
├── bin
│ ├── containerd
│ ├── containerd-shim
│ ├── containerd-shim-runc-v1
│ ├── containerd-shim-runc-v2
│ ├── containerd-stress
│ ├── crictl
│ ├── critest
│ ├── ctd-decoder
│ └── ctr
└── sbin
└── runc
#查看containerd。service文件,了解containerd文件安装位置
[root@containerd containerd 14:22:36]# 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
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
#复制containerd运行时的文件至系统
[root@containerd containerd 14:22:52]# cp usr/local/bin/* /usr/local/bin/
#添加containerd。service文件至系统
[root@containerd containerd 14:23:26]# cp etc/systemd/system/containerd.service /usr/lib/systemd/system/containerd.service
#生成containerd模块配置文件,可以自定义一下配置,如有私有镜像仓库等,按需配置
[root@containerd containerd 14:24:07]# mkdir /etc/containerd
[root@containerd containerd 14:25:28]# containerd config default > /etc/containerd/config.toml
[root@containerd containerd 14:25:38]# cat /etc/containerd/config.toml
disabled_plugins = []
imports = []
oom_score = 0
plugin_dir = ""
required_plugins = []
root = "/var/lib/containerd"
state = "/run/containerd"
temp = ""
version = 2
[cgroup]
path = ""
[debug]
address = ""
format = ""
gid = 0
level = ""
uid = 0
[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
[metrics]
address = ""
grpc_histogram = false
[plugins]
[plugins."io.containerd.gc.v1.scheduler"]
deletion_threshold = 0
mutation_threshold = 100
pause_threshold = 0.02
schedule_delay = "0s"
startup_delay = "100ms"
[plugins."io.containerd.grpc.v1.cri"]
device_ownership_from_security_context = false
disable_apparmor = false
disable_cgroup = false
disable_hugetlb_controller = true
disable_proc_mount = false
disable_tcp_service = true
drain_exec_sync_io_timeout = "0s"
enable_selinux = false
enable_tls_streaming = false
enable_unprivileged_icmp = false
enable_unprivileged_ports = false
ignore_deprecation_warnings = []
ignore_image_defined_volumes = false
max_concurrent_downloads = 3
max_container_log_line_size = 16384
netns_mounts_under_state_dir = false
restrict_oom_score_adj = false
sandbox_image = "registry.k8s.io/pause:3.6"
selinux_category_range = 1024
stats_collect_period = 10
stream_idle_timeout = "4h0m0s"
stream_server_address = "127.0.0.1"
stream_server_port = "0"
systemd_cgroup = false
tolerate_missing_hugetlb_controller = true
unset_seccomp_profile = ""
[plugins."io.containerd.grpc.v1.cri".cni]
bin_dir = "/opt/cni/bin"
conf_dir = "/etc/cni/net.d"
conf_template = ""
ip_pref = ""
max_conf_num = 1
[plugins."io.containerd.grpc.v1.cri".containerd]
default_runtime_name = "runc"
disable_snapshot_annotations = true
discard_unpacked_layers = false
ignore_rdt_not_enabled_errors = false
no_pivot = false
snapshotter = "overlayfs"
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
runtime_engine = ""
runtime_path = ""
runtime_root = ""
runtime_type = ""
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
runtime_engine = ""
runtime_path = ""
runtime_root = ""
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
BinaryName = ""
CriuImagePath = ""
CriuPath = ""
CriuWorkPath = ""
IoGid = 0
IoUid = 0
NoNewKeyring = false
NoPivotRoot = false
Root = ""
ShimCgroup = ""
SystemdCgroup = false
[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
runtime_engine = ""
runtime_path = ""
runtime_root = ""
runtime_type = ""
[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime.options]
[plugins."io.containerd.grpc.v1.cri".image_decryption]
key_model = "node"
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = ""
[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]
[plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]
tls_cert_file = ""
tls_key_file = ""
[plugins."io.containerd.internal.v1.opt"]
path = "/opt/containerd"
[plugins."io.containerd.internal.v1.restart"]
interval = "10s"
[plugins."io.containerd.internal.v1.tracing"]
[plugins."io.containerd.metadata.v1.bolt"]
content_sharing_policy = "shared"
[plugins."io.containerd.monitor.v1.cgroups"]
no_prometheus = false
[plugins."io.containerd.runtime.v1.linux"]
no_shim = false
runtime = "runc"
runtime_root = ""
shim = "containerd-shim"
shim_debug = false
[plugins."io.containerd.runtime.v2.task"]
platforms = ["linux/amd64"]
sched_core = false
[plugins."io.containerd.service.v1.diff-service"]
default = ["walking"]
[plugins."io.containerd.service.v1.tasks-service"]
rdt_config_file = ""
[plugins."io.containerd.snapshotter.v1.aufs"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.btrfs"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.devmapper"]
async_remove = false
base_image_size = ""
discard_blocks = false
fs_options = ""
fs_type = ""
pool_name = ""
root_path = ""
[plugins."io.containerd.snapshotter.v1.native"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.overlayfs"]
mount_options = []
root_path = ""
sync_remove = false
upperdir_label = false
[plugins."io.containerd.snapshotter.v1.zfs"]
root_path = ""
[plugins."io.containerd.tracing.processor.v1.otlp"]
[proxy_plugins]
[stream_processors]
[stream_processors."io.containerd.ocicrypt.decoder.v1.tar"]
accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"]
args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
path = "ctd-decoder"
returns = "application/vnd.oci.image.layer.v1.tar"
[stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"]
accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"]
args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
path = "ctd-decoder"
returns = "application/vnd.oci.image.layer.v1.tar+gzip"
[timeouts]
"io.containerd.timeout.bolt.open" = "0s"
"io.containerd.timeout.shim.cleanup" = "5s"
"io.containerd.timeout.shim.load" = "5s"
"io.containerd.timeout.shim.shutdown" = "3s"
"io.containerd.timeout.task.state" = "2s"
[ttrpc]
address = ""
gid = 0
uid = 0
#启动containerd并验证
[root@containerd containerd 14:25:46]# systemctl enable containerd --now
[root@containerd containerd 14:26:15]# systemctl status containerd.service
● containerd.service - containerd container runtime
Loaded: loaded (/usr/lib/systemd/system/containerd.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2025-11-24 14:26:15 CST;
#查看containerd版本
[root@containerd containerd 14:26:32]# ctr version
Client:
Version: v1.6.32
Revision: 8b3b7ca2e5ce38e8f31a34f35b2b68ceb8470d89
Go version: go1.21.10
Server:
Version: v1.6.32
Revision: 8b3b7ca2e5ce38e8f31a34f35b2b68ceb8470d89
UUID: 5b593249-b6c4-4555-97db-5513904a7d38
2.2 安装runC
runc是docker运行的环境,docker用来调用containerd
由于二进制包中提供的runC默认需要系统中安装seccomp支持,需要单独安装,且不同版本runC对 seccomp版本要求一致,所以建议单独下载runC 二进制包进行安装,里面包含了seccomp模块支持
下载地址: https://github.com/opencontainers/runc/releases
#利用xftp上传
`runc.amd64`
[root@containerd ~ 14:27:32]# ls
anaconda-ks.cfg containerd cri-containerd-cni-1.6.32-linux-amd64.tar.gz runc.amd64
#安装runc
[root@containerd ~ 14:27:53]# mv runc.amd64 /usr/sbin/runc
#为runc添加执行权限
[root@containerd ~ 14:28:14]# chmod +x /usr/sbin/runc
#查看runc是否安装成功
[root@containerd ~ 14:28:29]# runc -v
runc version 1.3.0
commit: v1.3.0-0-g4ca628d1
spec: 1.2.1
go: go1.23.8
libseccomp: 2.5.6
三、Containerd容器镜像管理
3.1.帮助命令
- docker使用docker images命令管理镜像
- 单机containerd使用ctr images命令管理镜像,containerd本身的CLI
- k8s中containerd使用crictl images命令管理镜像,Kubernetes社区的专用CLI工具
[root@containerd ~ 19:57:12]# ctr --help
NAME:
ctr -
__
_____/ /______
/ ___/ __/ ___/
/ /__/ /_/ /
\___/\__/_/
containerd CLI
USAGE:
ctr [global options] command [command options] [arguments...]
VERSION:
v1.6.32
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
deprecations
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
#查看子命令
[root@containerd ~ 19:57:22]# ctr images --help
NAME:
ctr images - manage images
USAGE:
ctr images command [command options] [arguments...]
COMMANDS:
check check existing images to ensure all content is available locally
export export images
import import images
list, ls list images known to containerd
mount mount an image to a target path
unmount unmount the image from the target
pull pull an image from a remote
push push an image to a remote
delete, del, remove, rm remove one or more images by reference
tag tag an image
label set and clear labels for an image
convert convert an image
OPTIONS:
--help, -h show help
3.2.查看镜像
#i,image,images同意思 ls,list同意思
[root@containerd ~ 15:42:14]# ctr i ls
[root@containerd ~ 15:42:14]# ctr images ls
[root@containerd ~ 15:42:14]# ctr image ls
[root@containerd ~ 15:42:14]# ctr i list
[root@containerd ~ 15:42:14]# ctr images list
[root@containerd ~ 15:42:14]# ctr image list
REF TYPE DIGEST SIZE PLATFORMS LABELS
3.3.下载镜像
containerd支持oci标准的镜像,所以可以直接使用docker官方或dockerfile构建的镜像
#这里ctr命令pull镜像时,不能直接把镜像名字写成nginx:alpine
[root@containerd ~ 15:14:45]# ctr images pull 054b8ac70e8010d90f2ac00ef29e6580.mirror.swr.myhuaweicloud.com/library/nginx:latest
#因为没有配置镜像加速器,所以需要指名镜像的域
3.4.镜像挂载
方便查看镜像中包含的内容
#挂载
[root@containerd ~ 15:32:52]# ctr images mount 054b8ac70e8010d90f2ac00ef29e6580.mirror.swr.myhuaweicloud.com/library/nginx:latest /mnt
#查看挂载
[root@containerd ~ 15:33:16]# cd /mnt
[root@containerd mnt 15:33:25]# ls
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
boot docker-entrypoint.d etc lib media opt root sbin sys usr
################umount实验################
#1.未退出挂载点
[root@containerd mnt 15:33:26]# umount /mnt
umount: /mnt: target is busy.
#因为在/mnt挂载点中所以挂载点被占用。无法取消挂载
#cd出来即可取消挂载
[root@containerd mnt 15:33:39]# cd
[root@containerd ~ 15:33:54]# umount /mnt
#2.一个对话可以同时登录几个终端
#另一个终端正在占用挂载点
[root@containerd ~ 15:34:49]# ctr images mount 054b8ac70e8010d90f2ac00ef29e6580.mirror.swr.myhuaweicloud.com/library/nginx:latest /mnt
sha256:7ab4a6fb632471ab3ee41345cf86ffaf7ecf2bf70be36232658a9374809268e7
/mnt
[root@containerd ~ 15:34:54]# ls /mnt
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
boot docker-entrypoint.d etc lib media opt root sbin sys usr
[root@containerd ~ 15:34:57]# cd /mnt
#本终端:
[root@containerd ~ 15:35:11]# yum install -y lsof
[root@containerd ~ 15:36:50]# lsof -l /mnt
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 1865 0 cwd DIR 0,45 33 202197394 /mnt
`lsof用于查看正在运行的文件系统`
[root@containerd ~ 15:37:39]# kill -9 1865
[root@containerd ~ 15:37:50]# umount /mnt
3.5.镜像导出
[root@containerd ~ 15:38:02]# ctr images export --platform linux/amd64 nginx.img 054b8ac70e8010d90f2ac00ef29e6580.mirror.swr.myhuaweicloud.com/library/nginx:latest
`需要指明导出平台`
[root@containerd ~ 15:39:24]# ls
nginx.img
3.6.镜像删除
[root@containerd ~ 15:39:31]# ctr images rm 054b8ac70e8010d90f2ac00ef29e6580.mirror.swr.myhuaweicloud.com/library/nginx:latest
[root@containerd ~ 15:39:50]# ctr image ls
REF TYPE DIGEST SIZE PLATFORMS LABELS
3.7.镜像导入
[root@containerd ~ 15:39:57]# ctr images import --platform linux/amd64 nginx.img
`指明导出平台`
[root@containerd ~ 15:40:48]# ctr image ls
REF TYPE DIGEST SIZE PLATFORMS LABELS
054b8ac70e8010d90f2ac00ef29e6580.mirror.swr.myhuaweicloud.com/library/nginx:latest application/vnd.oci.image.index.v1+json sha256:553f64aecdc31b5bf944521731cd70e35da4faed96b2b7548a3d8e2598c52a42 57.0 MiB linux/386,linux/amd64,linux/arm/v5,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/riscv64,linux/s390x,unknown/unknown -
3.8.修改镜像tag
[root@containerd ~ 15:40:53]# ctr images tag 054b8ac70e8010d90f2ac00ef29e6580.mirror.swr.myhuaweicloud.com/library/nginx:latest nginx:latest
nginx:latest
#查看
[root@containerd ~ 15:41:24]# ctr image ls
REF TYPE DIGEST SIZE PLATFORMS LABELS
054b8ac70e8010d90f2ac00ef29e6580.mirror.swr.myhuaweicloud.com/library/nginx:latest application/vnd.oci.image.index.v1+json sha256:553f64aecdc31b5bf944521731cd70e35da4faed96b2b7548a3d8e2598c52a42 57.0 MiB linux/386,linux/amd64,linux/arm/v5,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/riscv64,linux/s390x,unknown/unknown -
nginx:latest application/vnd.oci.image.index.v1+json sha256:553f64aecdc31b5bf944521731cd70e35da4faed96b2b7548a3d8e2598c52a42 57.0 MiB linux/386,linux/amd64,linux/arm/v5,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/riscv64,linux/s390x,unknown/unknown -
四、Containerd容器管理
container用于静态容器的命令,如:镜像创建容器 类似:docker ps -a
task用于动态容器命令 类似:**docker ps **
[root@localhost ~]# ctr container --help
#获取创建静态容器命令帮助 使用`ctr container create `命令创建容器后,容器并没有处于运行状态,其只是一个静态的容器。这个 container 对象只是包含了运行一个容器所需的资源及配置的数据结构,例如: namespaces、rootfs 和容器的配置都已经初始化成功了,只是用户进程(本案例为nginx)还没有启动。需要使用`ctr tasks`命令才能获取一个动态容器。
[root@containerd ~ 15:54:55]# ctr container ls
CONTAINER IMAGE RUNTIME
[root@containerd ~ 16:06:01]# ctr task ls
TASK PID STATUS
[root@containerd ~ 16:06:59]# ctr container create nginx:latest nginx1
[root@containerd ~ 16:07:24]# ctr container ls
CONTAINER IMAGE RUNTIME
nginx1 nginx:latest io.containerd.runc.v2
[root@containerd ~ 16:07:35]# ctr task ls
TASK PID STATUS
#查看容器基本情况
[root@containerd ~ 16:07:41]# ctr container info nginx1
#静态容器启动为动态容器
[root@containerd ~ 16:08:03]# ctr task start -d nginx1
[root@containerd ~ 16:08:43]# ctr task ls
TASK PID STATUS
nginx1 2424 RUNNING
[root@containerd ~ 16:09:01]# ps aux | grep 2424
root 2424 0.0 0.2 14764 9044 ? Ss 16:08 0:00 nginx: master process nginx -g daemon off;
root 2473 0.0 0.0 12216 1100 pts/1 S+ 16:09 0:00 grep --color=auto 2424
#进入容器
[root@containerd ~ 16:09:54]# ctr task exec --exec-id $RANDOM -t nginx1 /bin/sh
`为exec进程设定一个id,可以随意输入,只要保证唯一即可,也可使用$RANDOM变量 -t指定容器名`
# cat /etc/os-release 查看容器内部的操作系统类型
PRETTY_NAME="Debian GNU/Linux 13 (trixie)"
NAME="Debian GNU/Linux"
VERSION_ID="13"
VERSION="13 (trixie)"
VERSION_CODENAME=trixie
DEBIAN_VERSION_FULL=13.2
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
# exit
#直接运行一个动态容器
[root@containerd ~ 16:12:46]# ctr run -d --net-host nginx:latest nginx2
--net-host 代表容器的IP就是宿主机的IP(相当于docker里的host类型网络)
[root@containerd ~ 16:13:24]# ctr task ls
TASK PID STATUS
nginx1 2424 RUNNING
nginx2 2566 RUNNING
#暂停容器
[root@containerd ~ 16:13:49]# ctr task pause nginx2
[root@containerd ~ 16:13:53]# ctr task ls
TASK PID STATUS
nginx1 2424 RUNNING
nginx2 2566 PAUSED
#取消暂停
[root@containerd ~ 16:13:59]# ctr task resume nginx2
[root@containerd ~ 16:14:14]# ctr task ls
TASK PID STATUS
nginx1 2424 RUNNING
nginx2 2566 RUNNING
#停止容器
[root@containerd ~ 16:14:17]# ctr task kill nginx2
[root@containerd ~ 16:14:33]# ctr task ls
TASK PID STATUS
nginx1 2424 RUNNING
nginx2 2566 STOPPED
#删除容器
[root@containerd ~ 16:14:38]# ctr task delete nginx2 将运行中的容器删除
[root@containerd ~ 16:15:00]# ctr task ls
TASK PID STATUS
nginx1 2424 RUNNING
[root@containerd ~ 16:15:11]# ctr container ls
CONTAINER IMAGE RUNTIME
nginx1 nginx:latest io.containerd.runc.v2
nginx2 nginx:latest io.containerd.runc.v2
[root@containerd ~ 16:15:28]# ctr container delete nginx2 将静态容器删除
[root@containerd ~ 16:15:43]# ctr container ls
CONTAINER IMAGE RUNTIME
nginx1 nginx:latest io.containerd.runc.v2
五、Containerd使用私有容器镜像仓库 Harbor
# 手动在containerd宿主机上添加此配置信息,如果域名解析已存在忽略
[root@localhost ~]# vim /etc/hosts192.168.108.30 my.harbor.com
# harbor仓库需要提前在192.168.108.30上部署(参考docker教案),镜像需要提前传到harbor上,如果没有使用https可以使用--plain-http 指定http协议
[root@localhost ~]# ctr image pull --plain-http 192.168.108.30/cloud/nginx:latest
# 上传镜像到Harbor
[root@localhost ~]# ctr images tag nginx:latest my.harbor.com/cloud/nginx:latest
[root@localhost ~]# ctr image push --platform linux/amd64 --plain-http --user
"images_admin:Cloud12#$" my.harbor.com/cloud/nginx:latest
manifest-sha256:6533ddd664582430971e93e69cf343e3bfffceadeaaa97d4379c4d7a29f21d47:
done
|++++++++++++++++++++++++++++++++++++++|
config-sha256:2cd1d97f893f70cee86a38b7160c30e5750f3ed6ad86c598884ca9c6a563a501:
done
|++++++++++++++++++++++++++++++++++++++|
elapsed: 0.1 s
六、Containerd NameSpace管理
containerd中namespace的作用为隔离运行的容器,可以实现运行多个容器
#查看ctr层面的namespace
[root@containerd ~ 16:15:46]# ctr namespace ls
NAME LABELS
default
`docker -> containerd -> runc`
#docker下载镜像到containerd层面,但是namespace资源隔离,镜像保存在mody中不是default
[root@docker ~ 16:15:46]# ctr namespace ls
NAME LABELS
moby
#创建namespace
[root@containerd ~ 16:45:42]# ctr namespace create myns
[root@containerd ~ 16:46:32]# ctr namespace create testns
[root@containerd ~ 16:46:50]# ctr namespace ls
NAME LABELS
default
myns
testns
#删除namespace
[root@containerd ~ 16:46:57]# ctr namespace rm testns
testns
[root@containerd ~ 16:47:14]# ctr namespace ls
NAME LABELS
default
myns
#查看指定namespace中镜像
[root@containerd ~ 16:47:24]# ctr -n myns image ls
REF TYPE DIGEST SIZE PLATFORMS LABELS
[root@containerd ~ 16:47:43]# ctr -n myns task ls
TASK PID STATUS
#在指定namespace中下载容器镜像
[root@containerd ~ 16:48:16]# ctr -n myns images pull 054b8ac70e8010d90f2ac00ef29e6580.mirror.swr.myhuaweicloud.com/library/nginx:latest
#查看
[root@containerd ~ 16:48:36]# ctr -n myns image ls
#在指定namespace中创建静态容器
[root@containerd ~ 16:51:13]# ctr -n myns container create 054b8ac70e8010d90f2ac00ef29e6580.mirror.swr.myhuaweicloud.com/library/nginx:latest mynginx
[root@containerd ~ 16:52:08]# ctr -n myns container ls
CONTAINER IMAGE RUNTIME
mynginx 054b8ac70e8010d90f2ac00ef29e6580.mirror.swr.myhuaweicloud.com/library/nginx:latest io.containerd.runc.v2
#.查看在指定namespace中创建的容器
[root@containerd ~ 16:52:24]# ctr -n myns task start -d mynginx
[root@containerd ~ 16:53:01]# ctr -n myns task ls
TASK PID STATUS
mynginx 2919 RUNNING
nerdctl 实践
nerdctl 安装
我们推荐使用 nerdctl 管理containerd,命令语法与 docker 一致。
截止 2023-05-24 最新版本是 v 1.4.0 github项目地址: https://github.com/containerd/nerdctl/releases
cni插件项目地址: https://github.com/containernetworking/plugins/releases
#利用xftp上传
[root@containerd ~ 09:32:06]# ls
nerdctl-1.4.0-linux-amd64.tar.gz
#解压安装
[root@containerd ~ 09:32:47]# tar -xf nerdctl-1.4.0-linux-amd64.tar.gz -C /usr/bin/
#配置nerdctl补全命令
[root@containerd ~ 09:33:12]# nerdctl completion bash > /etc/bash_completion.d/nerdctl
[root@containerd ~ 09:34:26]# source /etc/bash_completion.d/nerdctl
`source用于扫描读取文件`
#利用xftp上传cni插件,解压安装
[root@containerd ~ 09:36:06]# mkdir -p /opt/cni/bin
[root@containerd ~ 09:36:26]# tar -xf cni-plugins-linux-amd64-v1.3.0.tgz -C /opt/cni/bin/
如果依然不能补全命令
yum install -y bash-completion
配置镜像加速器
#编辑containerd的配置文件config.toml,如果不存在,需要手动生成,方法 containerd config default > /etc/containerd/config.toml,在配置文件中搜索关键字“config_path”,在其下面添加镜像加速参数
`containerd config default > /etc/containerd/config.toml 生成配置文件`
#修改配置文件表明镜像加速器所在的位置
[root@containerd ~ 09:37:42]# vim /etc/containerd/config.toml
` config_path = "/etc/containerd/certs.d" 添加(一定是certs.d只有之这个目录可以被识别)`
[root@containerd ~ 09:40:45]# mkdir /etc/containerd/certs.d/docker.io -p
#添加镜像加速器
[root@containerd ~ 09:41:14]# vim /etc/containerd/cert.d/docker.io/hosts.toml
[root@containerd ~ 09:45:35]# cat /etc/containerd/cert.d/docker.io/hosts.toml
server = "https://3aa741e7c6bf42ae924a3c0143f0e841.mirror.swr.myhuaweicloud.com"
[host."https://3aa741e7c6bf42ae924a3c0143f0e841.mirror.swr.myhuaweicloud.com"]
capabilities = ["pull", "resolve"] `镜像加速器的功能`
[root@containerd ~ 09:45:42]# systemctl restart containerd
nerdctl 管理镜像
[root@localhost ~]# nerdctl image <tab><tab> 按两下tab键
build (Build an image from a Dockerfile. Needs buildkitd to be running.)
convert (convert an image)
decrypt (decrypt an image)
encrypt (encrypt image layers)
history (Show the history of an image)
inspect (Display detailed information on one or more images.)
load (Load an image from a tar archive or STDIN)
ls (List images)
prune (Remove unused images)
pull (Pull an image from a registry. Optionally specify "ipfs://" or "ipns://" scheme to pull i…)
push (Push an image or a repository to a registry. Optionally specify "ipfs://" or "ipns://" sc…)
rm (Remove one or more images)
save (Save one or more images to a tar archive (streamed to STDOUT by default))
tag (Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE)
ls
作用:查看镜像清单。
[root@containerd ~ 09:45:57]# nerdctl image ls
REPOSITORY TAG IMAGE ID CREATED PLATFORM SIZE BLOB SIZE
[root@containerd ~ 09:47:10]# nerdctl images
REPOSITORY TAG IMAGE ID CREATED PLATFORM SIZE BLOB SIZE
pull
作用:从网络上下载镜像。
#下载镜像
[root@containerd ~ 09:59:49]# nerdctl pull busybox
[root@containerd ~ 10:01:19]# nerdctl image pull httpd
#查看
[root@containerd ~ 10:02:20]# nerdctl images
REPOSITORY TAG IMAGE ID CREATED PLATFORM SIZE BLOB SIZE
busybox latest e3652a00a2fa 2 minutes ago linux/amd64 4.3 MiB 2.1 MiB
httpd latest f9b88f3f093d 45 seconds ago linux/amd64 121.0 MiB 43.1 MiB
rm
作用:删除本地不用的镜像。
`image rm == rmi`
[root@containerd ~ 10:02:46]# nerdctl image rm httpd
[root@containerd ~ 10:02:46]# nerdctl rmi httpd
#验证删除
[root@containerd ~ 10:03:07]# nerdctl images
REPOSITORY TAG IMAGE ID CREATED PLATFORM SIZE BLOB SIZE
busybox latest e3652a00a2fa 3 minutes ago linux/amd64 4.3 MiB 2.1 MiB
tag
作用:给镜像打标签。
[root@containerd ~ 10:03:11]# nerdctl tag busybox:latest busybox:v1
save
作用:将本地镜像导出为文件。
#导出镜像为tar包
[root@containerd ~ 10:24:27]# nerdctl save busybox -o busybox.tar
#删除镜像
[root@containerd ~ 10:24:35]# nerdctl rmi busybox
load
作用:导入tar文件中镜像。
[root@containerd ~ 10:25:16]# nerdctl load -i busybox.tar
[root@containerd ~ 10:25:43]# nerdctl images
REPOSITORY TAG IMAGE ID CREATED PLATFORM SIZE BLOB SIZE
busybox latest e3652a00a2fa 15 seconds ago linux/amd64 4.3 MiB 2.1 MiB
history
作用:查看镜像构建时的历史命令层次结构。
[root@containerd ~ 10:25:59]# nerdctl history busybox
#等价于
[root@containerd ~ 10:25:59]# nerdctl image history busybox
inspect
作用:查看镜像详细信息。
[root@containerd ~ 10:26:20]# nerdctl inspect busybox
[
{
"Id": "sha256:08ef35a1c3f050afbbd64194ffd1b8d5878659f5491567f26d1c814513ae9649",
"RepoTags": [
"busybox:latest"
],
"RepoDigests": [
"busybox@sha256:e3652a00a2fabd16ce889f0aa32c38eec347b997e73bd09e69c962ec7f8732ee"
],
"Comment": "",
"Created": "2024-09-26T21:31:42Z",
"Author": "",
"Config": {
"AttachStdin": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"sh"
]
},
"Architecture": "amd64",
"Os": "linux",
"Size": 4493312,
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:e14542cc062958c3bfada9c260a6ae47bb2906fd8b514999774760710dbce3cb"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]
prune
作用:删除所有未使用的镜像。
[root@containerd ~ 10:29:23]# nerdctl image prune --all --force
#这里必须要写image
[root@containerd ~ 10:29:33]# nerdctl images
REPOSITORY TAG IMAGE ID CREATED PLATFORM SIZE BLOB SIZE
nerdctl 管理容器
ls
作用:查看容器清单。
[root@containerd ~ 10:36:29]# nerdctl ps -a 查看包括未运行的容器
[root@containerd ~ 10:36:29]# nerdctl ps 只查看运行的容器
[root@containerd ~ 10:36:29]# nerdctl container ls -a
[root@containerd ~ 10:36:29]# nerdctl container ls
常用选项:
- -a, --all Show all containers (default shows just running)
- -f, --filter strings Filter matches containers based on given conditions
- –format string Format the output using the given Go template, e.g, ‘{{json .}}’, ‘wide’
run
作用:创建并运行容器。
[root@containerd ~ 10:37:59]# nerdctl run -dit ubuntu
FATA[0000] currently flag -i and -d cannot be specified together (FIXME)
#对于nerdctl-d和-i选项不能同时使用
[root@containerd ~ 10:35:26]# nerdctl run -it -h nihao ubuntu
root@nihao:/# exit
exit
#-h == --hostname 设置登陆容器的用户名
常用选项:
-
–cpu-shares uint CPU shares (relative weight)
-
–cpus float Number of CPUS
-
-d, --detach Run container in background and print container ID
-
–dns strings Set custom DNS servers
-
-e, --env stringArray Set environment variables
-
-h, --hostname string Container host name
-
-i, --interactive Keep STDIN open even if not attached
-
–ip string Pv4 address to assign to the container
-
–mac-address string MAC address to assgin to the container
-
-m, --memory string Memory limit
-
–name string Assign a name to the container
-
–net strings Connect a container to a network (“bridge”|“host”|“none”|) (default [bridge])
-
–network strings Connect a container to a network (“bridge”|“host”|“none”|“container:”|) (default [bridge])
-
–privileged Give extended privileges to this container
-
–pull string Pull image before running (“always”|“missing”|“never”) (default “missing”)
-
–restart string Restart policy to apply when a container exits (implemented values: “no”|“always|on-failure:n|unless-stopped”) (default “no”)
-
–rm Automatically remove the container when it exits
-
–runtime string Runtime to use for this container, e.g.
-
–stop-signal string Signal to stop a container (default “SIGTERM”)
-
–stop-timeout Timeout (in seconds) to stop a container
-
-t, --tty Allocate a pseudo-TTY
-
-v, --volume Bind mount a volume
rename
作用:重命名容器。
[root@containerd ~ 10:40:02]# nerdctl run -d --name ubuntu-1 ubuntu
[root@containerd ~ 10:40:55]# nerdctl rename ubuntu-1 ubuntu1
rm
作用:删除容器。
[root@containerd ~ 10:41:19]# nerdctl rm ubuntu1
#或者nerdctl container rm ubuntu1
prune
作用:删除所有未运行的容器。
[root@containerd ~ 10:39:43]# nerdctl container prune --force
#相比于镜像删除所有未运行的容器不能加--all
stop 和 start
作用:停止和启动容器。
[root@containerd ~ 10:41:38]# nerdctl run -d --name web1 httpd
[root@containerd ~ 10:42:30]# nerdctl stop web1
[root@containerd ~ 10:42:47]# nerdctl start web1
[root@containerd ~ 10:44:03]# nerdctl ps -a --format "{{.Names}} {{.Status}}"
web1 Up `{{}}之间用空格隔开,查看的列名首字母大写`
restart
作用:重启容器。
[root@containerd ~ 10:54:37]# nerdctl restart web1
pause 和 unpause
作用:挂起和取消挂起容器。
[root@containerd ~ 10:55:08]# nerdctl pause web1
[root@containerd ~ 10:55:20]# nerdctl ps -a --format "{{.Names}} {{.Status}}"
web1 Paused
[root@containerd ~ 10:55:21]# nerdctl unpause web1
[root@containerd ~ 10:55:27]# nerdctl ps -a --format "{{.Names}} {{.Status}}"
web1 Up
kill
作用:给容器发信号,默认发KILL信号。
[root@containerd ~ 10:55:30]# nerdctl kill web1
[root@containerd ~ 10:55:53]# nerdctl ps -a --format "{{.Names}} {{.Status}}"
web1 Exited (137) 2 seconds ago
exec
作用:在运行的容器内部执行命令。
[root@containerd ~ 10:56:58]# nerdctl exec -it web1 bash
root@d8a5e660c9b4:/usr/local/apache2# exit
cp
作用:将宿主机文件复制给容器。
[root@containerd ~ 10:57:41]# nerdctl cp /etc/hostnmae web1:
#将文件cp到web1的根目录
[root@containerd ~ 11:11:40]# nerdctl exec web1 -- ls /hostname
/hostname
[root@containerd ~ 11:11:40]# nerdctl exec web1 ls /hostname
/hostname
#这里不进入容器在外面执行命令加不加--都可以,加是为了适应kubernetes
inspect
作用:查看容器详细信息。
[root@containerd ~ 11:12:16]# nerdctl inspect web1
logs
作用:显示容器console终端内容。
[root@containerd ~ 11:12:59]# nerdctl logs web1
port
作用:显示宿主机和容器之间端口映射关系。
[root@containerd ~ 11:13:15]# nerdctl run -d -p 8080:80 --name web2 httpd
[root@containerd ~ 11:13:50]# curl 192.168.108.128:8080
<html><body><h1>It works!</h1></body></html>
commit
作用:将容器提交为镜像。
[root@containerd ~ 11:23:09]# nerdctl commit web1 web:v1
sha256:57a04c9023147a69e034508f17b6ff21186cd4029dce1de8d05bc11b4e90880c
#镜像要在运行状态写镜像名和ID都可以
#查看
[root@containerd ~ 11:24:03]# nerdctl images
REPOSITORY TAG IMAGE ID CREATED PLATFORM SIZE BLOB SIZE
web v1 d7ba3f2bb794 12 seconds ago linux/amd64 121.0 MiB 43.1 MiB
nerdctl 管理存储
[root@containerd ~ 10:31:28]# nerdctl volume --help
Manage volumes
Usage: nerdctl volume [flags]
Commands:
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes
nerdctl 命令创建容器的时候,可以使用 -v 选项将本地目录挂载给容器实现数据持久化。
[root@containerd ~ 11:29:09]# touch /data/f1
#将目录挂载给容器内的/data
[root@containerd ~ 11:29:35]# nerdctl exec busybox-b7efb -- ls /data
f1
#自动生成一个卷,将容器内/data的内容复制给自动生成的卷
[root@containerd ~ 11:42:42]# nerdctl run -d -v /data busybox -- sleep infinity
[root@containerd ~ 11:43:56]# nerdctl exec busybox-bda8c -- touch /data/f2
#将卷名命为data挂载给/data
[root@containerd ~ 11:42:50]# nerdctl run -d -v data:/data busybox -- sleep infinity
[root@containerd ~ 11:45:39]# nerdctl exec busybox-2e503 -- touch /data/f3
#查看卷
[root@containerd ~ 11:43:34]# nerdctl volume ls
VOLUME NAME DIRECTORY
9fbb926f1c772a1a7927a46f97eef7c8cb4fd0d717febfb5181cef562eb60d6d /var/lib/nerdctl/1935db59/volumes/default/9fbb926f1c772a1a7927a46f97eef7c8cb4fd0d717febfb5181cef562eb60d6d/_data
data /var/lib/nerdctl/1935db59/volumes/default/data/_data
#验证
[root@containerd ~ 11:46:07]# ls /var/lib/nerdctl/1935db59/volumes/default/data/_data
f3
[root@containerd ~ 11:46:31]# ls /var/lib/nerdctl/1935db59/volumes/default/9fbb926f1c772a1a7927a46f97eef7c8cb4fd0d717febfb5181cef562eb60d6d/_data
f2
nerdctl 管理网络
Containerd 中的网络与Docker类似,所有网络接口默认都是虚拟接口。
当使用nerdctl创建容器时,nerdctl命令会创建一个名称为bridge的Linux网桥(其上有一个nerdctl0内 部接口),利用了Linux虚拟网络技术,在本地主机和容器内分别创建一个虚拟接口,并让它们彼此连通 (这样的一对接口叫做vethpair)。Containerd 默认指定了nerdctl0接口的IP地址和子网掩码,让主机 和容器之间可以通过网桥相互通信。
[root@containerd ~ 11:26:21]# nerdctl ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2e50329b72e9 docker.io/library/busybox:latest "sleep infinity" 49 minutes ago Up busybox-2e503
b7efbf22c157 docker.io/library/busybox:latest "sleep infinity" About an hour ago Up busybox-b7efb
bda8cff512fd docker.io/library/busybox:latest "sleep infinity" 50 minutes ago Up busybox-bda8c
#查看容器的ip
[root@containerd ~ 12:33:27]# nerdctl exec busybox-2e503 -- ip a
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@if18:` <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 1a:9c:27:f4:76:0d brd ff:ff:ff:ff:ff:ff
inet 10.4.0.16/24 brd 10.4.0.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::189c:27ff:fef4:760d/64 scope link
valid_lft forever preferred_lft forever
#查看宿主机的ip
[root@containerd ~ 12:34:10]# ip a
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
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:c4:cd:50 brd ff:ff:ff:ff:ff:ff
altname enp3s0
inet 192.168.108.128/24 brd 192.168.108.255 scope global noprefixroute ens160
valid_lft forever preferred_lft forever
inet 192.168.108.129/24 brd 192.168.108.255 scope global secondary dynamic noprefixroute ens160
valid_lft 1221sec preferred_lft 1221sec
inet6 fe80::20c:29ff:fec4:cd50/64 scope link
valid_lft forever preferred_lft forever
3: nerdctl0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether c2:83:ab:da:4e:47 brd ff:ff:ff:ff:ff:ff
inet 10.4.0.1/24 brd 10.4.0.255 scope global nerdctl0
valid_lft forever preferred_lft forever
inet6 fe80::c083:abff:feda:4e47/64 scope link
valid_lft forever preferred_lft forever
16: vethb2157a0e@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master nerdctl0 state UP group default
link/ether a6:e4:d4:5f:88:04 brd ff:ff:ff:ff:ff:ff link-netnsid 3
inet6 fe80::a4e4:d4ff:fe5f:8804/64 scope link
valid_lft forever preferred_lft forever
17: vethf37d8cd3@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master nerdctl0 state UP group default
link/ether 76:7c:d6:d7:90:d3 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::747c:d6ff:fed7:90d3/64 scope link
valid_lft forever preferred_lft forever
`18: vethb81fbdaa@if2:` <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master nerdctl0 state UP group default
link/ether 7a:f8:35:3c:47:5d brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::78f8:35ff:fe3c:475d/64 scope link
valid_lft forever preferred_lft forever
#注意看绿色部分是网卡相对应的部分
#查看网络类型
[root@containerd ~ 12:34:22]# nerdctl network ls
NETWORK ID NAME FILE
17f29b073143 bridge /etc/cni/net.d/nerdctl-bridge.conflist
host
none
#显示网络类型的详细信息需要加network,显示image container 不需要特别说明
[root@containerd ~ 12:35:41]# nerdctl network inspect bridge
[
{
"Name": "bridge",
"Id": "17f29b073143d8cd97b5bbe492bdeffec1c5fee55cc1fe2112c8b9335f8b6121",
"IPAM": {
"Config": [
{
"Subnet": "10.4.0.0/24",
"Gateway": "10.4.0.1"
}
]
},
"Labels": {
"nerdctl/default-network": "true"
}
}
]
#宿主机和容器subnet range相互对应
[root@containerd ~ 12:35:53]# ip -br a
lo UNKNOWN 127.0.0.1/8 ::1/128
ens160 UP 192.168.108.128/24 192.168.108.129/24 fe80::20c:29ff:fec4:cd50/64
nerdctl0 UP 10.4.0.1/24 fe80::c083:abff:feda:4e47/64
vethb2157a0e@if2 UP fe80::a4e4:d4ff:fe5f:8804/64
vethf37d8cd3@if2 UP fe80::747c:d6ff:fed7:90d3/64
vethb81fbdaa@if2 UP fe80::78f8:35ff:fe3c:475d/64
[root@containerd ~ 12:38:03]# ip addr show nerdctl0
3: nerdctl0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether c2:83:ab:da:4e:47 brd ff:ff:ff:ff:ff:ff
inet 10.4.0.1/24 brd 10.4.0.255 scope global nerdctl0
valid_lft forever preferred_lft forever
inet6 fe80::c083:abff:feda:4e47/64 scope link
valid_lft forever preferred_lft forever
可以下载工具用于查看bridge网络的网线名
[root@containerd ~ 12:39:46]# yum install -y bridge-utils
[root@containerd ~ 12:40:03]# brctl show
bridge name bridge id STP enabled interfaces
nerdctl0 8000.c283abda4e47 no vethb2157a0e
vethb81fbdaa
vethf37d8cd3
nerdctl 管理命名空间
[root@containerd ~ 11:46:42]# nerdctl namespace ls
NAME CONTAINERS IMAGES VOLUMES LABELS
default 3 4 2
[root@containerd ~ 11:47:04]# ctr namespace create mysn
[root@containerd ~ 11:47:43]# nerdctl namespace ls
NAME CONTAINERS IMAGES VOLUMES LABELS
default 3 4 2
mysn 0 0 0
crictl 实践
crictl 命令介绍
crictl 命令是遵循 CRI 接口规范的一个命令行工具,通常用它来检查和管理 行时和镜像。
在kubernetes集群环境中,当我们执行 kubectl 命令式, kubelet 节点上的容器运 kubelet 代理会自动调用crictl命令管理镜像 和容器。 手动执行 crictl 命令时,一般用于查看镜像和容器。
crictl 命令安装
配置kubernetes源:
[root@containerd ~ 11:47:45]# vim /etc/yum.repos.d/kubernetes.repo
安装CRI命令
[root@containerd ~ 11:48:52]# yum install -y cri-tools
crictl 命令配置
使用c rictl 命令之前,需要先配置 /etc/crictl.yaml 。
示例:配置crictl后端运行时使用containerd。
[root@containerd ~ 11:49:10]# vim /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 5
debug: false
#.sock结尾的文件适用于通信连接
命令行对照表


更多推荐



所有评论(0)