美文网首页
容器的本质

容器的本质

作者: 郭青耀 | 来源:发表于2020-10-10 11:14 被阅读0次

容器的本质就是一组特殊的进程,它使用namespace做隔离,用cgroup做限制。

  • 这里的容器可以是docker ,rkt等
  • 因为容器是一组特殊的进程,所以他们是跑在同一个内核上的,隔离性没有虚拟机好。
  • 还因为进程带来的性能损耗比虚拟机小很多,它也是特别轻量的虚拟化。

如何使用namespace对容器做隔离的

容器是如何使用namespace做隔离的,因为namespace的种类也很多(pid,mount,network,ipc,user,UTS),这里以PID namespace为例。
首先看一下关于PID 的一个小实验:
环境说明:

  • 宿主机ubuntu 20.04
  • docker 容器
  • docker 加入了root组,所以不用输入sudo,容器启动的进程也是在root组中

实验步骤:

  1. 启动一个centos的交互终端
    docker run -it centos /bin/bash
  2. 看看容器内部bash进程的pid


    bash_pid.png
  3. 看看宿主机上bash进程的pid,用户是root的那个pid.


    宿主机pid.png

由上面的例子可以看到,容器启动的bash在容器内部看到的pid是1,在数组上看到的PID是31840,这是怎么做到的,其实很简单:
正常我们clone一个进程使用下面代码,
int pid = clone(child_main, stack_size, SIGCHLD, NULL);
如果要想这个新进程只能看到自己,以及由自己clone出来的进程(在上面的例子中就是容器内执行的ps进程),不能看到其他进程,使用这段代码
int pid = clone(child_main, stack_size, CLONE_NEWPID | SIGCHLD, NULL);
唯一的区别就是加入了CLONE_NEWPID,其他的namespace隔离也是使用相同的方式
int pid = clone(child_main, stack_size, CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWPID | SIGCHLD, NULL);
这就是同时对,UTS, IPC,PID同时做namespace的隔离。

这里有点不同是mount namespace ,因为mount namespace一定是伴随着mount动作才会生效。mount namespace由chroot 命令发展而来,chroot: change root file system,将根目录"/",挂载到指定的位置。通常我们说的容器镜像,就是挂载在根目录的文件系统,它为隔离后的容器提供文件系统,专业称之为"rootfs".

如何使用cgroup 对资源做限制

cgroup是一个内核功能,它能限制一个或者一组进程对进程资源(cpu,内存,网络等)的使用量不超过被分配的量。cgroup 给用户暴露出来的的操作系统接口是文件系统
mount -t cgroup
可以看到有哪些可以做cgroup限制的类型。

cgroup_type.png

下面演示一个对cpu类型的cgroup做限制的实例。
环境说明:

  • 宿主机ubuntu 20.04
  • docker 容器
  • docker 加入了root组,所以不用输入sudo,容器启动的进程也是在root组中

实验步骤:

  1. 启动一个centos的交互终端
    docker run -it centos /bin/bash
  2. 查看cpu 限制文件参数
[root@f7ab6d1d8b37 /]# ls /sys/fs/cgroup/cpu
cgroup.clone_children  cpu.shares      cpuacct.stat      cpuacct.usage_percpu_sys   notify_on_release
cgroup.procs           cpu.stat        cpuacct.usage         cpuacct.usage_percpu_user  tasks
cpu.cfs_period_us      cpu.uclamp.max  cpuacct.usage_all     cpuacct.usage_sys
cpu.cfs_quota_us       cpu.uclamp.min  cpuacct.usage_percpu  cpuacct.usage_user

这些文件中重要的有,cpu.cfs_period_us和cpu.cfs_quota_us ,表示在时间长度为cpu.cfs_period_us的时间内,可以分配到的CPU时间是cpu.cfs_quota_us ,单位都是us;
默认是没有限制的

[root@f7ab6d1d8b37 /]# cat  /sys/fs/cgroup/cpu/cpu.cfs_quota_us 
-1
[root@f7ab6d1d8b37 /]# cat  /sys/fs/cgroup/cpu/cpu.cfs_period_us 
100000

  1. 写一个死循环,并放到后台执行,记下后台进程的PID
[root@f7ab6d1d8b37 /]# sh deadloop.sh &
[1] 39
[root@f7ab6d1d8b37 /]# cat deadloop.sh 
while true :;
do :;
done
[root@f7ab6d1d8b37 /]# 

后台进程的PID=39

  1. 使用top查看刚才死循环的CPU使用率100%


    cpu_100.png

  1. 现在使用限制cpu方式启动容器,
    设置cpu 100ms(即100000us)可以使用30ms(即30000us)
    docker run -it --cpu-period=100000 --cpu-quota=30000 centos /bin/bash
  2. 查看cgroup中的参数设置


    cgroup30.png
  3. 运行同样的死循环程序
[root@c10f06c1832b /]# sh deadloop.sh  &
[1] 17
[root@c10f06c1832b /]# cat deadloop.sh 
while true :;
do :;
done

后台进程的PID=17

  1. 使用top查看刚才死循环的CPU使用率约等于30%,说明CPU使用率设置生效。


    top30.png

其他类型的Cgroup也是使用类似的方式做资源限制的。

相关文章

  • 容器的本质

    容器的本质就是一组特殊的进程,它使用namespace做隔离,用cgroup做限制。 这里的容器可以是docker...

  • docker 容器的基本管理

    1 容器的管理 1.1 容器的创建 1.1 新建并启动容器 1.1.1 容器的生命周期 容器其实本质是Host宿主...

  • 关联容器

    关联容器与顺序容器的本质差别在于:关联容器通过键值(key)存储和读取元素,而顺序容器则通过袁术在容器中的位置存储...

  • (十四)C++篇-关联容器map和set

    关联容器和顺序容器的本质差别在于:关联容器通过键(key)存储和读取元素,而顺序容器则通过元素在容器中的位置顺序存...

  • Spring知识点总结

    Spring 源码分析 IOC(Inversion of Controller)本质是一个容器, 这个容器在Spr...

  • 线程学习记录08-Concurrent与CopyOnWrite容

    一、什么是同步类容器和并发容器?同步类容器:最常见的就如Vector和Hashtable等。其本质就是由Colle...

  • [C++ Primer Note10] 关联容器

    关联容器和顺序容器的本质区别在于:关联容器中的元素是按关键字来保存和访问的,而顺序容器是按它们在容器中的位置来顺序...

  • Fragment 原理

    1. fragment 本质 fragment 本质上是 view 的容器和控制器,fragment 是 acti...

  • 【深入剖析Tomcat笔记】第五篇 Tomcat Contain

    简述 在第一章开始就提到,Tomcat的本质什么?是容器。容器这个概念现在很火,一提到容器,我们立马可以想到虚拟化...

  • mybatis连接池技术及事务

    连接池:本质是一个存储连接的容器,减少我们连接服务器的时间。容器本质就是一个集合。但该集合必须是一个安全线程。不能...

网友评论

      本文标题:容器的本质

      本文链接:https://www.haomeiwen.com/subject/cppdpktx.html