从安装到上手:Ubuntu 22.04 玩转 Containerd 2.1.3 容器运行时
Containerd 是一款支持 OCI 规范的容器运行时,注重容器部署和生命周期管理的简单性、健壮性与可移植性,常被嵌入到 Docker 和 Kubernetes 等系统中。本文将详细介绍在 Ubuntu 22.04 服务器上通过二进制包手动安装 Containerd 的完整步骤,包括相关组件的安装与配置。
一、安装 Containerd 组件
首先,你需要学习如何通过二进制包手动安装Containerd容器运行时。在此过程中,你还得为Containerd安装一些必要组件,像runc和CNI(容器网络接口)插件都包含在内。
Containerd及其所有组件均可在其GitHub仓库中找到,随时可供安装。
安装Containerd的步骤如下:先访问Containerd的GitHub发布页面,获取最新版本的相关信息;接着复制该版本的下载链接,用wget工具将Containerd的二进制包下载下来;最后把下载的文件解压到/usr/local目录。
1. 安装containerd核心
Containerd 及其组件可在其 GitHub 存储库中获取。首先需要查看 Containerd GitHub 发布页面 以获取最新版本,然后通过以下命令下载并解压:
在本文撰写时,Containerd的最新版本为v2.1.3。你可以在Ubuntu服务器上使用wget命令下载该版本,再通过tar命令将其解压到/usr/local目录。
# 本文以 v2.1.3 版本为例
root@k8s-master:~# wget https://github.com/containerd/containerd/releases/download/v2.1.3/containerd-2.1.3-linux-amd64.tar.gz
root@k8s-master:~# tar Cxzvf /usr/local containerd-2.1.3-linux-amd64.tar.gz
bin/
bin/containerd
bin/containerd-shim-runc-v2
bin/ctr
bin/containerd-stress
2. 安装 runc
runc 是一款根据 OCI 规范生成容器的命令行工具,从 runc GitHub 发布页面 获取最新版本安装:
# 本文以 v1.3.0 版本为例
root@k8s-master:~# wget https://github.com/opencontainers/runc/releases/download/v1.3.0/runc.amd64
root@k8s-master:~# install -m 755 runc.amd64 /usr/local/sbin/runc
root@k8s-master:~# which runc
/usr/local/sbin/runc
安装完成后,可通过 which runc
命令验证,若输出 /usr/local/sbin/runc
则表示安装成功。
3. 安装 CNI 插件
CNI(容器网络接口)插件为容器提供网络功能,需从 CNI 插件 GitHub 发布页面 获取最新版本:
# 本文以 v1.3.0 版本为例
root@k8s-master:~# wget https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-amd64-v1.3.0.tgz
# 创建安装目录并解压
root@k8s-master:~# mkdir -p /opt/cni/bin
root@k8s-master:~# tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.3.0.tgz
./
./loopback
./bandwidth
./ptp
./vlan
./host-device
./tuning
./vrf
./sbr
./tap
./dhcp
./static
./firewall
./macvlan
./dummy
./bridge
./ipvlan
./portmap
./host-local
二、配置 Containerd
安装完所有组件后,需进行如下配置以确保 Containerd 正常运行:
1. 生成默认配置文件:
root@k8s-master:~# mkdir -p /etc/containerd/
root@k8s-master:~# containerd config default | sudo tee /etc/containerd/config.toml
version = 3
root = '/var/lib/containerd'
state = '/run/containerd'
temp = ''
disabled_plugins = []
required_plugins = []
oom_score = 0
imports = []
......
2. 启用 SystemdCgroup
该操作会将配置文件中的 SystemdCgroup = false
改为 SystemdCgroup = true
,以支持 systemd 控制组:
root@k8s-master:~# sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
验证是否启动只需要grep配置即可
root@k8s-master:~# cat /etc/containerd/config.toml | grep -i systemdcgroupSystemdCgroup = trueroot@k8s-master:~# journalctl -u containerd | grep -i "systemdcgroup"
Jul 19 10:45:13 k8s-master containerd[16895]: time="2025-07-19T10:45:13.086716772+08:00" level=info msg="starting cri plugin" config="{\"containerd\":{\"defaultRuntimeName\":\"runc\",\"runtimes\":{\"runc\":{\"runtimeType\":\"io.containerd.runc.v2\",\"runtimePath\":\"\",\"PodAnnotations\":[],\"ContainerAnnotations\":[],\"options\":{\"BinaryName\":\"\",\"CriuImagePath\":\"\",\"CriuWorkPath\":\"\",\"IoGid\":0,\"IoUid\":0,\"NoNewKeyring\":false,\"Root\":\"\",\"ShimCgroup\":\"\",\"SystemdCgroup\":true},\"privileged_without_host_devices\":false,\"privileged_without_host_devices_all_devices_allowed\":false,\"cgroupWritable\":false,\"baseRuntimeSpec\":\"\",\"cniConfDir\":\"\",\"cniMaxConfNum\":0,\"snapshotter\":\"\",\"sandboxer\":\"podsandbox\",\"io_type\":\"\"}},\"ignoreBlockIONotE
如果没有此配置,则手动添加即可。
找到 [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
部分(如果没有则手动创建层级),添加 SystemdCgroup = true
:
root@k8s-master:~# cat /etc/containerd/config.toml | grep -ni -C 5 'systemdcgroup'
95- snapshotter = ''
96- sandboxer = 'podsandbox'
97- io_type = ''
98-
99- [plugins.'io.containerd.cri.v1.runtime'.containerd.runtimes.runc.options]
100: SystemdCgroup = true
101- BinaryName = ''
102- CriuImagePath = ''
103- CriuWorkPath = ''
104- IoGid = 0
105- IoUid = 0
如果输出中包含 SystemdCgroup: true
,则表示手动配置成功。此配置在 Kubernetes 环境中尤为重要,确保容器的 cgroup 驱动与 kubelet 保持一致(均为 systemd)。
3. 设置 systemd 服务
直接复制即可
root@k8s-master:~# 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 dbus.service[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/containerdType=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# 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
4. 启动并启用服务
root@k8s-master:~# systemctl daemon-reload
root@k8s-master:~# systemctl start containerd
root@k8s-master:~# systemctl enable containerd
5. 验证服务状态
执行 systemctl status containerd
命令,若输出中显示 active(running)
则表示服务启动成功。
root@k8s-master:~# systemctl status containerd.service
● containerd.service - containerd container runtimeLoaded: loaded (/etc/systemd/system/containerd.service; enabled; vendor preset: enabled)Active: active (running) since Sat 2025-07-19 09:57:57 CST; 12s agoDocs: https://containerd.ioMain PID: 3744 (containerd)Tasks: 9Memory: 13.1MCPU: 178msCGroup: /system.slice/containerd.service└─3744 /usr/local/bin/containerdJul 19 09:57:57 k8s-master containerd[3744]: time="2025-07-19T09:57:57.274448607+08:00" level=info msg="Start recovering state"
Jul 19 09:57:57 k8s-master containerd[3744]: time="2025-07-19T09:57:57.274750311+08:00" level=info msg="Start event monitor"
Jul 19 09:57:57 k8s-master containerd[3744]: time="2025-07-19T09:57:57.274911742+08:00" level=info msg="Start cni network conf syncer for default"
Jul 19 09:57:57 k8s-master containerd[3744]: time="2025-07-19T09:57:57.275083463+08:00" level=info msg="Start streaming server"
Jul 19 09:57:57 k8s-master containerd[3744]: time="2025-07-19T09:57:57.275362835+08:00" level=info msg="Registered namespace \"k8s.io\" with NRI"
Jul 19 09:57:57 k8s-master containerd[3744]: time="2025-07-19T09:57:57.275605709+08:00" level=info msg="runtime interface starting up..."
Jul 19 09:57:57 k8s-master containerd[3744]: time="2025-07-19T09:57:57.275738617+08:00" level=info msg="starting plugins..."
Jul 19 09:57:57 k8s-master containerd[3744]: time="2025-07-19T09:57:57.275879079+08:00" level=info msg="Synchronizing NRI (plugin) with current runtime stat>
Jul 19 09:57:57 k8s-master containerd[3744]: time="2025-07-19T09:57:57.276191212+08:00" level=info msg="containerd successfully booted in 0.084635s"
Jul 19 09:57:57 k8s-master systemd[1]: Started containerd container runtime.
三、containerd配置国内镜像源
1. 编辑配置文件
vi /etc/containerd/config.toml
2. 添加镜像加速配置
在 [plugins."io.containerd.grpc.v1.cri"]
部分下,补充 registry.mirrors
配置(若已有该节点,直接添加内容):
[plugins."io.containerd.grpc.v1.cri"]# 已有的其他配置...[plugins."io.containerd.grpc.v1.cri".registry][plugins."io.containerd.grpc.v1.cri".registry.mirrors][plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]endpoint = ["https://docker.1panel.live","https://docker.1ms.run","https://dytt.online","https://lispy.org","https://docker-0.unsee.tech","https://docker.xiaogenban1993.com","https://666860.xyz","https://hub.rat.dev","https://docker.m.daocloud.io","https://demo.52013120.xyz","https://proxy.vvvv.ee","https://registry.cyou"]
3. 重启 containerd 生效
systemctl daemon-reload
systemctl restart containerd
- 上述
endpoint
列表包含多个国内可用的 DockerHub 加速镜像,若某个地址不可用,会自动尝试下一个。 - 配置后,containerd 拉取
docker.io
镜像时会优先使用这些加速源,提升拉取速度。
四、Containerd常用命令汇总
1. 名称空间管理:资源隔离的核心
名称空间是 Containerd 实现资源隔离的关键机制,通过不同的命名空间,可以将容器、镜像等资源进行逻辑划分,避免相互干扰。
2. 基本操作示例
- 查看所有名称空间:
ctr ns ls
该命令会列出当前系统中所有的 Containerd 名称空间,方便了解资源隔离的范围。
- 创建名称空间:
ctr ns create myonly
新建一个名为 myonly 的名称空间,后续可在该空间内管理独立的容器和镜像。
- 删除名称空间:
ctr ns rm linux96
删除不再使用的 linux96 名称空间,注意删除前需确保该空间内无运行的容器或重要镜像。
- 带标签创建名称空间:
ctr ns c linux96 linux97=true
创建 linux96 名称空间时添加标签 linux97=true,便于对名称空间进行分类管理。
3. 镜像管理:从拉取到推送的全流程
镜像作为容器的基础,其管理包括拉取、标签、推送、导入导出等操作,Containerd 提供了简洁高效的命令支持。
3.1. 基础操作示例
- 查看指定命名空间的镜像:
ctr -n myonly image ls
通过 -n 参数指定名称空间 myonly,查看该空间下的所有镜像列表。
- 拉取第三方镜像:
ctr -n myonly image pull registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1
从阿里云镜像仓库拉取指定镜像到 myonly 名称空间,适用于快速获取所需容器镜像。
- 为镜像打标签:
ctr -n myonly image tag registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1 myapp:v1
将原镜像重新标记为 myapp:v1,方便后续识别和使用。
3.2. 高级操作示例
- 推送镜像到 Harbor:
ctr image push -u admin:123456 harbor250.myonly.com/library/stress:v0.2
使用 -u 参数指定 Harbor 仓库的用户名和密码,将镜像推送到私有仓库,实现镜像的集中管理。
- 镜像导入导出:
# 导出镜像
ctr image export app_v1.tar.gz registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1
# 导入镜像
ctr image import app_v1.tar.gz
通过导出 / 导入操作,可在无网络环境下迁移镜像,灵活应对不同部署场景。
- 删除指定镜像:
ctr -n myonly image rm myonly:linux96
清理 myonly 名称空间中不再需要的镜像,释放存储空间。
3.3. 容器生命周期管理:从创建到销毁的全流程
容器的生命周期包括创建、启动、暂停、恢复、停止、删除等阶段,Containerd 通过 containers 和 task 命令组实现精细化管理。
4. 容器操作示例
- 创建容器:
ctr -n myonly containers create myapp:v1 app1
在 myonly 名称空间中,基于 myapp:v1 镜像创建名为 app1 的容器(此时容器处于未运行状态)。
- 查看容器列表:
ctr -n myonly containers ls
列出 myonly 名称空间中所有已创建的容器,包括运行和未运行的状态。
- 删除容器:
ctr -n myonly containers rm app1
删除指定容器,删除前需确保容器对应的任务已停止。
5. 任务管理示例
- 启动容器任务:
ctr -n myonly task start -d app1
以后台模式(-d)启动 app1 容器的任务,此时容器进入运行状态。
- 查看运行中任务:
ctr -n myonly task ls
查看 myonly 名称空间中所有正在运行的容器任务。
- 进入容器内部:
ctr -n myonly task exec -t --exec-id $RANDOM app1 sh
通过 exec 命令进入运行中的 app1 容器,-t 参数分配终端,--exec-id 指定随机 ID 避免冲突。
- 任务控制(暂停 / 恢复 / 停止):
# 暂停任务ctr -n myonly task pause app1# 恢复任务ctr -n myonly task resume app1# 停止任务ctr -n myonly task kill app1
灵活控制容器任务的运行状态,适用于调试或资源调整场景。
6. 存储与网络管理:容器的资源配置
6.1. 存储卷挂载示例
Containerd 支持通过绑定挂载实现宿主机与容器的文件共享,可指定读写权限:
- 只读挂载:
ctr run -d --mount type=bind,src=/host/data,dst=/container/data,options=rbind:ro myapp:v1 app2
将宿主机 /host/data 目录以只读模式挂载到容器 /container/data 目录,防止容器内误修改宿主机文件。
- 读写挂载:
ctr run -d --mount type=bind,src=/host/logs,dst=/container/logs,options=rbind:rw myapp:v1 app3
以读写模式挂载目录,适用于容器需要向宿主机写入日志、数据等场景。
6.2. 网络配置示例
- 共享宿主机网络:
ctr -n myonly run -d --net-host myapp:v1 app4 /bin/sh -c "while true; do sleep 3600; done"
通过 --net-host 参数让容器共享宿主机的网络命名空间,容器可直接使用宿主机的 IP 和端口。
7. 监控与排错:保障容器稳定运行
7.1. 容器指标查看
ctr -n myonly task metrics app1
查看 app1 容器的资源使用指标,包括 CPU、内存、I/O 等,帮助分析容器性能。
7.2. 常见报错处理
- HTTPS 证书错误:
错误现象:x509: certificate signed by unknown authority
解决方案:
-
- 确保 CA 证书正确安装到 /etc/docker/certs.d/域名目录
-
- 使用 --plain-http 参数强制使用 HTTP 协议
- 镜像推送认证失败:
错误现象:401 Unauthorized
解决方案:
ctr image push --plain-http -u 用户名:密码 镜像名
8. 高级特性与实用命令
8.1. 跨命名空间操作
ctr -n 命名空间名
通过 -n 参数可直接操作指定命名空间的资源,无需切换上下文。
8.2. 快照管理
(需参考官方文档进行深度配置)
8.3. 镜像导出
ctr image export 导出文件.tar.gz 镜像名
8.4. 容器日志查看
ctr -n myonly task logs app1
8.5. 资源限制
ctr run --memory-limit 512M --cpus 1 镜像名 容器名
8.6. 容器元数据查看
ctr -n myonly containers info app1
9. 常用命令汇总表
操作类别 | 命令用途 | 示例命令 |
名称空间管理 | 查看命名空间 | ctr ns ls |
名称空间管理 | 创建命名空间 | ctr ns create myonly |
镜像管理 | 拉取镜像 | ctr -n myonly image pull 镜像地址 |
镜像管理 | 推送镜像到仓库 | ctr image push -u 用户名:密码 镜像名 |
容器管理 | 创建容器 | ctr -n myonly containers create 镜像名 容器名 |
容器管理 | 启动容器任务 | ctr -n myonly task start -d 容器名 |
存储管理 | 只读挂载目录 | ctr run -d --mount type=bind,src=/host,dst=/container,options=rbind:ro 镜像名 容器名 |
网络配置 | 共享宿主机网络 | ctr run -d --net-host 镜像名 容器名 |
监控排错 | 查看容器指标 | ctr -n myonly task metrics 容器名 |
高级操作 | 限制容器资源 | ctr run --memory-limit 512M --cpus 1 镜像名 容器名 |
通过上述命令,你可以轻松完成 Containerd 从基础到进阶的各项操作。无论是日常的容器管理,还是复杂的镜像分发与资源控制,这些命令都能满足你的需求。在实际使用中,可根据具体场景灵活组合,提升容器管理效率。
五、总结
通过以上步骤,完全可以在 Ubuntu 22.04 上手动完成了 Containerd 容器运行时的安装与配置,包括核心组件、runc 和 CNI 插件的安装,以及相关服务的设置。完成后,可以基于此环境进行容器开发,或作为 Kubernetes 集群的一部分使用。如果需要管理容器,可进一步安装 nerdctl
工具(与 Docker CLI 兼容),以便更便捷地操作容器。祝入门顺利!