我正在写小型普罗米修斯出口商在 Go 中发布 docker 容器的网络指标。
有一个 goroutine 按以下方式收集值:
1. Get all docker containers using docker SDK
2. Locks the goroutine in its current thread
3. Remembers current namespace
4. For each container
4.1. Switches network namespace into the contanier's one (setns() syscall)
4.2. Reads the file /proc/net/netstat
4.3. Parses the contend and makes it available in a shared map
5. Restores the namespace to the remembered one
服务器请求处理程序查找共享地图并在 Prometheus 指标中格式化数据。
问题是它在约 20% 的情况下按预期工作,并且似乎命名空间切换没有按预期工作,就好像命名空间切换是异步完成的,或者文件 /proc/net/netstat 的内容缓存在某处。其余时间 /proc/net/netstat 的内容来自“根”(或起始)命名空间或坚持到 docker 容器的命名空间之一。
有什么建议我可以进一步研究以使其可靠地工作吗?我对这种行为感到困惑。
编辑:更好的表述
答案1
好吧,看来我忽略了一个重要的细节procfs 手册页:
/proc/net
[...]
With the advent of network namespaces, various information
relating to the network stack is virtualized (see
network_namespaces(7)). Thus, since Linux 2.6.25, /proc/net
is a symbolic link to the directory /proc/self/net, which con‐
tains the same files and directories as listed below. How‐
ever, these files and directories now expose information for
the network namespace of which the process is a member.
因此,看起来网络统计信息是针对每个进程的,并且更改属于某个进程的单个线程的 NW 命名空间不会反映在 /proc/net/netstat 文件中