一、容器里的进程看到的文件系统又是什么样子呢?

1、你会看到好多宿主机的文件

  1. [root@k8s-master ~]# vim ns.c
  2. [root@k8s-master ~]# gcc -o nl nl.c
  3. [root@k8s-master ~]# ll
  4. total 20
  5. drwxr-xr-x 5 root root 4096 Jan 30 10:00 2019-1-30
  6. -rwxr-xr-x 1 root root 8824 Jan 30 10:01 ns
  7. -rw-r--r-- 1 root root 728 Jan 30 10:01 ns.c
  8. [root@k8s-master ~]# ./ns
  9. Parent - start a container!
  10. Container - inside the container!
  11. [root@k8s-master ~]# ls
  12. 2019-1-30 ns ns.c
  13. [root@k8s-master ~]# ls /tmp/
  14. kubectl-edit-fplln.yaml systemd-private-afc4026216a1411886ba9484a063bd2f-vmtoolsd.service-6f4pjo
  15. systemd-private-0ea8ac9f463c47a2a1fd701cd31b7f11-chronyd.service-g7wBf0 systemd-private-b950aff5d80e486799e4380086de4b44-chronyd.service-pMgZnM
  16. systemd-private-5de01992e9814dbebf18d4b5bedc759b-chronyd.service-0EbBnM tmp.3eJpxKKBQM
  17. systemd-private-5de01992e9814dbebf18d4b5bedc759b-vgauthd.service-G9Hekh tmp.3X3XJVLq4z
  18. .........
  19. systemd-private-afc4026216a1411886ba9484a063bd2f-vgauthd.service-hgIgbE tmp.ZTAC6cOJKw

Mount Namespace 修改的,是容器进程对文件系统"挂载点"的认知,但是这也就意味,只有在"挂载"这个操作
之后,进程的视图才会被改变,而在此之前,新常见的容器会直接继承宿主机的各个挂载点

2、tmp 变成了一个空目录

修改nc文件

  1. [root@k8s-master ~]# cat ns.c
  2. #define _GNU_SOURCE
  3. #include <sys/mount.h>
  4. #include <sys/types.h>
  5. #include <sys/wait.h>
  6. #include <stdio.h>
  7. #include <sched.h>
  8. #include <signal.h>
  9. #include <unistd.h>
  10. #define STACK_SIZE (1024 * 1024)
  11. static char container_stack[STACK_SIZE];
  12. char* const container_args[] = {
  13. "/bin/bash",
  14. NULL
  15. };
  16.  
  17. int container_main(void* arg)
  18. {
  19. printf("Container - inside the container!\n");
  20. // 如果你的机器的根目录的挂载类型是 shared,那必须先重新挂载根目录
  21. // mount("", "/", NULL, MS_PRIVATE, "");
  22. mount("none", "/tmp", "tmpfs", 0, "");
  23. execv(container_args[0], container_args);
  24. printf("Something's wrong!\n");
  25. return 1;
  26. }
  27.  
  28. int main()
  29. {
  30. printf("Parent - start a container!\n");
  31. int container_pid = clone(container_main, container_stack+STACK_SIZE, CLONE_NEWNS | SIGCHLD , NULL);
  32. waitpid(container_pid, NULL, 0);
  33. printf("Parent - container stopped!\n");
  34. return 0;
  35. }

再次执行

  1. [root@k8s-master ~]# gcc -o ns ns.c
  2. [root@k8s-master ~]# ./ns
  3. Parent - start a container!
  4. Container - inside the container!
  5. [root@k8s-master ~]# ls /tmp/
  6. [root@k8s-master ~]# ls
  7. 2019-1-30 ns ns.c

可以看到,这次/tmp变成了一个空目录,这意味着重新挂载生效了,我们用mount -l检查一下

  1. [root@k8s-master ~]# mount -l | grep tmpfs
  2. devtmpfs on /dev type devtmpfs (rw,nosuid,size=1006112k,nr_inodes=251528,mode=755)
  3. tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
  4. tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
  5. tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755)
  6. tmpfs on /run/user/0 type tmpfs (rw,nosuid,nodev,relatime,size=203192k,mode=700)
  7. none on /tmp type tmpfs (rw,relatime)
  8. [root@k8s-master ~]# ls /tmp/
  9. [root@k8s-master ~]# exit
  10. exit
  11. Parent - container stopped!
  12. [root@k8s-master ~]# mount -l | grep tmpfs
  13. devtmpfs on /dev type devtmpfs (rw,nosuid,size=1006112k,nr_inodes=251528,mode=755)
  14. tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
  15. tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755)
  16. tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
  17. tmpfs on /run/user/0 type tmpfs (rw,nosuid,nodev,relatime,size=203192k,mode=700)
  18. none on /tmp type tmpfs (rw,relatime)

