深入剖析Kubernetes之容器化的基础
容器化的基础之进程管理
容器化的基础是依赖于Linux底层提供的两种能力分别是cgroups,Namespace
cgroups
cgroups 的全称是control groups,是Linux内核提供的一种可以限制单个进程或者多个进程所使用资源的机制
cgroups可以管理的资源有:
- cpu子系统
主要限制进程的cpu使用率 - cpuacct子系统
可以统计cgroups中的进程的cpu使用报告 - cpuset 子系统
可以为cgroups中的进程分配单独的cpu节点或者内存节点 - memory子系统
可以限制进程的
可以限制进程的块设备 io - devices子系统
可以控制进程能够访问某些设备 - net_cls子系统
可以标记cgroups中进程的网络数据包,然后可以使用tc模块(traffic control)对数据包进行控制 - freezer子系统
可以挂起或者恢复cgroups中的进程 - ns子系统
可以使不同cgroups下面的进程使用不同的namespace
cgroups是通过与内核的其他模块来完成进程维度对资源的管理
Namespace
namespace是对内核资源进行分组管理的一个特性,用来修改进程间的可见性
namespace创建进程时会使用CLONE_NEWPID这个参数来创建一个新的进程空间
虚拟机与Docker的区别
虚拟机与Docker的区别在于虚拟机会采用硬件虚拟化功能,模拟出操作系统底层的设备;docker只是在宿主机上做了进程隔离和资源隔离
容器化的基础之隔离和限制
通过namespace来完成进程之间的隔离,通过cgroups来完成对资源的限制
cgroups是通过配置在/sys/fs/cgroup文件夹下会有
-
资源分组
这些限制项来进行处理 -
控制组
通过详细信息可以看到这个目录下有不同的配置文件cgroup.procs,内容如下展示
可以看到这里记录的就是pid列表,
docker就是在创建容器的时候为每一个容器创建一个控制组,在将用户指定的docker容器初始化资源配置写入控制组中就可以了
cgroups采用的资源限制方式主要是通过控制时间的形式来实现的,因此就会存在容器的进程实际上可以看到整个宿主机的一些状态.这是相较与虚拟机方式的不足
容器的本质就是一个特殊的进程
容器中镜像的概念
镜像指的是一个由容器识别的只读模板.通常这个模板是基于另外的一个模板并进行一些自定义改动的
以上是docker官网中对镜像概念的描述,镜像在物理上指的是容器进程实际可用的文件
通过Namespace和cgroups实现了对进程和操作时间的隔离,但是容器之间没有对文件的隔离,容器进程的可用文件与其他用户进程的可用文件相同.
因此需要对容器的可用文件进行限制,在docker上是优先使用pivot_root,其次使用chroot
pivot_root与chroot的区别
-
pivot_root改变当前mount namespace的rootfs("/"目录)
-
chroot改变的是当前进程的rootfs("/"目录)
pivot_root的执行步骤分为三步:
- 创建临时目录并将当前所有的root mount移动到临时目录
- 创建新目录(“/”)
- 清理新目录
rootfs
rootfs指的是就是镜像中的文件,也就是登录到具体的镜像中看到的文件.rootfs在结构上可以分为三层可读写层、
init层、只读层
从上到下分别是应用层到系统层的划分,在详细的对这三层进行分析之前需要了解一下为什么镜像文件中分层的文件在使用的时候可以想在同一个文件夹中一样?
这是采用了一种被称为联合文件系统(union file System)概念,docker中默认是使用Overlay2的实现,关于联合文件系统的文章看可以参考
https://lwn.net/Articles/324291/
-
可读写层
可读写层是rootfs中最上面的一层,是承载容器中文件读写的操作一层,在这一层中的挂载方式是read + write -
init层
init层指的是Docker项目用来存放对底层操作系统的改动信息例如’etc/hosts’、‘etc/resolv.conf’等,因为容器在启动时可以手动指定。init层在挂载时是采用’ro’ + 'wh’的方式,'ro’指的是read onley,'wh’指的是whiteout,即只读 + ‘whiteout’,whiteout指的是对文件的操作会在通过一定的手段进行隐藏,类似与java中的临时变量的概念,只在当前容器中有效,不会真正的修改底层的文件 -
只读层
只读层指的是镜像中最底层的系统镜像层,它们的挂载方式也是’ro’ + ‘wh’
总结
docker中的镜像通过这种分层构建的方式大大的减少了传统镜像中操作系统的大小,只包含了可读写层中应用的部分。底层支持这种构建方式主要是依赖chroot(切换根目录的能力)和union file System(联合文件系统)
总结
docker容器化的基础是三个部分
- Namespace提供的进程隔离能力
- Cgroup提供的资源限制能力
- rootfs的文件分层结构设计
clone(true)/cgroup file/union file System