命名空间是什么
命名空间提供了一套独立的系统资源,对这些系统资源的修改会影响同一个命名空间中的其他进程,但是不会影响到其他的命名空间中的进程。所以它的一个用途就是用来实现容器。
Linux下有以下几种Namespace
Flag:在API中指定命名空间的标志位
Page: manpage
Isolates:Namespace所分离的资源内容
Namespace | Flag | Page | Isolates |
cgroup | CLONE_NEWCGROUP | cgroup_namespaces | cgroup root directory |
IPC | CLONE_NEWIPC | ipc_namespaces | SystemV IPC,POSIX message queue |
Network | CLONE_NEWNET | network_namespaces | Network devices, stacks, port, etc |
Mount | CLONE_NEWNS | mount_namespaces | Mount points |
PID | CLONE_NEWPID | pid_namespaces | Process PID |
Time | CLONE_NEWTIME | time_namespaces | Boot & monotonic clocks |
User | CLONE_NEWUSER | user_namespaces | User & group IDS |
UTS | CLONE_UTS | uts_namespaces | Hostname & NIS domain name |
/proc/[pid]/ns/ 目录
1)bind 挂载ns目录下的文件可以使命名空间一直存在,即使它对应的所有进程都已经停止。
2)打开其中的文件也可以使命名空间存在,并且获得的文件描述符可以传给setns
3)/proc/sys/user目录展示了对创建各种命名空间数量的限制,如下:
限制数量是对用户来说的,也就是同一个命名空间下的所有用户能创建最多个命名空间数
相关的系统调用
1)clone
clone系统调用用来创建一个新的进程,相较于fork,clone提供更多对于进程的控制。比如父子进程是否使用相同的虚拟地址空间,文件描述符表等。
#define _GNU_SOURCE #include <sched.h> int clone(int (*fn)(void *), void *stack, int flags, void *arg, ... /* pid_t *parent_tid, void *tls, pid_t *child_tid */ ); |
fn:进程执行函数,函数return时进程结束
stack:指定给子进程的栈空间,父子进程可以公用内存空间,但是栈空间不可以
flags(与namespace相关的):
(子进程在新的命名空间)
CLONE_NEWCGROUP
CLONE_NEWIPC
CLONE_NEWNET
CLONE_NEWNS
CLONE_NEWPID
CLONE_NEWUSER
CLONE_NEWUTS
如果添加了任意一个CLONE_NEW*标志位,则创建一个新的命名空间,并且创建的子进程就在这个新的Namespace中
2)setns
setns系统调用把调用的进程移动到现有的命名空间中去,如果需要看当前进程所在的命名空间可以在 /proc/[pid]/ns 下看到
数字表示命名空间id
3)unshare
unshare系统调用移动调用的进程到一个新的命名空间中去,如果加上CLONE_NEW*标志位的话会创建一个新的明明空间并把进程放到此命名空间
4)ioctl