• Linux ip netns 命令


    ip netns 命令用来管理 network namespace。它可以创建命名的 network namespace,然后通过名字来引用 network namespace,所以使用起来很方便。

    ip netns 命令格式如下:
    ip [ OPTIONS ] netns { COMMAND | help }

    可以通过 help 命令查看 ip netns 所有操作的帮助信息:

    network namespace
    network namespace 在逻辑上是网络堆栈的一个副本,它有自己的路由、防火墙规则和网络设备。
    默认情况下,子进程继承其父进程的 network namespace。也就是说,如果不显式创建新的 network namespace,所有进程都从 init 进程继承相同的默认 network namespace。
    根据约定,命名的 network namespace 是可以打开的 /var/run/netns/ 目录下的一个对象。比如有一个名称为 net1 的 network namespace 对象,则可以由打开 /var/run/netns/net1 对象产生的文件描述符引用 network namespace net1。通过引用该文件描述符,可以修改进程的 network namespace。

    显示所有命名的 network namespace
    ip netns list 命令显示所有命名的 network namesapce,其实就是显示 /var/run/netns 目录下的所有 network namespace 对象:

    创建命名的 network namespace
    ip netns add NAME 命令创建一个命名的 network namespace:

    删除命名的 network namespace
    ip [-all] netns del [ NAME ] 命令删除指定名称的 network namespace。如果指定了 -all 选项,则尝试删除所有的 network namespace。

    注意,如果我们把网卡设置到了某个 network namespace 中,并在该 network namespace 中启动了进程:

    $ sudo ip netns add net0
    $ sudo ip link set dev eth0 netns net0
    $ sudo ip netns exec net0 bash
    在另一个 bash 进程中删除 network namespace net0:

    $ sudo ip netns del net0
    此时虽然可以删除 netowrk namespace,但是在进程退出之前,网卡一直会保持在你已经删除了的那个 network namespace 中。

    查看进程的 network namespace
    ip netns identify [PID] 命令用来查看进程的 network namespace。如果不指定 PID 就显示当前进程的 network namespace:

    下面的命令指定了 PID:

    技术分享图片

    查看 network namespace 中进程的 PID
    ip netns pids NAME 命令用来查看指定的 network namespace 中的进程的 PID。这个命令其实就是去检查 /proc 下的所有进程,看进程的 network namespace 是不是指定的 network namespace:

    技术分享图片

    在指定的 network namespace 中执行命令
    ip [-all] netns exec [ NAME ] cmd 命令用来在指定的 network namespace 中执行命令。比如我们要看一下某个 network namespace 中有哪些网卡:

    技术分享图片

    ip netns exec 后面跟着 namespace 的名字,比如这里的 neta,然后是要执行的命令,只要是合法的 shell 命令都能运行,比如上面的 ip addr 或者 bash。
    更棒的是,执行的可以是任何命令,不只是和网络相关的(当然,和网络无关命令执行的结果和在外部执行没有区别)。比如下面例子中,执行 bash 命令之后,后面所有的命令都是在这个 network namespace 中执行的,好处是不用每次执行命令都要把 ip netns exec NAME 补全,缺点是你无法清楚知道自己当前所在的 shell,容易混淆:

    技术分享图片

    通过 -all 参数我们可以同时在所有的 network namespace 执行命令:

    技术分享图片

    输出中的 netns: 指示在某个 network namespace 中执行的结果。

    监控对 network namespace 的操作
    ip netns monitor 命令用来监控对 network namespace 的操作。比如我们删除一个 network namespace 时就会收到相应的通知:

    技术分享图片

    理解 ip netns add 命令
    我们通过下面的演示来理解 ip netns add 命令的本质。
    查看默认 network namespace 的 ID:

    $ readlink /proc/$$/ns/net
    在 /var/run/netns 目录下创建一个用于绑定 network namespace 的文件,名为 mynet:

    $ sudo mkdir -p /var/run/netns
    $ sudo touch /var/run/netns/mynet
    技术分享图片

    通过 unshare 命令创建新的 network namespace,并在新的 namespace 中启动新的 bash:

    $ sudo unshare --net bash
    查看新的 network namespace ID:

    readlink /proc/$$/ns/net

    技术分享图片

    通过绑定挂载把当前 bash 进程的 network namespace 文件挂载到前面创建的 mynet 文件上:

    mount --bind /proc/$$/ns/net /var/run/netns/mynet

    ls -I /var/run/netns/mynet

    通过 ls -I 命令可以看到文件 mynet 的 inode 号和 network namespace 的 ID 相同,说明绑定成功:

    技术分享图片

    退出新创建的 bash,再检查一次 mynet 文件的 inode:

    exit

    $ ls -I /var/run/netns/mynet
    技术分享图片

    可以看出 mynet 文件的 inode 没有发生变化,说明我们使用了绑定挂载后,虽然新的 network namespace 中已经没有进程了,但这个新的 network namespace 还继续存在。

    上面的一系列操作其实等同于执行了命令:sudo ip netns add mynet
    下面的 nsenter 命令则等同于执行了命令: sudo ip netns exec mynet bash

    $ sudo nsenter --net=/var/run/netns/mynet bash

    readlink /proc/$$/ns/net

    技术分享图片

    通过 nsenter 命令新建了一个 bash 进程,并把它加入 mynet 所关联的 network namespace(net:[4026532616])。

    从上面的示例可以看出,创建命名的 network namespace 其实就是创建一个文件,然后通过绑定挂载的方式将新创建的 network namespace 文件(/proc/$$/ns/net)和该文件绑定,就算该 network namespace 里的所有进程都退出了,内核还是会保留该 network namespace,以后我们还可以通过这个绑定的文件来加入该 network namespace。

  • 相关阅读:
    UIKit框架-高级控件:2.UIScrollView的单图分页设置
    欢迎使用CSDN-markdown编辑器
    UIKit框架-高级控件:1.UIScrollView的基本认识
    UIKit基础:18-MVC模式, 代理消息传递机制, 计时器机制
    UIKit基础:17-基础控件的总结
    UIKit基础:16-小游戏之舒尔特表
    UIKit基础:15-与电脑玩剪刀石头布
    iOS之 Category 属性 的理解
    学习方法,特别对于新手
    iOS 之GCD串行和并发队列的理解
  • 原文地址:https://www.cnblogs.com/ztxd/p/12266341.html
Copyright © 2020-2023  润新知