我已经在我的 Linux 系统(内核版本 3.10)上设置了几个网络命名空间,现在我想配置每个网络命名空间以拥有自己的 DNS 设置。
我resolv.conf
在每个/etc/netns/[namespace]
目录中创建了文件,现在我想让我的系统按以下方式工作:
在 bash 命令行中,每当我nsenter --net=/run/netns/[namespace name]
使用/etc/netns/[namespace name]/resolv.conf
.
如果我像这样运行我的命令:
"ip netns exec [namespace name] [command]"
然后应用命名空间的 DNS 设置。
但是,当运行没有“ip netns exec”的命令时,DNS 设置取自/etc/resolv.conf
,即使运行“netns get cur”表示上下文设置为所需的网络命名空间。
我尝试mount --bind /etc/netns/[namespace name]/resolv.conf /etc/resolv.conf
在适当的网络命名空间的上下文中执行此操作,但这会将挂载应用到整个系统中,而不是仅在该网络命名空间的上下文中。
我怀疑使用挂载命名空间可能会有所帮助,所以我尝试阅读挂载命名空间的手册页,但是在我致力于它的短时间内无法从中做出任何事情。
有没有一种简单而优雅的方式来实现这个目标?
任何有关解决方案的帮助/指导将不胜感激!
解决方案
您可以使用
ip netns exec
withbash
而不是 usingnsenter
,即:这将允许您进入交互式 shell 会话,其中特定于命名空间的网络配置文件会自动绑定安装到其默认(全局)位置(不影响其他会话)。
解释
以下内容来自
ip netns
手册页:特别注意网络名称空间感知应用程序和网络名称空间不感知应用程序之间的区别。
另一方面,手册页似乎没有提到这种区别(特别是我搜索了字符串“aware”、“resolv”、“.conf”和“/etc”,但没有找到任何结果)
nsenter
。这似乎表明该nsenter
实用程序不会对不知道命名空间的应用程序执行相同类型的自动处理。附加评论
除了Network Namespaces之外,您可能还想查看User Namespaces和Mount Namespaces。如果您希望在 DNS 之外进一步隔离,您可能还需要考虑容器化,例如LXC Containers、Docker,甚至是完整的 VM。
看看
ip netns exec test ...
你的情况在做什么,使用strace
.摘抄:
所以要重现(部分,例如
/sys
这里没有处理)ip netns exec test ...
正在做什么:~# nsenter --net=/var/run/netns/test unshare --mount sh -c 'mount --bind /etc/netns/test/resolv.conf /etc/resolv.conf; exec bash'
所以这是对的。
nsenter
单独是不够的。unshare
必须使用,更改为新创建的挂载命名空间(基于前一个的副本)并更改它,而不仅仅是逐字使用现有的命名空间,因为还没有适合的现有命名空间。这就是在做与 tell 同名的系统调用的原因strace
。前两个答案提供了很好的信息和答案,但我会尝试从稍微不同的角度来回答。
网络命名空间为您提供放置网络接口、网络路由路由和规则以及网络过滤器条目的位置。
挂载命名空间为您提供了放置文件的地方。这些文件可能与网络相关,并且可能旨在用于特定的网络命名空间,但最终它们只是文件。
创建新的网络命名空间(例如使用“
ip netns add newnetns
”)不会自动为您提供新的挂载命名空间。如果您使用“
ip netns exec newnetns somecomand
”命令,那么您将使用新的网络命名空间(您之前创建的 newnetns)创建一个新进程(somecommand),并且您还将获得一个为此进程创建的新挂载命名空间。您还将获得某些文件绑定挂载到新的挂载命名空间(例如,/etc/netns/newnetns/resolv.conf
到/etc/resolv.conf
)。现在使用“ip netns exec
”时,这些文件通常与网络相关,例如 resolv.conf。但是,即使这些文件与网络相关并且您可能创建它们以与新的网络命名空间一起使用,它们也不属于您的新网络命名空间。当您的进程(某个命令)终止时,为其创建的挂载命名空间也将消失(除非您通过其他方式将另一个进程附加到同一个挂载命名空间),但网络命名空间将保留。当您使用该
nsenter
命令时,它会将您的命令放入您选择的网络命名空间中,但nsenter
不会像“ip netns exec
”那样创建新的挂载命名空间。值得注意的是,“
ip netns add newnetns
”创建了一个基本上为空的新网络命名空间。您必须将接口或路由添加到该新的网络命名空间。“ip netns exec
” 将一个进程放入该网络命名空间,创建一个新的挂载命名空间,它基本上是主挂载命名空间的副本(很可能显示您的主文件系统),只添加了几个绑定挂载。另外值得注意的是,
ip-netns
手册页提到了它将代表不知道网络名称空间的应用程序使用的文件约定。这可能会给人一种印象,即有一大堆使用文件约定的网络感知应用程序/etc/netns/nsname/...
据我所知,情况并非如此。我想不出任何其他使用文件的应用程序/etc/netns/nsname/...
,但也许有。