主要回答的问题

  1. namespace和cgroup的产生原因,各自的功能
  2. 虚拟化技术和容器技术对比时的一个误区。
  3. 容器实际上是什么?
  4. 通过命令行感受PID和MNT这两个namespace的隔离功能
  5. 通过命令行感受cgroup的限制功能(cpu)
  6. 查看docker是如何通过cgroup做到限制cpu的

namespace和cgroup

Q:difference between cgroups and namespaces

  • In short:
    Cgroups = limits how much you can use;
    namespaces = limits what you can see(and therefore use)
    Cgroups involve resource metering and limiting:
    Namespaces provide processes with their own view of the system.(障眼法)
  • 中文结论: namespace 是用来做资源隔离, cgroup 是用来做资源限制

Q: 虚拟化技术和容器技术对比时的一个误区。
A: 容器化不是又一种虚拟化技术,容器是被障眼法所迷惑的一个个主机进程。

  • Q: 容器实际上是什么?
    A: 容器,其实是一种特殊的进程而已。
    除了我们刚刚用到的 PID Namespace,Linux 操作系统还提供了 Mount、UTS、IPC、Network 和 User 这些 Namespace,用来对各种不同的进程上下文进行 障眼法操作。
    比如,Mount Namespace,用于让被隔离进程只看到当前 Namespace 里的挂载点信息;Network Namespace,用于让被隔离进程看到当前 Namespace 里的网络设备和配置。
    所以,Docker 容器这个听起来玄而又玄的概念,实际上是在创建容器进程时,指定了这个进程所需要启用的一组 Namespace 参数
    这样,容器就只能“看”到当前Namespace所限定的资源、文件、设备、状态,或者配置。而对于宿主机以及其他不相关的程序,它就完全看不到了。

namespace

参考附录6(命令行和go代码实现)
6种资源可以被障眼法造成隔离效果

MNT Namespace和mount单独理解下

参考附录6

  • 为什么要mount(挂载)

  • MNT Namespace的作用
    Mount Namespace用来隔离各个进程看到的挂载点视图。在不同Namespace的进程中,看到的文件系统层次是不一样的。
    在Mount Namespace 中调用mount()和umount()仅仅只会影响当前Namespace内的文件系统,而对全局的文件系统是没有影响的.

  • 图解不同NS下的进程看到的挂载点视图不同

  • 命令行演示
mkdir -p /tmp/test_mnt_namespace  //在宿主机创建一个目录作为挂载点.

unshare --mount /bin/sh // 在不同的MNT NS中启动一个/bin/sh进程,随后进入该bash进程,之后的命令都是该bash进程内部执行的。
mount -t tmpfs tmpfs /tmp/test_mnt_namespace // 在新bash进程中挂载一个虚拟设备文件tmpfs到挂载点
cd /tmp/test_mnt_namespace // 访问这个挂载点,相当于访问虚拟设备文件tmpfs。
echo "pid:8493 mnt namespace" > test01.txt // 往其中放入文件text01.txt
ls // 查看当前文件
test01.txt

我们回到宿主机上查看/tmp/test_mnt_namespace是看不到text01.txt文件的。

如果我们用相同操作再创建一个bash进程放入text02.txt,那么在宿主机和第一个bash进程中都是看不到这个text02.txt的。
// 也就是说,尽管挂载点都是/tmp/test_mnt_namespace, 但是不同进程看到的内容(文件/目录)却是不同的,也就达到了隔离的效果。

补充. UID是什么

cgroup

参考附录8

  • 几个核心概念及其相互关系
    tasks,cgroup(control group),hierarchy,subsystem(每种资源一棵树).
  1. tasks把几棵树关联起来,表示不同的资源限制组合。
  2. 层级关系可以传递资源限制。
  3. 这几棵树实际对应着linux的几个目录树结构
    /sys/fs/cgroup/目录下每个文件夹都对应一种资源的限制树。
  • 自己使用cgroup实现cpu资源限制
    参考附录7
  • 查看docker如何利用cgroup实现cpu资源限制的 // CentOS
    参考附录7
docker run -it --cpu-period=100000 --cpu-quota=20000 busybox /bin/sh  // 限制100ms内只有20ms能使用,也就是20%
while : ; do : ; done & // 打满容器cpu
docker ps // 拿到运行容器的id
cd /sys/fs/cgroup/cpu/system.slice/docker-容器id.scope // 切换到该容器(进程)的对应的cpu-hierarchy目录中。
[root@192 docker-e2828f9ef030a9698c8c87025270a53768bac203d0d2e04a5289aa25c5e6697c.scope]# cat cpu.cfs_period_us cpu.cfs_quota_us // 查看配额 100ms/20ms
100000
20000
// 容器内执行top,见下图

