[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構建了腳下的大地,這片土地是你熟悉和喜歡的,無論你走到哪裏,均可以帶着它,就好像你從未離開過家鄉,沒有絲毫的陌生感(容器的一致性)~