原标题:云原生基座OpenKube开放容器实践(一):如何理解Linux network namespace ?
2020—12.21
作者 刘海峰
IT行业资深码农,从事java/go语言开发十余年,对springcloud/k8s/linux网络相关技术有深入理解,现为滴普科技容器产品首席架构师。
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/Va返回搜狐,查看更多
责任编辑: