Containerd:容器宇宙里那个默默扛事的老黄牛(但你真该认识它了!)


朋友们!咱今天就聊聊容器世界里那个**存在感超低却至关重要的狠角色**——Containerd。说真的,每次提到容器,Docker 那可爱的鲸鱼 logo 立刻蹦进脑子,Kubernetes 的舵轮标志也霸气得不行。但**Containerd?** 它就像后台那位穿着格子衫、默默敲代码的大佬,活儿全干了,名声?不存在的!(直到你的集群出问题,深入排查时才惊呼:啊!原来是您老在管事啊?)

## 一、 容器世界的"地基":运行时到底是啥玩意儿?

先别急着跑,咱得把地基打牢了。想象一下你盖房子(容器):

1.  **图纸 (镜像 Image):** 房子的设计蓝图,定义了里面要有啥(比如 Ubuntu + Nginx + 我的代码)。Docker build / Podman build 主要干这个。
2.  **施工队 (容器运行时 Container Runtime):** **负责按图纸把房子 (容器) 真正盖起来并运行!** 这才是 Containerd 的核心战场。它干的是**最脏最累最底层的活**:
    *   从仓库拖图纸 (`docker pull` / `crictl pull` 背后是它)。
    *   按图纸砌砖、通水电 (`container create`)。(理解成创建运行环境:挂载 rootfs、设置 namespaces/cgroups 限制...)
    *   启动住户进程 (`container start`)。
    *   管理房子的生老病死 (`stop`, `pause`, `rm`...)。
    *   处理房子里的垃圾 (`container kill` 清理进程)。
    *   看门+监控 (`events`, `stats`)。

**简单粗暴总结:** 没了运行时,你的镜像就是一坨漂亮的、没法运行的二进制数据!Docker 和 K8s 都**依赖**底层运行时来真正操作容器。

## 二、 Containerd 的崛起:从 Docker 的"内脏"到行业基石

故事时间到!(倒杯咖啡呗☕️)

*   **远古时代 (2013-2016):** Docker 一家独大。它自己就包含了一个完整的容器运行时(当时是 `docker-containerd` + `docker-runc` 的早期组合)。开发者用 Docker CLI (`docker run...`),一切岁月静好(表面上看)。
*   **痛点浮现:**
    *   **Docker 太重了!** 对于只想跑容器、不需要 Docker Swarm/Build 等全家桶的场景(尤其是 K8s),一个臃肿的 Docker Daemon 显得很多余。
    *   **依赖耦合深:** K8s 想直接管理容器生命周期?得通过一层层的 Docker API 调用,效率低,路径长,**复杂且不稳定!**
    *   **标准缺失:** 各家运行时实现五花八门,互操作性是个噩梦。
*   **破局之道:OCI 标准与 CRI**
    *   **OCI (Open Container Initiative):** Linux 基金会搞的,定了容器**镜像格式 (OCI Image Spec)** 和**运行时规范 (OCI Runtime Spec)**。`runc` 成为了最主流的 OCI 运行时参考实现。(`runc` 就是干实际 `fork/exec` 进程 + 设置隔离环境那个小工具)。
    *   **CRI (Container Runtime Interface):** Kubernetes 发明的插件接口!它定义了一组 gRPC 协议。K8s 的 `kubelet` 只认 CRI,**不管**底下是 Docker、Containerd 还是其他什么运行时,只要实现了 CRI 接口就能接入 K8s!(划重点啊同志们!!!)
*   **Containerd 的华丽转身:**
    *   Docker 公司(后改名 Mirantis)有远见!他们意识到需要把核心的**运行时管理能力**独立出来、标准化、让更多人受益。
    *   **2016-2017:** Docker 把 `containerd` 项目捐献给了 **CNCF (云原生计算基金会)**。是的,就是管着 K8s、Prometheus 那帮大佬的基金会!
    *   **使命:** 成为一个**专注于运行容器**的、**工业级**的、**符合标准**的**守护进程 (daemon)**。它定位清晰:
        *   管理容器生命周期(从拉镜像到运行到销毁)。
        *   管理镜像(拉取、存储、转换)。
        *   管理存储卷(Volume)。
        *   提供稳定 API 供上层调用(比如 Docker Engine,比如 K8s CRI 插件)。
        *   **它自己不直接操作 `runc`!** 它通过一个叫 `containerd-shim` 的中间层来管理 `runc` 实例。这个 `shim` 设计超级妙!后面细说。