这就是 Mount Namespace 跟其他 Namespace 的使用略有不同的地方:它对容器进程视图的改变
一定是伴随着挂载操作(mount)才能生效。

二、Mount Namespace 和 rootfs为容器进程构建出一个完善的文件系统隔离环境

1、chroot 的命令改变简称的根目录到你指定的位置

  1. mkdir -p luoahong/test
  2. mkdir -p luoahong/test/{bin,lib64,lib}
  3. T=luoahong/test
  4. cd $T
  5.  
  6. cp -v /bin/{bash,ls} luoahong/test/bin
  7.  
  8. T=/root/luoahong/test
  9. list="$(ldd /bin/ls | egrep -o '/lib.*\.[0-9]')"
  10. for i in $list; do cp -v "$i" "${T}${i}"; done
  11.  
  12. $ chroot /root/luoahong/test /bin/bash
  13. chroot

实际上,Mount Namespace 正是基于对 chroot 的不断改良才被发明出来的,它也是Linux 操作系统里的第一个 Namespace

2、Mount Namespace最核心的原理是?

它最核心的原理实际上就是为待创建的用户进程

1、启用Linux Namespace配置;
2、设置置顶的Cgroups参数
3、切换进程的跟目录

roots只是一个操作系统所含的文件,配置和目录,并不包含操作系统内核,在linux操作系统中,
这两部分是分开存放的,操作系统只有在开机启动时才会加载指定版本的内核镜像

3、容器的灵魂在哪呢?

正是由于rootfs的存在,容器才有了一个被反复宣传至今的只要特性:一致性

由于rootfs里打包的不只是应用,而是整个操作系统的文件目录,也就意味着,应用以及它运行所需要的

所有依赖,被封装在了一起

对一个应用来说,操作系统本身才是它所需的最完整的"依赖库"

这种深入到操作系统级别的运行环境一致性,打通了应用在本地开发和远端执行环境之间难以逾越的鸿沟。

Docker 在镜像的设计中,引入了层(layer)的概念。也就是说,用户制作镜像的每一步操作,都会生成一个层,也就是一个增量rootfs

4、什么是联合文件系统?

  1. $ mkdir C
  2. $ mount -t aufs -o dirs=./A:./B none ./C
  3.  
  4. [root@k8s-master tree]# tree
  5. .
  6. ├── A
  7. ├── a
  8. └── x
  9. └── B
  10. ├── b
  11. └── X
  12.  
  13. $ tree ./C
  14. ./C
  15. ├── a
  16. ├── b
  17. └── x

5、经典留言

继Namespace构建了四周的围墙(进程隔离),Cgroups构建了受控的天空优先使用阳光雨露(资源限制),Mount namespace与rootfs构建了脚下的大地,这片土地是你熟悉和喜欢的,不管你走到哪里,都可以带着它,就好像你从未离开过家乡,没有丝毫的陌生感(容器的一致性)~