Linux命令

pstree

  • example
    pstree -a -p
-a:显示每个程序的完整指令,包含路径,参数或是常驻服务的标示;
-p:显示程序识别码;
-u:显示用户名称;

ps+grep命令

sh-4.2#  ps -ef | grep 10105 // 打印和进程14029相关的所有进程信息,包括该进程本身,该进程作为父子进程的情况
root      10105  10010  0 04:40 pts/0    00:00:00 /bin/sh // bash是父进程
root      10107  10105  0 04:41 pts/0    00:00:00 ps -ef // bash的子进程
root      10108  10105  0 04:41 pts/0    00:00:00 grep 10105 // 还是bash的子进程

mount

[root@localhost ~]# mount [-t 系统类型] [-L 卷标名] [-o 特殊选项] [-n] 设备文件名 挂载点
一个普通的挂载:
mount /dev/sdb1 /mnt/disk1
博客中的一个挂载: 当我没有真实的设备时,tmpfs可以作为一个虚拟的设备用于挂载? TODO
mount -t tmpfs tmpfs /tmp/test_mnt_namespace

-t tmpfs: 挂载为tmpfs文件系统类型
tmpfs: 设备文件名 TODO
/tmp/test_mnt_namespace:挂载点

1. -t 系统类型:指定欲挂载的文件系统类型。Linux 常见的支持类型有 EXT2、EXT3、EXT4、iso9660(光盘格式)、vfat、reiserfs 等。如果不指定具体类型,挂载时 Linux 会自动检测。
2. tmpfs 参考附录5
3. tmpfs 设备
  • mount -bind命令
    使得访问后一个目录就相当于前一个目录。
mount –bind /dev/shm/tmp /tmp

mount --bind和硬连接的区别

Q: 为什么需要挂载
A: 在 Linux 看来,任何硬件设备也都是文件,它们各有自己的一套文件系统(文件目录结构)。
因此产生的问题是,当在 Linux 系统中使用这些硬件设备时,只有将Linux本身的文件目录与硬件设备的文件目录合二为一,硬件设备才能为我们所用。合二为一的过程称为“挂载”。

Q: 挂载做了什么
A: 挂载,指的就是将设备文件中的顶级目录连接到 Linux 根目录下的某一目录(最好是空目录),访问此目录就等同于访问设备文件。

Q: 自动挂载和手动挂载
附录4
A: 《linux挂载》一节讲到,所有的硬件设备必须挂载之后才能使用,只不过,有些硬件设备(比如硬盘分区)在每次系统启动时会自动挂载,而有些(比如 U 盘、光盘)则需要手动进行挂载。

Q: 如果没有挂载,能看到哪些信息。
A: 事实上,当 U 盘插入 Linux 后,系统也确实会给 U 盘分配一个目录文件(比如 sdb1),就位于 /dev/ 目录下(/dev/sdb1),但无法通过 /dev/sdb1/ 直接访问 U 盘数据,访问此目录只会提供给你此设备的一些基本信息(比如容量)。

Q: 自动挂载的路径
A: 根目录下的 /dev/ 目录文件负责所有的硬件设备文件,

df命令

附录3
从中可以看出 挂载的磁盘是/dev/vda1,20G //阿里云抢占式实例

[root@iZ8vbbz0mtspzvkwiu5j64Z /]# df
Filesystem     1K-blocks    Used Available Use% Mounted on
devtmpfs         3994144       0   3994144   0% /dev
tmpfs            4004504       0   4004504   0% /dev/shm
tmpfs            4004504     484   4004020   1% /run
tmpfs            4004504       0   4004504   0% /sys/fs/cgroup
/dev/vda1       20510332 1673444  17771980   9% /
tmpfs             800904       0    800904   0% /run/user/0

/proc/self/exe /proc/[pid]/exe

一个指向自己当前进程的软连接。表示当前进程本身。

参考资料

  1. Linux 进程树查看工具 pstree
  2. 什么是挂载,Linux挂载详解
  3. Linux du命令:统计目录或文件所占磁盘空间大小
  4. Linux mount命令详解:挂载Linux系统外的文件
  5. tmpfs是最好的基于RAM的文件系统
  6. mydocker--Linux Namespace
  7. 06丨白话容器基础(二):隔离与限制
  8. mydocker--Linux Cgroup

TODOLinux文件系统到底有什么用处?

02-14 03:36