Linux namespace命名空间

namespace[1]提供一种隔离机制,让不同的namespace下的进程看到的全局资源不同,每一个namespace有一个自己独立的全局资源实例。
namespace的一个用途是实现容器。

 

Linux namespace命名空间_Linux

linux-namespace.png

Linux系统下的namespace类型

名称API中使用的标识手册隔离的资源
CgroupCLONE_NEWCGROUPcgroup_namespaces(7)Cgroup root directory
IPCCLONE_NEWIPCipc_namespaces(7)System V IPC, POSIX message queues
NetworkCLONE_NEWNETnetwork_namespaces(7)Network devices,stacks,ports,etc.
MountCLONE_NEWNSmount_namespaces(7)Mount points
PIDCLONE_NEWPIDpid_namespaces(7)Process IDs
TimeCLONE_NEWTIMEtime_namespaces(7)Boot and monotonic clocks
UserCLONE_NEWUSERuser_namespaces(7)User and group IDs
UTSCLONE_NEWUTSuts_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生命周期结束

举个例子

 

Linux namespace命名空间_Linux_02

example.jpg

一段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.htmlchar *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:Linux namespace命名空间_Linux_03

运行该程序后执行 ls /proc/$$/ns可以查看当前bash进程的namespace