我们总说容器通过namespace,cgroup来限定资源,达到一个隔离的效果,总说镜像层级,可读可写等背书一样的概念,但是如何达到这种效果?如何抹平不同操作系统差异达到一致性?docker-compose/kubernets 细节是什么?这些我不知道,这种不能将其融于自己只是体系的理解,很是痛苦。<br /> 可能大多数人和我一样,会用,了解。 我在接触容器之后感觉只留于表面使用,在出现错误的时候,更多的是被动去接受。希望重新学习的时候,能和自己学习的linux操作系统只是相互反馈。
1. 从进程开始说。
一个程序执行的时候,会将该程序的磁盘的二进制的文件,加载入内存,化作一个个数据,一个个指令加上设备信息,文件描述符。这些加起来的集合,就是进程。
容器运行起来,本质上也是程序,也是进程。而容器技术”边界””隔离”的效果,实质上是对进程做各种限制。核心实现的方法namespace,cgroups.
NameSpace(限定进程所能看到的地方)
首先明白的一件事是:进程他能控制系统的什么?
进程有pid,有网络network,有文件, 在一个系统内,进程之间在权限允许的条件下是可以相互通信和操作的。假设一个进程能够在启动运行10s之后终止其他的进程,那是很恐怖的事情! 而namespce就是给进程限定了其视野范围 ,不同namespace限定的视野功能不一样,有限制PID 的namespace ,有限制文件的namespce ,有限制网络和rpc的namespace 。
这些namespace的存在则能够使进程在自己看得到的地方,构建自己的小世界。即在容器进程启动的时候,限制进程能看到的资源,文件,设备信息,配置等。
cgroups (限制进程所能走的路)
容器并不像虚拟机一样,容器内部的Application依然跑在宿主机的操作系统上。比如node 获取系统核心数的api.其获取的依然是操作系统的核心参数,因为应用的进程依然属于宿主机。 namespace的隔离能力并不是万能,很多系统资源并不受限!!!!
多个容器公用操作系统内核,这就意味着,一个应用如果消耗系统的资源过大,会影响到其他的容器的Application,假设有一个容器程序死循环,其吃了系统内核大部分的cpu和内存,则饿死了其他容器的进程!
Cgroups则可以限制包括CPU,内存,磁盘,网络带宽等资源的上线.
linux系统基于文件,而cgroups也以文件的形式,记录于/sys/fs/cgroup,比如cpu,memory都是可以被限制的资源种类:
在资源种类之下,有着该资源种类能被限制的配置(文件接口),比如cpu下,有着cfs_period,cfs_quota这两个可以操作进程cpu占用时间的配置:
假设我想给我的一个进程加上cpu只能占用20% 的限制 ,如何做?
建造资源控制的对象。
cd /sys/fs/cgroup/cpu
mkdir cgrouptest
cd cgrouptest
ls
这时候你会发现/sys/fs/cgroup/cpu/cgrouptest 文件下面自动生成了关于cpu资源的配置文件。
配置资源以及添加限定任务(进程,进程组),假设我们已知进程1999 .
echo 20000 > /sys/fs/cgroup/cpu/cgrouptest/cpu.cfs_quota_us
// 默认100000us的cpu时间里。限定对象只能使用20000us
echo 1999 > /sys/fs/cgroup/cpu/cgrouptest/tasks
// 设置任务限定对象进程1999
问题来了,容器相关的资源配置在哪里?
假设系统内部已经有运行的容器了,以我截图为例,系统目前存活的两个容器:
进入/sys/fs/cgroup/cpu/docker/,我们发现其下面有这两个容器的资源限定配置。
这里做出一个疑问,在配置资源组在面配置子资源,其限定的资源是否是继承关系?因为在/sys/fs/cgroup/cup/docker 下面新建容器的资源组。都具有自动生成的配置。
这样cgroup就算是能给容器又加上一道限定,限定其能使用的资源。
当然cgroup还是不能完美的解决,比如之前的node获取核心数的api.即使有cgroup的存在,依然不能够正确的获取容器信息。因为存放系统内核/proc的文件并不能被cgroup识别,哪些是我要的!!!
容器镜像
容器镜像。