容器核心技术感受 Namespace
发布时间:2023-06-05 13:02:17 所属栏目:教程 来源:
导读:Namespace 能不能让我们直接观察到呢?
让我们进入 Linux 环境,执行如下操作:
# 进入/proc/目录cd /proc/# 查看当前目录下有哪些文件或目录ls# 随便进入一个以数字(进程号)命名的目录,比如1cd 1# 查看ns(
让我们进入 Linux 环境,执行如下操作:
# 进入/proc/目录cd /proc/# 查看当前目录下有哪些文件或目录ls# 随便进入一个以数字(进程号)命名的目录,比如1cd 1# 查看ns(
Namespace 能不能让我们直接观察到呢? 让我们进入 Linux 环境,执行如下操作: # 进入/proc/目录cd /proc/# 查看当前目录下有哪些文件或目录ls# 随便进入一个以数字(进程号)命名的目录,比如1cd 1# 查看ns(Namespace)目录下的内容ls -al ns 当前目录下红色的链接,就是这个进程对应的 Namespace。 有兴趣的读者可以看看其他不同进程的 Namespace,比对下是否有差异。如果你找到某个进程的Namespace 与其他的不一致,就说明这个进程指定了 Namespace 隔离。 使用 Namespace 自制简易容器 将以下代码保存到/root/test/container.c #define _GNU_SOURCE#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/mount.h>#include <sys/capability.h>#include <stdio.h>#include <sched.h>#include <signal.h>#include <unistd.h>#define STACK_SIZE (1024 * 1024)static char container_stack[STACK_SIZE];char* const container_args[] = {/bin/bash,NULL};int pipefd[];void set_map(char* file, int inside_id, int outside_id, int len) {FILE* mapfd = fopen(file, w);if (NULL == mapfd) {perror(open file error);return;}fprintf(mapfd, %d %d %d, inside_id, outside_id, len);fclose(mapfd);}void set_uid_map(pid_t pid, int inside_id, int outside_id, int len) {char file[];sprintf(file, /proc/%d/uid_map, pid);set_map(file, inside_id, outside_id, len);}void set_gid_map(pid_t pid, int inside_id, int outside_id, int len) {char file[];sprintf(file, /proc/%d/gid_map, pid);set_map(file, inside_id, outside_id, len);}int container_main(){char ch;close(pipefd[]);read(pipefd[], &ch, );sethostname(container,);/* Mount Namespace */mount(proc, /proc, proc, , NULL);mount(none, /tmp, tmpfs, , );execv(container_args[], container_args);return ;}int main(){const int gid=getgid(), uid=getuid();pipe(pipefd);int container_pid = clone(container_main, container_stack+STACK_SIZE,CLONE_NEWCGROUP|CLONE_NEWIPC|CLONE_NEWUTS | CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWUSER | SIGCHLD, NULL);set_uid_map(container_pid, , uid, );set_gid_map(container_pid, , gid, );close(pipefd[]);waitpid(container_pid, NULL, );return ;} 我们不用读懂这个代码,只需要留意下 main 主函数中这部分 int container_pid = clone(container_main, container_stack+STACK_SIZE,CLONE_NEWCGROUP|CLONE_NEWIPC|CLONE_NEWNET|CLONE_NEWUTS | CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWUSER | SIGCHLD, NULL); 这段代码 调用 clone 实现线程的系统调用,用来创建一个新的进程,并可以通过设计上述参数达到隔离。 执行下面的操作 # 安装可能需要的依赖sudo dnf install -y libcap-devel# 编译这个文件cc container.c -o container# 运行./container 执行我们编译好的container程序后,发现我们处于一个新的环境的终端中,你可以在这里验证你的猜测,比如查看当前环境的进程 ps,当前登录的用户 whoami,网络状况 ip a等等,使用exit 可以退出回到原来的环境。 我们确实通过系统调用,创建了一个与宿主机资源隔离的容器环境。 (编辑:汽车网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |