anancds / document

MIT License
1 stars 0 forks source link

docker namespace #96

Open anancds opened 4 years ago

anancds commented 4 years ago

namespace提供了6种隔离: UTS:主机名与域名,系统调用参数是:CLONE_NEWUTS IPC:信号量、消息队列和共享内存,系统参数是:CLONE_NEWIPC PID:进程编号,系统参数是:CLONE_NEWPID NETWORK:网络设备、网络栈、端口等,系统参数是:CLONE_NEWNET Mount:挂载点(文件系统),系统参数是:CLONE_NEWNS User:用户和用户组,系统参数是:CLONE_NEWUSER

anancds commented 4 years ago

UTS namespace

#define _GNU_SOURCE

#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <sched.h>
#include <signal.h>
#include <unistd.h>

#define STACK_SIZE (1024 * 1024)

static char child_stack[STACK_SIZE];
char* const child_args[] = { "/bin/bash", NULL};

int child_main(void* args)
{
    printf("我们此时在子进程中!输入'exit'命令可以退出子进程,此时主机名已修改。\n");
    sethostname("NewNamespace", 12);
    execv(child_args[0], child_args);
    return 1;
}

int main()
{
    printf("程序开始:\n");
    printf("使用clone()来创建一个独立的namespace的进程,此时会进入子进程中。\n");
    printf("此时演示的是UTS namespace功能。\n");
    int child_pid = clone(child_main, child_stack + STACK_SIZE, CLONE_NEWUTS | SIGCHLD, NULL);
    waitpid(child_pid, NULL, 0);
    printf("已退出子进程。\n");
    return 0;
}
anancds commented 4 years ago

IPC nameapace:运行程序前使用ipcmk -Q创建message queue,然后使用ipcs -q可以查看结果,进入程序后,使用ipcs -q查看不到之前声明的message queue,这说明IPC隔离成功了。

#define _GNU_SOURCE

#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <sched.h>
#include <signal.h>
#include <unistd.h>

#define STACK_SIZE (1024 * 1024)

static char child_stack[STACK_SIZE];
char* const child_args[] = { "/bin/bash", NULL};

int child_main(void* args)
{
    printf("我们此时在子进程中!输入'exit'命令可以退出子进程,此时主机名已修改。\n");
    sethostname("NewNamespace", 12);
    execv(child_args[0], child_args);
    return 1;
}

int main()
{
    printf("程序开始:\n");
    printf("使用clone()来创建一个独立的namespace的进程,此时会进入子进程中。\n");
    printf("此时演示的是IPC namespace功能。\n");
    int child_pid = clone(child_main, child_stack + STACK_SIZE, CLONE_NEWIPC | CLONE_NEWUTS | SIGCHLD, NULL);
    waitpid(child_pid, NULL, 0);
    printf("已退出子进程。\n");
    return 0;
}
anancds commented 4 years ago

PID namespace:不同的namespace中其pid可以和别的namespace下的相同。在运行程序后,进入了另一个namespace,输入echo $$可以看到pid为1。

#define _GNU_SOURCE

#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <sched.h>
#include <signal.h>
#include <unistd.h>

#define STACK_SIZE (1024 * 1024)

static char child_stack[STACK_SIZE];
char* const child_args[] = { "/bin/bash", NULL};

int child_main(void* args)
{
    printf("我们此时在子进程中!输入'exit'命令可以退出子进程,此时主机名已修改。\n");
    sethostname("NewNamespace", 12);
    execv(child_args[0], child_args);
    return 1;
}

int main()
{
    printf("程序开始:\n");
    printf("使用clone()来创建一个独立的namespace的进程,此时会进入子进程中。\n");
    printf("此时演示的是PID namespace功能。\n");
    int child_pid = clone(child_main, child_stack + STACK_SIZE, CLONE_NEWPID | CLONE_NEWIPC | CLONE_NEWUTS | SIGCHLD, NULL);
    waitpid(child_pid, NULL, 0);
    printf("已退出子进程。\n");
    return 0;
}