Network Namespace
Namespace的作用
隔离内核资源,分割全局系统资源,并装到抽象的独立空间里。Namespace包括:
文件系统挂载点 (Mount)
主机名 (UTS)
POSIX进程间通信消息队列 (IPC)
进程PID数字空间 (PID)
IP地址 (network)
userID数字空间 (user)
Linux的namespace给里面的进程造成两个错觉:
- 它是系统里唯一的进程
- 它独享系统的所有资源
Network namespace使得每个容器都有自己的虚拟网络设备(IP地址、路由表、端口范围、/proc/net目录等),并且容器里的进程可以放心地绑定在端口上而不必担心冲突,这就使得在一个主机上同时运行多个监听80端口的Web服务器变为可能。
Network namespace管理命令
1 | 创建新的netns |
注:删除操作并没有删除netns1,只是移除了netns1对应的挂载点。只要里面还有进程运行着,该network namespace便会一直存在。
Network namespace配置命令
1 | 进入netns1,并把设备状态设置成UP |
不同network namespace之间的路由表和防火墙规则等也是隔离的。
1 | 进入netns1,并查询其路由表 |
用户可以随意将虚拟网络设备分配到自定义的network namespace里,而连接真实硬件的物理设备则只能放在系统的根network namespace。
Network namespace里的root进程能够本network namespace的虚拟网络设备分配到其他network namespace。但通常为了保证安全性,需要结合PID namespace和Mount namespace的隔离特征做到network namespace之间的完全不可达。
Network namespace API的使用
1 | # 只要在clone()设置标志位CLONE_NEW,系统就会创建一个新的对应类型的namespace及一个新的进程,并将这个进程放入到这个新创建的namespace中 |
每个Linux进程都拥有一个属于自己的/proc/PID/ns,这个目录下的每个文件都代表一个类型的namespace。
如图所示,该目录下每一个文件都是一个特殊的符号链接文件。其主要用途有两点:
- 确定某两个进程是否属于同一个namespace。
- 当打开这些文件时,只要文件描述符保持open状态,对应的namespace就会一直存在,哪怕这个namespace里的所有进程都终止运行了。
注:一旦系统管理员禁用namespace中的网络设备,即使里面的进程拿到了一些特权,也无法与外界通信。
参考
《Kubernetes网络权威指南》