背景 链接到标题 最近在阅读 runc 的实现,发现在 runc 中比较重要的一个逻辑是在设置 namespace 过程中的 nsenter 模块,其中逻辑有些绕,也发现了一段很长很有意思的注释,分享一下。
What 链接到标题 什么是 nsenter,nsenter 是 runc 中的一个 package,它包含了一个特殊的构造函数,用来在 Go runtime 启动之前做一些事情,比如 setns()。nsenter 会引入 C 并使用 cgo 实现相关逻辑。在cgo中,如果在 C 的 import 后紧跟注释,则在编译程序包的 C 语言实现部分时,该注释将用作 header。因此,每次 import nsenter 时,nsexec()都会调用 C 函数。
在 runc 中只有 init.go import 了 nsenter。
Why 链接到标题 容器技术最关键的就是 namespace 和 cgroup,其中 namespace 是通过 setns() 函数来实现的,但是 setns() 有一个问题: A multithreaded process may not change user namespace with setns(). 。而 go runtime 是多线程的,所以需要在 go runtime 启动前执行 setns() 设置好 namespace,然后再走 go 相关实现流程。