go MPG 模型导致的系统调用setns的坑

在Go中,通过syscall.Syscall执行setns系统调用进入Docker容器的网络命名空间时,遇到一个奇怪的问题:当在主协程中且无其他子协程时,能正确读取容器内的/proc/net/tcp;若有子协程,将读取主机的。解决方案是使用runtime.LockOSThread()固定主协程在初始的M上,确保setns调用正确。
摘要由CSDN通过智能技术生成

go MPG 模型导致的系统调用setns的坑

背景

最近在做的一个项目是关于获取docker容器内的端口监听(包括导出的端口和未导出的端口)以及端口对应的sokcet inode号,因为有了inode号可以在物理机上对应到是哪个服务进程。采用的方案是先获取到docker容器的ns命名空间,然后使用系统调用 syscall .Syscall(SYS_SETNS, uintptr(target), uintptr(Type), 0)函数进入容器的网络命名空间(net),在此命名空间下读取/proc/net/tcp文件获取监听的端口,以及端口sokcet对应的inode号。

某些情况下syscall.Syscall失败

在实现上述方案的过程中出现了一个比较怪异的现象,如果syscall.Syscall系统调用是在main()函数所在的主协程,且没有启动其他协程,则接下来读取/proc/net/tcp文件是对应容器内的/proc/net/tcp文件;如果 如果syscall.Syscall系统调用是在main()函数所在的主协程,但是启动了其他协程,则接下来读取的/proc/net/tcp文件是物理机上的/proc/net/tcp文件。

经历过程

一开始确认方案之后,开发了一个demo,确认通过setns的系统系统是能获取到容器内的/proc/net/tcp文件的,后面demo集成到线上环境时,因为是在单独的一个go协程中实现的这个功能,发现竟然获取不到容器内的/proc/net/tcp文件了,觉得有点怪异。刚好自己电脑上安装的是go1.14,而线上环境原有的项目是go1.8编译的,怀

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值