Linux namespace命名空间
namespace[1]提供一种隔离机制,让不同的namespace下的进程看到的全局资源不同,每一个namespace有一个自己独立的全局资源实例。
namespace的一个用途是实现容器。
![](http://upload-images.jianshu.io/upload_images/15604519-f5138275818db919.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)
Linux系统下的namespace类型
名称 | API中使用的标识 | 手册 | 隔离的资源 |
---|---|---|---|
Cgroup | CLONE_NEWCGROUP | cgroup_namespaces(7) | Cgroup root directory |
IPC | CLONE_NEWIPC | ipc_namespaces(7) | System V IPC, POSIX message queues |
Network | CLONE_NEWNET | network_namespaces(7) | Network devices,stacks,ports,etc. |
Mount | CLONE_NEWNS | mount_namespaces(7) | Mount points |
PID | CLONE_NEWPID | pid_namespaces(7) | Process IDs |
Time | CLONE_NEWTIME | time_namespaces(7) | Boot and monotonic clocks |
User | CLONE_NEWUSER | user_namespaces(7) | User and group IDs |
UTS | CLONE_NEWUTS | uts_namespaces(7) | Hostname and NIS domain name |
namespace相关系统调用
clone 创建新进程,flags参数可以用来创建新的namespace
setns 让进程加入存在的namespace
unshare 将调用进程移动到新的namespace中
ioctl_ns 查看namespace的信息
进程namespace目录
/proc/[pid]/ns/cgroup 进程cgroup命名空间句柄
/proc/[pid]/ns/ipc 进程IPC命名空间句柄
/proc/[pid]/ns/mnt 进程mount命名空间句柄
/proc/[pid]/ns/net 进程网络命名空间句柄
/proc/[pid]/ns/pid 进程PID命名空间句柄
/proc/[pid]/ns/pid_for_children 该进程的子进程的PID命名空间句柄
/proc/[pid]/ns/time 进程time命名空间句柄
/proc/[pid]/ns/user 进程user命名空间句柄
/proc/[pid]/ns/uts 进程UTS命名空间句柄
namespace limit
/proc/sys/user目录
max_cgroup_namespaces
max_inotify_instances
max_inotify_watches
max_ipc_namespaces
max_mnt_namespaces
max_net_namespaces
max_pid_namespaces
max_user_namespaces
max_uts_namespaces
namespace生命周期
namespace中的最后一个进程结束或离开namespace,该namespace生命周期结束
举个例子
![](http://upload-images.jianshu.io/upload_images/15604519-e8ea4f031d968105.jpg?imageMogr2/auto-orient/strip|imageView2/2/w/550/format/webp)
一段C语言代码实现在新的namespace中运行bash
#define _GNU_SOURCE
#include <sys/wait.h>
#include <sys/utsname.h>
#include <sched.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
int static new_world() {
printf("new world\n");
execlp("/bin/bash", "bash", NULL);
return 0;
}
/**
* clone出来新进程的栈大小
*/
#define STACK_SIZE (1024*1024)
int main() {
// linux clone函数
// http://www.man7.org/linux/man-pages/man2/clone.2.html
char *stack;
char *stackTop;
pid_t pid;
struct utsname uts;
//给新进程分配栈空间
stack = mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
if (stack == MAP_FAILED) {
printf("mmap failed!\n");
exit(-1);
}
stackTop = stack + STACK_SIZE;
//clone一个新进程出来
//Notice: Only a privileged process (CAP_SYS_ADMIN) can employ CLONE_NEWCGROUP.
//也就是说必须要用root用户才能执行该程序
pid = clone(new_world, stackTop,
CLONE_NEWCGROUP | CLONE_NEWIPC | CLONE_NEWNET | CLONE_NEWNS | CLONE_NEWUTS | SIGCHLD, NULL);
if (pid == -1) {
printf("clone failed!\n");
exit(-1);
}
if (waitpid(pid, NULL, 0) == -1) {
printf("waitpid failed\n");
exit(-1);
}
printf("child has terminated\n");
return EXIT_SUCCESS;
}
NOTICE:
运行该程序后执行 ls /proc/$$/ns可以查看当前bash进程的namespace
相关命令
lsns 命令可以查看系统下所有的namespace
/proc/[pid]/ns 伪文件系统下记录了进程的所有namespace
作者:写个代码容易么
链接:https://www.jianshu.com/p/319a0cef1f1e
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
posted on 2021-04-16 00:01 ExplorerMan 阅读(553) 评论(0) 编辑 收藏 举报