如何从一个单一的流程实例创建多个网络空间 [英] How to create multiple network namespace from a single process instance

查看:247
本文介绍了如何从一个单一的流程实例创建多个网络空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用下面的C函数从单流程实例创建的多个网络命名空间

I am using following C function to create multiple network namespaces from a single process instance:

void create_namespace(const char *ns_name)
{
    char ns_path[100];

    snprintf(ns_path, 100, "%s/%s", "/var/run/netns", ns_name);
    close(open(ns_path, O_RDONLY|O_CREAT|O_EXCL, 0));
    unshare(CLONE_NEWNET);
    mount("/proc/self/ns/net", ns_path, "none", MS_BIND , NULL);
}

在我的进程创建所有namspaces和我添加的自来水的接口,任何一个网络空间(​​与 IP链路设置TAP1 netns NS1 命令),那么,我居然看到在所有的命名空间的这个接口(presumably,这其实是一个单一命名空间,根据不同的名字去)。

After my process creates all the namspaces and I add a tap interface to any of the one network namespace (with ip link set tap1 netns ns1 command), then I actually see this interface in all of the namespaces (presumably, this is actually a single namespace that goes under different names).

但是,如果我通过使用多个进程创建多个命名空间,那么一切工作就好了。

But, if I create multiple namespaces by using multiple processes, then everything is working just fine.

可能是什么错在这里?我是否需要任何额外的标志传递给取消共享()来得到这从一个单一的流程实例的工作?是否有一个限制,即单个进程实例不能创建多个网络命名空间?或者是有与)的一个问题贴装(通话,因为的/ proc /自/ NS /净是实际安装多次?

What could be wrong here? Do I have to pass any additional flags to the unshare() to get this working from a single process instance? Is there a limitation that a single process instance can't create multiple network namespaces? Or is there a problem with mount() call, because /proc/self/ns/net is actually mounted multiple times?

更新:
看来,取消共享()函数创建多个网络名称空间正确,但是所有的挂载点在 / var / run中/ netns / 实际引用到已安装在direcotry的第一个网络空间。

Update: It seems that unshare() function creates multiple network namespaces correctly, but all the mount points in /var/run/netns/ actually reference to the first network namespace that was mounted in that direcotry.

UPDATE2:
看来,最好的办法是到餐桌()另一个进程,并从那里执行create_namespace()函数。无论如何,我会很高兴地听到一个更好的解决方案,不涉及fork()的调用或至少得到一个确认,将证明它是不可能从一个单一的过程中创建和管理多个网络名称空间。

Update2: It seems that the best approach is to fork() another process and execute create_namespace() function from there. Anyway, I would be glad to hear a better solution that does not involve fork() call or at least get a confirmation that would prove that it is impossible to create and manage multiple network namespaces from a single process.

UPDATE3:
我能够通过以下code。与取消共享()来创建多个命名空间:

Update3: I am able to create multiple namespaces with unshare() by using the following code:

int  main() {
    create_namespace("a");
    system("ip tuntap add mode tap tapa");
    system("ifconfig -a");//shows lo and tapA interface
    create_namespace("b");
    system("ip tuntap add mode tap tapb");
    system("ifconfig -a");//show lo and tapB interface, but does not show tapA. So this is second namespace created.
}

但经过进程终止和我执行 IP netns Exec中的ifconfig -a IP netns EXEC b使用ifconfig -a 似乎这两个命令都在命名空间中突然执行的的。所以,实际的问题是存储引用的命名空间(或调用安装()以正确的方式,但我不知道,这是可能的)。

But after the process terminates and I execute ip netns exec a ifconfig -a and ip netns exec b ifconfig -a it seems that both commands were suddenly executed in namespace a. So the actual problem is storing the references to the namespaces (or calling mount() the right way. But I am not sure, if this is possible).

推荐答案

您只需要绑定坐骑的/ proc / * / NS / * 如果您需要访问这些从另一个进程名称空间,或需要得到处理,以便能够来回切换两者。它不需要使用多个命名空间,从一个单一的过程。

You only have to bind mount /proc/*/ns/* if you need to access these namespaces from another process, or need to get handle to be able to switch back and forth between the two. It is not needed to use multiple namespaces from a single process.


  • 取消共享的的创建新的命名空间。

  • 克隆和叉子在默认情况下不创建任何新的命名空间。

  • 有分配给过程的各种之一的当前命名空间。它可以通过取消共享或setns被改变。设置命名空间(默认)是由子进程继承。

  • unshare does create new namespace.
  • clone and fork by default do not create any new namespaces.
  • there is one "current" namespace of each kind assigned to a process. It can be changed by unshare or setns. Set of namespaces (by default) is inherited by child processes.

每当你打开(的/ proc / N / NS /净),它为这个文件创建的inode,
和所有后续执行open()将返回绑定到该文件
相同的命名空间。详情失去了内核的dentry缓存的深处。

Whenever you do open(/proc/N/ns/net), it creates inode for this file, and all subsequent open()s will return file that is bound to the same namespace. Details are lost in the depths of kernel dentry cache.

另外,每个进程只有一个的/ proc /自/ NS /净文件条目,并
绑定安装不创建这个proc文件的新实例。
打开这些安装文件的完全相同的,因为打开
的/ proc /自/ NS /净直接文件(这将让指向
的命名空间指向,当你第一次打开它)。

Also, each process has only one /proc/self/ns/net file entry, and bind mount does not create new instances of this proc file. Opening those mounted files are exactly the same as opening /proc/self/ns/net file directly (which will keep pointing to the namespace it pointed to when you first opened it).

看来,的/ proc / * / NS 是半生不熟的是这样的。

It seems that "/proc/*/ns" is half-baked like this.

所以,如果你只需要2的命名空间,您可以:

So, if you only need 2 namespaces, you can:


  • 开启的/ proc / 1 / NS /净

  • 取消共享

  • 开启的/ proc /自/ NS /净

  • open /proc/1/ns/net
  • unshare
  • open /proc/self/ns/net

和在两者之间切换。

有关超过2,您可能需要的clone()。似乎有没有办法建立一个以上的的/ proc /每个进程N / NS /净文件。

For more that 2 you might have to clone(). There seems to be no way to create more than one /proc/N/ns/net file per process.

不过,如果你并不需要在运行时的名称空间之间进行切换,或与其他进程共享,您可以使用许多命名空间是这样的:

However, if you do not need to switch between namespaces at runtime, or to share them with other processes, you can use many namespaces like this:


  • 开启插座和运行流程主命名空间。

  • 取消共享

  • 开启插槽和2号命名空间(网络链路,TCP等)运行的进程

  • 取消共享

  • ...

  • 取消共享

  • 开启插座和运行流程,第N个命名空间(网络链路,TCP等)

打开插座不断提及自己的网络空间,所以他们不会被收集到插座关闭。

Open sockets keep reference to their network namespace, so they will not be collected until sockets are closed.

您还可以使用网络链路名称空间之间移动界面,通过在源空间发送netlink的命令,或者通过PID或命名空间FD(后来你没有)指定DST的命名空间。

You can also use netlink to move interfaces between namespaces, by sending netlink command on source namespace, and specifying dst namespace either by PID or namespace FD (the later you don't have).

您需要访问依赖于该命名空间的/ proc 项之前,切换过程中的命名空间。一旦过程的文件是开放的,它使引用的命名空间。

You need to switch process namespace before accessing /proc entries that depend on that namespace. Once "proc" file is open, it keeps reference to the namespace.

这篇关于如何从一个单一的流程实例创建多个网络空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