滴普技术荟 - 云原生基座 OpenKube 开放容器实践(一):如何理解 Linux network namespace ?
network namespace 是 linux 内核提供的用于实现网络虚拟化的重要功能,它能创建多个隔离的网络空间,一个独立的网络空间内的防火墙、网卡、路由表、邻居表、协议栈都是独立的。不管是虚拟机还是容器,当运行在独立的命名空间时,就像是一台单独的主机一样。
下面会通过一些例子来说明网络命名空间,以加深理解,会用到 iproute2 工具包的 ip 命令,请各位先自行安装,并且使用 root 权限操作。
在 centos 下执行如下命令:
验证安装完成:
创建网络命名空间
ip 命令中用于操作网络命名空间的命令是 ip netns,用 help 来查看一下子命令有哪些:
常用的也就是增删查命令,先来创建一个网络空间空间 ns1:
查看当前所有的网络命名空间:
在这有些人可能会很困惑,我主机上明明运行中好几个 docker 容器,按理说每个容器都运行在独立的网络命名空间,怎么这里没有列出来?不要着急,下面会提到。
先来感觉一下什么叫独立的网卡,独立的路由表,要查看 ns1 命名空间的网卡,iproute2 工具提供了命令 ip netns exec ns1,跟在这个命令后面的命令都会在这个网络命名空间中执行。
先查看一下主机的网卡和路由表:
再看看 ns1 中的网卡和路由表:
这样执行命令有点麻烦,也可以简单一点:
用 exit 可以回到主机的默认空间
ip netns add 的原理
当我们在主机上执行 ip netns add ns1 后 ,实际是在/var/run/netns 下创建了一个 ns1 的文件:
下面的命令可以模拟 ip netns add ns2 && ip netns exec ns2 bash
从上面的示例可以看出,创建命名的 network namespace 其实就是创建一个文件,然后通过绑定挂载的方式将新创建的 network namespace 文件和进程的/proc/self/ns/net 文件绑定。
查看容器的网络命名空间
接下来该回答上面的遗留问题,为什么当我在主机上 ip netns list 的时候看不到 docker 的网络命名空间,因为 ip netns list 的时候只会显示在/var/run/netns 下的文件,而 docker 的文件默认是创建在/var/run/docker/netns 下的,所以我们可以通过 ls /var/run/docker/netns 来显示当前的所有容器的网络命名空间,并且通过 nsenter --net=/var/run/docker/xxx 来进入容器的网络命名空间。
如果想查看具体某个 docker 容器对应的文件,可以用:
注意如果是 k8s 拉起来的 docker,要拿非 hostNetwork=true 的 pause 容器来看,如果 hostNetwork=true,那么下面的值为/var/run/docker/netns/default,这是主机的默认网络命名空间,如果不是 pause 容器,那么下面的值为空,因为只有 pause 容器会创建一个新的网络命名空间,其它 container 都只是加入这个网络命名空间。(这个 SandboxKey 大家先记着,后面写 cni 组件时还会提到这个值)
还有另一个办法:
这个小技巧在我们调试 pod 的网络时非常有用,大多数时候 pod 里面自带的工具非常少,没有 curl 没有 telnet,这时候用这个技巧先进入空器的网络空间,再执行命令就行了,因为只是切了网络命名空间,其它还在主机上,所以用的工具也全是主机的工具。
更多信息欢迎关注滴普科技官网 http://datasink-sensors.deepexi.top/t/ta
版权声明: 本文为 InfoQ 作者【滴普科技2048实验室】的原创文章。
原文链接:【http://xie.infoq.cn/article/aa91f437fce154d05fd765603】。文章转载请联系作者。
评论