我一直在用 C 从头开始编写自己的 Linux 容器。我从几个地方借用了代码并提供了一个基本版本命名空间&cgroups。
基本上,我克隆一个新的流程与所有克隆_新*为创建新的命名空间的标志克隆的过程。
我还通过插入来设置 UID 映射0 0 1000进入uid_map和gid_map文件。我想确保根容器内部被映射到根外部。
对于文件系统,我使用的基本映像拉紧创建于反引导程序。
现在,我正在尝试从容器内部设置网络连接。我用了这用于设置容器内接口的脚本。该脚本创建了自己的新网络命名空间。我对其进行了稍微编辑,以通过脚本将创建的进程的网络命名空间安装到新创建的网络命名空间上。
mount --bind /proc/$PID/ns/net /var/run/netns/demo
我可以进入新的网络命名空间,如下所示:
ip netns exec ${NS} /bin/bash --rcfile <(echo "PS1=\"${NS}> \"")
并成功 ping 通外部。
但是,当我默认进入克隆进程时,从 bash shell 无法 PING。我收到错误:
ping: socket: Operation not permitted
我尝试过设置功能:cap_net_raw和cap_net_admin
我想要一些指导。
答案1
我更愿意根据更完整的规范进行工作。然而,通过仔细阅读脚本和您的描述,我得出的结论是您首先输入网络名称空间(使用脚本),然后输入用户名称空间。
netns 归初始用户所有,而不是您的子用户。为此ping
,您需要在拥有 netns 的用户中使用 cap_net_raw。我认为。
这里有一个类似的答案,它提供了参考文档的链接:Linux 与用户命名空间的功能
(我认为ping
如果您有权访问 ICMP 套接字,也可以在没有特权的情况下工作。但至少在我的 Fedora 29 上,这似乎没有被使用。无特权cp "$(which ping)" && ping localhost
显示相同socket: Operation not permitted
。不知道为什么它没有被采用)。