**结果?Containerd 赢了!而且赢得漂亮!**

*   它成了 **Kubernetes 默认推荐**的容器运行时(尤其是在 1.24 版本弃用内置 Docker shim 之后)!!!
*   Docker Engine 自己也把 Containerd 作为默认底层运行时。
*   几乎所有主流云平台和发行版的 K8s 底层都在用它(GKE, EKS, AKS, 你熟知的 Linux 发行版...)。
*   **轻量、稳定、专注、符合标准**,让它成了大规模容器集群的**不二之选**。

## 三、 Containerd 架构深潜:简洁有力,插件为王!(适合好奇宝宝)

别被“底层”吓到,Containerd 的设计其实相当优雅(至少在我看来)。来,掀开引擎盖瞧瞧:

±-----------------------+ ±-----------------------------------+
| Your Awesome App | | Docker Engine (dockerd) |
| (e.g., docker run) | <—>| (Build, Network Mgmt, API, UX…) |
±-----------------------+ ±-------------±--------------------+
| (Containerd API)
v
±-------------------------------------------------+
| containerd (daemon) |
| ±---------------+ ±---------------+ |
| | Plugins | | GRPC API | <------->| CRI Clients (e.g., kubelet via cri-plugin)
| | (Storage, | | (Core Control) | |
| | Metadata, | ±---------------+ |
| | Events…) | |
| ±---------------+ |
| | |
| | Manage Tasks |
| v |
| ±-----------------------------------------------+|
| | Task Supervisor ||
| | (Manages shims and their lifecycle) ||
| ±-----------------------------------------------+|
| | |
| | (via containerd-shim) |
| v |
| ±-----------------------------------------------+|
| | containerd-shim (per container!) || <-- 关键先生!
| | - Acts as parent for runc ||
| | - Keeps STDIO open (no TTY stuck!) ||
| | - Reports exit status ||
| | - Zombie process reaping ||
| | - Enables live restore on daemon restart || (神设计!)
| ±-----------------------------------------------+|
| | |
| | (OCI Runtime Spec) |
| v |
| ±-----------------------------------------------+|
| | runc (or other OCI runtime) ||
| | (fork/exec the container process, namespaces,||
| | cgroups, seccomp, capabilities…) ||
| ±-----------------------------------------------+|
±-------------------------------------------------+


**核心亮点解析(个人觉得超酷的点):**

1.  **`containerd-shim`:神设计!**
    *   **为啥要它?** 设想:如果 `containerd` 自己直接 `fork/exec` 出 `runc` 来跑容器,那么 `containerd` 就是容器的父进程。一旦 `containerd` 重启或挂掉(虽然它很稳定,但总有运维操作嘛),它的所有子进程(容器)会收到 `SIGKILL` 信号——容器全挂了!灾难!
    *   **`shim` 如何救场:** `containerd` 先 `fork/exec` 出一个 `containerd-shim` 进程。然后,`shim` 再去 `fork/exec` 出 `runc`跑容器。这样:
        *   `containerd` 挂了?没关系!容器的父进程是 `shim`,`shim` 还活着,容器继续跑!
        *   `containerd` 重启后,它能找到存活的 `shim`,重新连接上,继续管理容器。**无缝衔接!** (生产环境救命稻草!!!)
    *   **它还干了啥好事?**
        *   **处理 TTY/STDIO:** 保证即使 `containerd` 断开,你的 `docker attach` / `kubectl logs` 还能用。
        *   **收集退出状态:** 容器挂了?`shim` 确保退出码被正确报告给 `containerd`。
        *   **清理僵尸:** 负责任地“收尸”。
        *   **降低升级影响:** 升级 `containerd` 时,容器通常不受影响!(当然,最好还是滚动重启)