深入剖析Kubernetes学习笔记:深入理解镜像(07)的更多相关文章

  1. 深入剖析Kubernetes学习笔记:深入理解镜像(08)

    一.Python 应用案例环境 [root@k8s-node1 Flask]# pwd /opt/Dockerfile/Flask [root@k8s-node1 Flask]# ll total 1 ...

  2. 深入剖析Kubernetes学习笔记:开篇词(00)

    一.关于Kubernetes初学的疑惑 就在这场因"容器"而起的技术变革中,kubernetes项目已经成为容器技术的事实标准,重新定义了基础设置领域对应用编排与管理的种种可能 1 ...

  3. 深入剖析Kubernetes学习笔记:预习篇(01-04)

    01 初出茅庐 1.PaaS 项目被大家接纳的一个主要原因? 就是它提供了一种名叫"应用托管". 2.像 Cloud Foundry 这样的 PaaS 项目,最核心的组件是? 一套 ...

  4. 深入剖析Kubernetes学习笔记:容器基础(05-06)

    05 :从进程说起 1.容器本身没有价值,有价值的是"容器编排" 2.什么是进程? 一旦"程序"被执行起来,它就从磁盘上的二进制文件,变成 1.计算机内存中的数 ...

  5. Kubernetes 学习笔记(一):基础概念

    个人笔记,仅本人查阅使用,不保证正确. 零.微服务 微服务架构专注于应用解耦合,通过将应用彻底地组件化和服务化,每个微服务只包含一个非常小的功能,比如权限管理.日志收集等等.由这一组微服务组合起来,提 ...

  6. Kubernetes学习笔记(八):Deployment--声明式的升级应用

    概述 本文核心问题是:如何升级应用. 对于Pod的更新有两种策略: 一是删除全部旧Pod之后再创建新Pod.好处是,同一时间只会有一个版本的应用存在:缺点是,应用有一段时间不可用. 二是先创建新Pod ...

  7. 微信小程序开发:学习笔记[7]——理解小程序的宿主环境

    微信小程序开发:学习笔记[7]——理解小程序的宿主环境 渲染层与逻辑层 小程序的运行环境分成渲染层和逻辑层. 程序构造器

  8. Kubernetes学习笔记(四):服务

    服务介绍 服务是一种为一组相同功能的pod提供单一不变接入点的资源.当服务存在时,他的IP和端口不会改变.客户端通过IP和端口建立连接,这些连接会被路由到任何一个pod上.如此,客户端不需要知道每个单 ...

  9. Kubernetes学习笔记之认识Kubernetes组件

    前言:笔记知识点来源于Kubernetes官方文档说明,链接:https://kubernetes.io/docs/concepts/overview/components/ ,本记录仅仅是学习笔记记 ...

随机推荐

  1. 基于django的视频点播网站开发

    项目名称 基于django的视频点播网站开发 项目背景 学习完毕python和django之后,想找个项目练练手,本来想写个博客项目练手,无奈别人已经写过了,所以笔者就打算写一个视频点播网站,因为笔者 ...

  2. PM领导能力成熟度2级

    人生如戏,大幕拉开,他走上舞台,饰演PM一角. 从技术岗位迈向管理岗位的第一步,对大多数像他一样的新晋PM来说,并不轻松.技术知识与经验是他曾经的主要才能与成功基础,而从成熟度一级开始,身为管理者的他 ...

  3. windows下编译Grafana前端

    本次介绍一下Windows环境源码编译步骤. 准备 安装Go 1.8.1 安装NodeJS LTS 安装Git 安装golang开发环境:  参考链接:https://www.cnblogs.com/ ...

  4. CentOS 6忘记root密码的解决办法

    1.在开机启动的时候按键盘上的“E”键 或者“ESC”键,会进入如下界面 2.选择相应的内核,再次按“E”,出现下图,选择第二项,再次按“E”键 3.经过第二步,这个画面可以编辑,在信息的最后加“空格 ...

  5. 解决RSA加密中,System.Security.Cryptography.CryptographicException: 系统找不到指定的文件

    首先说下环境,win2008R2,iis7.5 遇到这个问题,困扰了我一天,在外国的网站上找到答案,还好有点英文基础.最后算是解决了,不过其中的原理还是没有搞的十分清楚. 先说下解决办法, 打开IIS ...

  6. Java基础系列--04_数组

    一维数组: (1)数组:存储同一种数据类型的多个元素的容器. (2)特点:每一个元素都有编号,从0开始,最大编号是数组的长度-1. 编号的专业叫法:索引 (3)定义格式 A:数据类型[] 数组名;(一 ...

  7. UVA - 11090 - Going in Cycle!!(二分+差分约束系统)

    Problem  UVA - 11090 - Going in Cycle!! Time Limit: 3000 mSec Problem Description You are given a we ...

  8. 使用try-with-resources优雅的关闭IO流

    Java类库中包括许多必须通过调用close方法来手工关闭的资源.例如InputStream.OutputStream和java.sql.Connection.客户端经常会忽略资源的关闭,造成严重的性 ...

  9. 类 Calendar

    简介 Java.util.Calendar是日历类,在Date后出现,替换掉了许多Date的方法.该类将所有可能用到的时间信息封装为静态成员变量,方便获取.日历类就是方便获取各个时间属性的.注意Cal ...

  10. [c++项目]迷宫 控制台游戏

    #include<stdio.h> #include<windows.h> #include<stdlib.h> #include<time.h> #i ...