我决定为了好玩自己做一个容器运行时。虽然我还处于早期阶段,但我已经发现Docker很奇怪。这里是我了解到的一些关于Docker的奇怪之处。
容器并不是真实存在的东西。与虚拟机不同,容器只是带有特殊限制的进程。你的内核仍在运行该进程,你可以在/proc中找到它。并不存在单一的Linux容器功能——容器实际上是5个不同的Linux内核功能披着一件风衣组合而成。命名空间隐藏了宿主机和容器各自能看到的内容,cgroups限制资源使用,而网络方面的巧妙设计则隔离了容器的网络。
镜像只是文件夹。Docker将它们放在某处,然后调用chroot(或pivot_root),使该文件夹成为容器的新根目录。Go语言对于容器运行时来说有些糟糕。Docker的运行时runc是用Go编写的,而Go的设计选择使其不太适合这项工作。Go的运行时原生是多线程的,但许多Linux系统调用需要单线程环境,因此runc包含一个C模块,在Go初始化之前运行。Go也没有fork,所以runc通过exec /proc/self/exe来近似实现fork。
Docker需要root权限。许多Linux内核API都需要root权限,因此Docker守护进程通常以root身份运行。无root权限的运行时可能不得不在用户空间中重新实现整个网络协议栈。学习很有趣!编写你每天使用的工具的自有版本,是了解它的绝佳方式。
来源: Hacker News · 由HeadlinesBriefing整理摘要