写点什么

滴普技术荟 - 云原生基座 OpenKube 开放容器实践(一):如何理解 Linux network namespace ?

发布于: 2021 年 01 月 05 日
滴普技术荟-云原生基座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

 

发布于: 2021 年 01 月 05 日阅读数: 30
用户头像

还未添加个人签名 2020.12.22 加入

滴普科技2048实验室致力于探索科技未知,以点滴努力,普惠科技为驱动力,立足于数据智能、创新性技术和应用技术的研究院。

评论

发布
暂无评论
滴普技术荟-云原生基座OpenKube开放容器实践(一):如何理解Linux network namespace ?