15.namespace本质,cgroup本质,层结构,mount namespace介绍

namespace本质

它其实只是 Linux 创建新进程clone()的一个可选参数

namespace类型

除了我们刚刚用到的 PID Namespace,Linux 操作系统还提供了 Mount、UTS、IPC、Network 和 User 这些 Namespace,用来对各种不同的进程上下文进行“障眼法”操作。

所有容器共享内核

尽管你可以在容器里通过 Mount Namespace 单独挂载其他不同版本的操作系统文件,比如 CentOS 或者 Ubuntu,但这并不能改变共享宿主机内核的事实。

所有的资源都可以namespace化吗?

在 Linux 内核中,有很多资源和对象是不能被 Namespace 化的,最典型的例子就是:时间。

namespace和cgroup各自的功能是什么?

namespace完成隔离,cgroup完成限制
Cgroups 技术是用来制造约束的主要手段,而 Namespace 技术则是用来修改进程视图的主要方法。

cgroup主要作用是什么?

它最主要的作用,就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。

cgroup如何起作用?如何使用?

  • 在 /sys/fs/cgroup 下面有很多诸如 cpuset、cpu、 memory 这样的子目录,也叫子系统
    • 子系统下的一系列配置文件实现了容器资源限制
  • Cgroups 给用户暴露出来的操作接口是文件系统,即它以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下

容器是如何利用cgroup的?

容器创建的时候,在cgroup的子系统下比如sys/fs/cgroup/cpu下创建一个子目录container, container里会自动生成和cpu目录下一致的配置文件,改变这些配置文件里的值,然后把被限制的进程(即容器进程)的PID写入tasks即可。 这些配置文件的值一般是docker run的时候指定的

cgroup缺点?

  • 众所周知,Linux 下的 /proc 目录存储的是记录当前内核运行状态的一系列特殊文件,用户可以通过访问这些文件,查看系统以及当前正在运行的进程的信息,比如 CPU 使用情况、内存占用率等,这些文件也是 top 指令查看系统信息的主要数据来源。
  • 你如果在容器里执行 top 指令,就会发现,它显示的信息居然是宿主机的 CPU 和内存数据,而不是当前容器的数据。因为/proc 文件系统并不知道用户通过 Cgroups 给这个容器做了什么样的资源限制,即:/proc 文件系统不了解 Cgroups 限制的存在。

如何克服/proc问题?
把宿主机的 /var/lib/lxcfs/proc/* 文件挂载到容器的/proc/*

为什么容器最好不要同时运行两个进程?

  • 容器是一个“单进程”模型。由于一个容器的本质就是一个进程,用户的应用进程实际上就是容器里 PID=1 的进程,也是其他后续创建的所有进程的父进程。这就意味着,在一个容器中,你没办法同时运行两个不同的应用,除非你能事先找到一个公共的 PID=1 的程序来充当两个不同应用的父进程,这也是为什么很多人都会用 systemd 或者 supervisord 这样的软件来代替应用本身作为容器的启动进程。
    • 因为PID=1的进程就是容器中其他进程的父进程,退出后容器也退出了,其他进程也退出了。

mount namespace问题

mount namespace默认继承宿主机的文件系统,必须执行mount操作之后,才能看到不同的文件系统

容器怎么完成mount namespace挂载的?难不成一个个mount()

  • 不是,只挂载本身的根目录即可,通过chroot可以一次挂载。
  • 容器会把自己的进程根目录通过 chroot完成切根。
    • chroot就是一个linux命令,作用是修改视图
    • chroot $HOME/test /bin/bash

容器根目录会挂载什么?

  • 一般会在容器的根目录下挂载一个完整os的fs, 而这个挂载在容器根目录上、用来为容器进程提供隔离后执行环境的文件系统, 就是所谓的容器镜像, 也叫rootfs
  • 那么每开发/升级完一个应用,都要重复只做一次rootfs吗?引入层, 用户制作镜像的每一步操作,都会生成一个层,也就是一个增量rootfs,然后通过UnionFS把多个不同位置的目录联合挂载到同一个目录下。

unionFS是如何挂载的?

  • unionFS一个实例,aufs,其关键目录结构在 /var/lib/docker/aufs/diff 目录下,diff下是一个个层
  • 镜像的层都放置在 /var/lib/docker/aufs/diff 目录下,然后被联合挂载在 /var/lib/docker/aufs/mnt 里面。
  • 查看mnt下的子目录,果然是一个完整的ubuntu os

如何查看aufs挂载信息?

  • cat /proc/mounts| grep aufs 找到挂载目录对应的aufs内部id:si
  • 通过cat /sys/fs/aufs/si_972c6d361e6b32ba/br[0-9]* 查到联合挂载的层目录,然后发现这些层分成三种:容器层、init层、只读层
  • docker init可用作 docker commit只提交容器层,不提init层。 init层:etc/hosts这些用户专属值
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值