容器其实是一种沙盒技术。这样应用与应用之间因为有了边界不会互相干扰。
- 容器的核心功能,就是通过约束和修改进程的动态表现,从而为其创造出一个边界
- Cgroups 是用来制造约束的主要手段
- Namespace 是用来修改进程视图的主要方法
对于宿主机,这些被“隔离”的教程(容器)和其他教程没有太大的区别
-
需要注意
- 容器是共享宿主机内核
- 在 Linux 内核中,有很多资源和对象是不能被 Namespace 化的,最典型的例子就是:时间。
-
Linux Cgroups就是Linux内核用来为进程设置资源限制的一个重要功能
-
容器是『单进程』模型,只有 PID=1 的进程才会被 Dockerd 控制,即 pid=1 的进程挂了 Dockerd 能够感知到,但是其它的进程却不受 Dockerd 的管理,当出现孤儿进程的时候,管理和调度是个问题
Docker核心原理是为待创建的用户进程
-
- 启用 Linux Namespace 配置
-
- 设置指定的 Cgroups 参数
-
- 切换进程的根目录(Change Root)
docker创建镜像时没有使用rootfs的标准流程,而是使用了layer层。
layer记录是增量的rootfs
容器的本质是一个进程,只不过这个进程加上了视图上的隔离和资源上的限制。 就容器本质而言,它并没有在宿主机上启动一个“容器进程”,它启动的还是用户原来要启动的应用程序,只不过这个应用程序上加了视图隔离和资源限制。虚拟机也能实现视图隔离和资源限制,但它底层的技术实现与容器不同,在宿主机上你能看到这样一个“虚拟机进程”。因此,与容器相比,虚拟机会带来更多的性能损耗,主要在(1)虚拟机本身的进程需要占用一部分资源 (2)与底层硬件交互的时候(网络、磁盘I/O)都需要经过虚拟化软件拦截,会有损耗。但是它比容器有更好的隔离性和安全性。
容器使用的底层技术:
- (1)视图隔离:Namespace
- (2)资源限制:cgropus
对于Docker项目来说,它最核心的原理实际就是为待创建的用户进程:
- 1、启用Linux Namespace配置:视图隔离
- 2、设置指定的Cgroups参数:资源限制
- 3、切换进程的根目录(Change Root):容器镜像生效,以实现环境一致性。所谓容器镜像,本质就是容器的根文件系统(rootfs)。
Docker容器的增量rootfs:即下层已经生成的永远不会改变,所有的修改都通过在上层叠加。比如,删除A文件,就是在上层添加一个“白障”,让系统无法读取到下层A文件。修改则是先copy一个备份到新的层(新老的文件可能都在可读写层),然后读取的时候直接读取新的层。
Docker通过Volume来实现将宿主机的文件挂载到容器中
一个“容器”,实际上是一个由 Linux Namespace、Linux Cgroups 和 rootfs 三种技术构建出来的进程的隔离环境。
从这个结构中我们不难看出,一个正在运行的 Linux 容器,其实可以被“一分为二”地看待:
- 一组联合挂载在 /var/lib/docker/aufs/mnt 上的 rootfs,这一部分我们称为“容器镜像”(Container Image),是容器的静态视图;
- 一个由 Namespace+Cgroups 构成的隔离环境,这一部分我们称为“容器运行时”(Container Runtime),是容器的动态视图。
Kubernetes 本质就是为用户提供一个具有普遍意义的容器编排工具