2.  **插件化架构:**
    *   Containerd 的核心职责明确且稳定。其他功能(比如**存储驱动、快照ter、镜像仓库授权、CRI 实现...**) 都设计成了**插件 (Plugins)**!
    *   **好处爆炸多:**
        *   核心更稳定!升级插件不影响核心。
        *   按需启用!生产环境不需要的功能?关掉!安全加固。
        *   生态扩展!社区或厂商可以开发自己的插件满足特定需求(比如 GPU 支持插件)。
        *   CRI 支持就是通过 `cri` 插件实现的!(`cri` 插件把 K8s CRI 请求翻译成 containerd 自己的 API 调用)

3.  **CRI 插件:连接 K8s 的桥梁**
    *   这就是为啥 K8s (kubelet) 能直接驱动 containerd!`cri` 插件实现了 CRI gRPC Server。
    *   它处理 PodSandbox (pause 容器)、Pod 网络、镜像拉取(可配置镜像仓库认证)、容器创建启动销毁等所有 CRI 要求的动作。
    *   通常配置在 `/etc/containerd/config.toml` 里,超级灵活。

## 四、 Containerd vs Docker:剪不断理还乱?**不!定位清晰得很!**

别再傻傻分不清了!他俩是**上下游关系**,不是竞争对手!(虽然历史渊源深)

*   **Docker (Engine / dockerd):**
    *   **定位:** 完整的**开发者体验 (DX) 工具链和平台**。
    *   **包含:**
        *   容器运行时管理(**底层调用 containerd**)
        *   **镜像构建 (`docker build`)**
        *   **镜像仓库交互 (`docker push/pull`)**
        *   高级网络管理(Swarm scope, 跨容器网络)
        *   **用户友好的 CLI (`docker run/ps/exec...`)**
        *   REST API
        *   文档、社区、商业支持等。
    *   **优点:** 开箱即用,开发者友好,功能全家桶。
    *   **缺点:** 相对较重,部分功能在纯运行时场景冗余。

*   **Containerd:**
    *   **定位:** 纯粹的、高性能、稳定的**容器生命周期管理守护进程**。专注底层运行时。
    *   **包含:**
        *   容器生命周期 (create/start/stop/rm...)
        *   镜像管理 (pull/push/存储)
        *   存储卷管理
        *   底层 API (GRPC)
        *   通过插件扩展(如 CRI)。
    *   **优点:** 轻量级、高效稳定、符合标准(OCI)、插件化、CNCF 毕业项目、云原生/K8s 首选。
    *   **缺点:** **没有用户友好的默认 CLI!** 你需要 `ctr` (containerd 自带的测试工具,贼难用) 或者 `nerdctl` (超赞的替代品!) 或者 `crictl` (主要看 CRI 容器) 来操作它。**不处理构建!不提供 Docker 那样的网络抽象!**

**大白话比喻:**
*   **Docker 是辆功能齐全的豪华 SUV:** 能拉人载货(容器),有漂亮内饰和导航(CLI/UX),自带工具箱(Build/Swarm)。适合家庭出游(开发者本地)。
*   **Containerd 是重型卡车的底盘和引擎:** 极其坚固可靠,动力澎湃,专注于承载核心负荷(运行容器)。但你要自己配驾驶室(CLI)、货箱(网络/构建)才能组成一辆完整的卡车(生产集群)。它是物流车队(云平台/K8s)的绝对主力。

**结论:** 你开发应用、本地调试?Docker 依然很棒!跑大规模生产 K8s 集群?Containerd 是基石!**Docker Engine 离不开 Containerd,现代 K8s 集群拥抱 Containerd。**

## 五、 上手 Containerd:直击要害操作指南(告别 `ctr` 的地狱!)

