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 兼容),以便更便捷地操作容器。祝入門順利!