【从零造容器】runc 源码考古:OCI 参考实现到底长什么样

💡 原文中文,约6800字,阅读约需16分钟。
📝

内容提要

本文分析了runc的架构与设计,探讨了其与其他容器运行时的区别。runc采用两阶段初始化,使用C代码处理namespace切换,以克服Go运行时的限制。文章强调了安全性的重要性,包括关闭多余的文件描述符和支持seccomp过滤。通过对比指出miniruntime的不足,强调了cgroup管理和PTY管理的复杂性。整体上,runc的设计体现了工程上的优雅与安全性。

🎯

关键要点

  • runc 是 OCI Runtime 的参考实现,代码量大于其他迷你运行时,主要处理边缘情况。

  • runc 的架构包括 libcontainer,提供了容器接口、cgroup 管理和 seccomp 过滤等功能。

  • nsenter 使用 C 代码进行 namespace 切换,以克服 Go 运行时的限制,确保安全性。

  • runc 采用两阶段初始化,分为 bootstrap 和 standard 两个阶段,分别处理 namespace 和文件系统等操作。

  • runc 使用 FIFO 作为 create 和 start 的同步机制,解决了两个独立进程之间的通信问题。

  • 与 miniruntime 相比,runc 在安全性、cgroup 管理和 PTY 管理等方面表现更为出色。

  • 从 runc 的设计中可以学习到 C 和 Go 的分工、安全默认值的重要性以及两阶段初始化的优雅性。

延伸问答

runc的主要功能是什么?

runc是OCI Runtime的参考实现,主要处理容器的创建、管理和安全性。

runc与miniruntime相比有哪些优势?

runc在安全性、cgroup管理和PTY管理等方面表现更为出色,能够处理更多边缘情况。

runc的两阶段初始化是如何工作的?

runc的两阶段初始化分为bootstrap和standard两个阶段,分别处理namespace和文件系统等操作。

为什么runc使用C代码进行namespace切换?

因为Go运行时在fork后执行代码不安全,使用C代码可以确保在单线程状态下安全切换namespace。

runc是如何确保容器安全性的?

runc通过关闭多余的文件描述符、支持seccomp过滤和设置安全默认值来确保容器的安全性。

runc的FIFO同步机制有什么优势?

FIFO作为命名管道,允许独立进程之间的通信,简单、可靠且易于调试。

➡️

继续阅读