我知道 `ctr` 的命令行设计得...呃...不太友好(这是客气的说法)。别慌!强推神器 **[nerdctl](https://github.com/containerd/nerdctl)**!它提供了类似 `docker` CLI 的用户体验,直接操作 containerd!**(开发者福音!!!)**

假设你已经装了 containerd(大部分 K8s 发行版默认装好了)。装 `nerdctl`:

```bash
# 去 GitHub release 页面找最新版,比如:
wget https://github.com/containerd/nerdctl/releases/download/v1.7.2/nerdctl-1.7.2-linux-amd64.tar.gz
tar -xvf nerdctl-1.7.2-linux-amd64.tar.gz -C /usr/local/bin/

基础操作 (感觉是不是很 Docker?):

# 1. 拉镜像 (默认使用 Docker Hub)
nerdctl pull nginx:alpine

# 2. 运行容器!(熟悉的配方)
nerdctl run -d --name my-nginx -p 8080:80 nginx:alpine

# 3. 查看运行中的容器
nerdctl ps

# 4. 看日志
nerdctl logs my-nginx

# 5. 进容器 shell
nerdctl exec -it my-nginx sh

# 6. 停止 & 删除
nerdctl stop my-nginx
nerdctl rm my-nginx

高级玩法(nerdctl 也支持很多):

  • 构建镜像: nerdctl build -t my-image . (需要 buildkitd)
  • Compose: nerdctl compose up -d (兼容 docker-compose.yml!本地开发测试更方便了)
  • 管理镜像: nerdctl images, nerdctl rmi ...
  • 管理网络 (nerdctl network ...) / 卷 (nerdctl volume ...)

查看 Containerd 管理的容器:

# 使用 crictl (如果你是 K8s 环境,crictl 默认就是配好连 Containerd 的)
crictl ps
crictl images

# 或者直接用 nerdctl (不加 `-n k8s.io` 看的是 default 命名空间,K8s 容器通常在 `k8s.io`)
nerdctl -n k8s.io ps

配置 (/etc/containerd/config.toml) : 这才是重点!生产环境必调!常见项:

  • systemd_cgroup = true (如果系统用 systemd,务必开启!尤其 K8s!不然资源统计不准!)
  • 镜像仓库 mirror / 认证: 加速拉取,访问私有仓库。
  • sandbox_image (pause 镜像): 指定 K8s 用的 pause 镜像地址。
  • 日志驱动/选项: 控制容器日志格式、大小限制 (json-filejournald 常见)。
  • 存储驱动 (io.containerd.runc.v2 是主流) / 快照ter (overlayfs 主流)。

(超级重要) 改完配置记得重启服务:sudo systemctl restart containerd

六、 我为什么觉得 Containerd 是未来?(个人碎碎念)

  1. Kubernetes 的“官方选择”: 事实标准的力量是巨大的。社区、生态、工具链都围绕着它优化。稳定性、性能的投入是持续的。
  2. “Less is More” 的胜利: 它完美诠释了单一职责原则。只做运行时,做到极致。这带来了惊人的稳定性和低资源消耗。在一个动辄成百上千节点的 K8s 集群里,每节点省一点 CPU/Memory,整体收益巨大!
  3. 插件化带来无限可能: GPU、FPGA、特殊硬件加速?安全沙箱(Kata Containers, gVisor)?新的存储后端?都可以通过插件集成!核心依然保持纯净。这种架构的生命力太强了。
  4. OCI 标准的坚定执行者: 拥抱开放标准是避免厂商锁定的关键。Containerd 和 runc 的组合是 OCI 的标杆实现。
  5. 社区与基金会背书: CNCF 毕业项目意味着极高的成熟度、完善度以及活跃健康的社区支持。企业用着放心。
  6. 摆脱 Docker 的历史包袱: Docker 曾经是伟大的开创者,但其架构设计(尤其是早期)为了快速迭代,包含了一些历史包袱和较强的耦合。Containerd 作为后起之秀,设计更清晰、更现代。

当然,也有槽点:

  • 用户体验门槛: 没有 nerdctl 之前(或者 crictl),原生 ctr 真的让人抓狂。现在好多了,但生态工具链相比 Docker 的成熟度和统一性,仍需努力(尤其在非 K8s 场景)。
  • 学习曲线: 想真正理解它的架构(特别是 sh
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值