为什么未检测到我的命名空间?

为什么未检测到我的命名空间?

我尝试从家里出发,然后sudo su -

ip netns exec 5bd337503b01 ip addr show
Cannot open network namespace "5bd337503b01": No such file or directory

密码显示

/var/run/docker/netns

为什么?

答案1

注意:/var/run是一个符号链接,/run因此下面写的内容并不重要。我将使用/var/runDocker/runip netns.

ip netns将网络命名空间安装在其专用/run/netns目录中。 Docker 使用不同的专用目录/var/run/docker/netns,因此ip netns不了解任何与 Docker 相关的信息,反之亦然。这两个工具并不旨在操作用户提供的伪文件,也不使这些伪文件可用。用户提供名称或哈希值,并且不应直接与这些挂载点混合:这是这两个工具中的实现细节,不应该被视为公共 API。尽管如此...

可以做的是“复制”(使用绑定安装)已安装的网络名称空间,使其也出现在其中,从而/run/netns/FOO使其可用ip netns exec FOO ...ip -n FOO ...

一罐:

  • 具有子命令的最新ip netns版本attach

    使用正在运行的容器的 PID 作为参考,在其他地方安装 PID 的命名空间(可通过 获得/proc/PID/ns/net)。下面简单地重用了与网络命名空间挂载点名称不同的容器名称。这可以使用docker inspect正确的 JSON 过滤器以编程方式完成。

    ip netns attach containername $(docker inspect --format '{{.State.Pid}}' containername)
    

    要使用与 Docker 命名的网络命名空间相同的名称而不是容器的名称,可以使用(至少在今天).NetworkSettings.SandboxKey其值为/var/run/docker/XXXXXXXXXXXX.

    ip netns attach "$(basename "$(docker inspect --format '{{.NetworkSettings.SandboxKey}}' containername)")" $(docker inspect --format '{{.State.Pid}}' containername)
    
  • 旧版本ip netns不支持attach

    至少创建一次网络命名空间以完成正确的配置(例如:/run/netns创建为具有共享传播的挂载点):

    [ ! -e /run/netns ] && { ip netns add dummy; ip netns delete dummy; } # for correct initial setup
    

    创建一个空文件并从其上检索到的 PID 引用挂载命名空间docker inspect

    touch /run/netns/containername
    mount --bind /proc/$(docker inspect --format '{{.State.Pid}}' containername)/ns/net /run/netns/containername
    

    或者使用重用 Docker 网络命名空间名称而不是容器名称的变体:

    touch /run/netns/$(basename "$(docker inspect --format '{{.NetworkSettings.SandboxKey}}' containername)")
    mount --bind /proc/$(docker inspect --format '{{.State.Pid}}' containername)/ns/net /run/netns/$(basename "$(docker inspect --format '{{.NetworkSettings.SandboxKey}}' containername)")
    
  • 或者直接直接使用,不使用进程 PID,也不使用docker inspect

    例如,要使所有当前可见的 Docker 已安装的网络命名空间可供以下用户使用ip netns

    [ ! -e /run/netns ] && { ip netns add dummy; ip netns delete dummy; } # for correct initial setup
    
    for i in /var/run/docker/netns/*; do
        netnsname="$(basename "$i")"
        touch /run/netns/"$netnsname"
        mount --bind "$i" /run/netns/"$netnsname"
    done
    

在删除来自 Docker 和(using ) 的引用之前,通过提供的此类命名空间ip netns不会消失。使用应该进行适当的清理,并且不会影响此网络命名空间,因为 Docker 仍在使用它:它只是删除对其的挂载点引用,直到删除所有引用为止,不会发生任何事情。ip netnsip netns delete somenetnsnameip netns delete somenetnsname

相关内容