[root@k8s-master ~]# vim ns.c [root@k8s-master ~]# gcc -o nl nl.c [root@k8s-master ~]# ll total 20 drwxr-xr-x 5 root root 4096 Jan 30 10:00 2019-1-30 -rwxr-xr-x 1 root root 8824 Jan 30 10:01 ns -rw-r--r-- 1 root root 728 Jan 30 10:01 ns.c [root@k8s-master ~]# ./ns Parent - start a container! Container - inside the container! [root@k8s-master ~]# ls 2019-1-30 ns ns.c [root@k8s-master ~]# ls /tmp/ kubectl-edit-fplln.yaml systemd-private-afc4026216a1411886ba9484a063bd2f-vmtoolsd.service-6f4pjo systemd-private-0ea8ac9f463c47a2a1fd701cd31b7f11-chronyd.service-g7wBf0 systemd-private-b950aff5d80e486799e4380086de4b44-chronyd.service-pMgZnM systemd-private-5de01992e9814dbebf18d4b5bedc759b-chronyd.service-0EbBnM tmp.3eJpxKKBQM systemd-private-5de01992e9814dbebf18d4b5bedc759b-vgauthd.service-G9Hekh tmp.3X3XJVLq4z ......... systemd-private-afc4026216a1411886ba9484a063bd2f-vgauthd.service-hgIgbE tmp.ZTAC6cOJKw
Mount Namespace 修改的,是容器进程对文件系统"挂载点"的认知,可是这也就意味,只有在"挂载"这个操做
以后,进程的视图才会被改变,而在此以前,新常见的容器会直接继承宿主机的各个挂载点node
修改nc文件linux
[root@k8s-master ~]# cat ns.c #define _GNU_SOURCE #include <sys/mount.h> #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 container_stack[STACK_SIZE]; char* const container_args[] = { "/bin/bash", NULL }; int container_main(void* arg) { printf("Container - inside the container!\n"); // 若是你的机器的根目录的挂载类型是 shared,那必须先从新挂载根目录 // mount("", "/", NULL, MS_PRIVATE, ""); mount("none", "/tmp", "tmpfs", 0, ""); execv(container_args[0], container_args); printf("Something's wrong!\n"); return 1; } int main() { printf("Parent - start a container!\n"); int container_pid = clone(container_main, container_stack+STACK_SIZE, CLONE_NEWNS | SIGCHLD , NULL); waitpid(container_pid, NULL, 0); printf("Parent - container stopped!\n"); return 0; }
再次执行vim
[root@k8s-master ~]# gcc -o ns ns.c [root@k8s-master ~]# ./ns Parent - start a container! Container - inside the container! [root@k8s-master ~]# ls /tmp/ [root@k8s-master ~]# ls 2019-1-30 ns ns.c
能够看到,此次/tmp变成了一个空目录,这意味着从新挂载生效了,咱们用mount -l检查一下bash
[root@k8s-master ~]# mount -l | grep tmpfs devtmpfs on /dev type devtmpfs (rw,nosuid,size=1006112k,nr_inodes=251528,mode=755) tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev) tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755) tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755) tmpfs on /run/user/0 type tmpfs (rw,nosuid,nodev,relatime,size=203192k,mode=700) none on /tmp type tmpfs (rw,relatime) [root@k8s-master ~]# ls /tmp/ [root@k8s-master ~]# exit exit Parent - container stopped! [root@k8s-master ~]# mount -l | grep tmpfs devtmpfs on /dev type devtmpfs (rw,nosuid,size=1006112k,nr_inodes=251528,mode=755) tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev) tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755) tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755) tmpfs on /run/user/0 type tmpfs (rw,nosuid,nodev,relatime,size=203192k,mode=700) none on /tmp type tmpfs (rw,relatime)
这就是 Mount Namespace 跟其余 Namespace 的使用略有不一样的地方:它对容器进程视图的改变
必定是伴随着挂载操做(mount)才能生效。ide
mkdir -p luoahong/test mkdir -p luoahong/test/{bin,lib64,lib} T=luoahong/test cd $T cp -v /bin/{bash,ls} luoahong/test/bin T=/root/luoahong/test list="$(ldd /bin/ls | egrep -o '/lib.*\.[0-9]')" for i in $list; do cp -v "$i" "${T}${i}"; done $ chroot /root/luoahong/test /bin/bash chroot
实际上,Mount Namespace 正是基于对 chroot 的不断改良才被发明出来的,它也是Linux 操做系统里的第一个 Namespaceui
它最核心的原理实际上就是为待建立的用户进程spa
一、启用Linux Namespace配置;
二、设置置顶的Cgroups参数
三、切换进程的跟目录操作系统
roots只是一个操做系统所含的文件,配置和目录,并不包含操做系统内核,在linux操做系统中,
这两部分是分开存放的,操做系统只有在开机启动时才会加载指定版本的内核镜像设计
正是因为rootfs的存在,容器才有了一个被反复宣传至今的只要特性:一致性blog
因为rootfs里打包的不仅是应用,而是整个操做系统的文件目录,也就意味着,应用以及它运行所须要的
全部依赖,被封装在了一块儿
对一个应用来讲,操做系统自己才是它所需的最完整的"依赖库"
这种深刻到操做系统级别的运行环境一致性,打通了应用在本地开发和远端执行环境之间难以逾越的鸿沟。
Docker 在镜像的设计中,引入了层(layer)的概念。也就是说,用户制做镜像的每一步操做,都会生成一个层,也就是一个增量rootfs
$ mkdir C $ mount -t aufs -o dirs=./A:./B none ./C [root@k8s-master tree]# tree . ├── A │ ├── a │ └── x └── B ├── b └── X $ tree ./C ./C ├── a ├── b └── x
继Namespace构建了四周的围墙(进程隔离),Cgroups构建了受控的天空优先使用阳光雨露(资源限制),Mount namespace与rootfs构建了脚下的大地,这片土地是你熟悉和喜欢的,无论你走到哪里,均可以带着它,就好像你从未离开过家乡,没有丝毫的陌生感(容器的一致性)~