docker 网络之host模式底层实现

众所周知,docker有4种网络模式:桥接、host、容器、none,默认使用桥接。今天主要介绍一下host模式。

host模式,本质是容器与物理主机在网络空间是同一个namesapce。docker在创建容器后会在默认路径/var/run/docker/netns/ 生成一个文件,创建一个容器并且指定网络是为--net=host,具体如下可知:

我们通过上图可知,蓝色中实际为文件inode id,三者是完全相同的。其中进程1的net namespace代表就是物理主机net namespace,由此可知容器和物理主机是处在相同net namespace中

我们都知道,在linux下面创建一个文件,都会对应一个inode节点,每个文件对应的inode都是不一样的,那么docker是通过什么技术实现的呢是不同文件映射到同一个inode上呢?这里先公布答案:通过系统调用函数mount,具体流程图:

  

具体代码:docker/libnetwork/osl/namespace_linux.go

func reexecCreateNamespace() {
	if len(os.Args) < 2 {
		logrus.Fatal("no namespace path provided")
	}
	if err := mountNetworkNamespace("/proc/self/ns/net", os.Args[1]); err != nil {
		logrus.Fatal(err)
	}
}

func mountNetworkNamespace(basePath string, lnPath string) error {
	return syscall.Mount(basePath, lnPath, "bind", syscall.MS_BIND, "")
}

其中basePath为当前进程下面ns/net,lnPath为/var/run/docker/ns/default(这个default文件要先创建出来),然后在执行系统调用mount,进行bind操作。通过上面一系列操作可知,最终是通过mount操作,将default文件mount到ns/net所指向的inode节点,也就是说将容器net namespace指向物理主机net namespace(即在相同namespace)。

总结:从这部分逻辑可知,我们最后还是调用系统调用,那么我们是不是也可以通过C语言方式实现这个功能呢?答案是肯定。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值