先来笼统地看一下
1、环境一致性
众所周知,开发过程中一个常见的问题是环境一致性问题,由于开发环境,测试环境,生产环境不一致,导致有些bug并未在开发过程中被发现,而Docker的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性。
所以Docker将所有的环境进行了打包,注意这个"包"是除了内核外的所有环境,所以有些人说Docker连操作系统都给你包进去了其实不准确,操作系统最核心的内核依然是和宿主机共享。
**面试官追问:**如果仅仅只是做一个环境的隔离,那么虚拟机不就可以完成这件事吗?为什么还要你Docker呢?那么就请看我们的第2点,资源利用率
2、资源利用率
"面试官有所不知,虚拟机这家伙笨重如牛,体积又大,动不动就是以G为单位的大小,因为它里面要运行一个完整的操作系统 ,所以跑起来格外费劲,慢就不说了,还非常占资源,一台机器上跑不了几台虚拟机就把性能拖垮了!而Docker想要做一个轻量级的虚拟容器,只提供一个运行环境,不用运行一个操作系统,所有容器中的系统内核还是和外面的宿主机共用的,这样就可以批量复制很多个容器,轻便又快捷"
**面试官追问:**那你把Docker说的那么好,实现起来又谈何容易。比如隔离就不是那么好做的,你知道其中的原理吗?
接下来请看我们的第3点,隔离性与安全性
3、隔离性与安全性
3.1、文件隔离
首先需要做的就是文件资源的隔离,容器内部肯定要将一个容器的文件环境和外部宿主机的文件环境隔离开来,所以Docker解决这个问题用到了Chroot & pivot_root
他们俩都是做文件隔离的"利器",对于Docker容器运行的进程,使得进程只能看到指定目录及其子目录中的文件。
3.2、资源隔离
文件隔离解决了,但是就做到了完整的隔离吗?Docker心里清楚,自己虽然叫容器,但这只是表面现象,容器内的进程其实和自己一样,都是运行在宿主操作系统上面的一个个进程想要遮住这些进程的眼睛,瞒天过海,实在不是什么容易的事情。
比如进程列表、网络设备、用户列表这些,是决不能让容器中的进程知道的,得让他们看到的世界是一个干净如新的系统。
解决这一问题主要就是用到namespace
namespace为每个容器提供了一个独立的、隔离的视图,使得容器内的进程、网络、文件系统等资源彼此隔离。
3.3、资源管理
隔离倒是解决完毕,也能实现功能了,那么长期使用会不会产生什么问题呢?
分析一下:由于容器内的环境启动起来也是一个进程,是和宿主机共享了内核,那么对于CPU、网络、硬盘等资源那也是共享的同样硬件资源,假设Docker容器占用了很多资源(一直占用CPU不释放),那不就给宿主机造成了极大的影响了吗
所以必须要对Docker容器内的进程加以管控、这时候就用到了CGroups (控制组)
控制组是 Linux 内核的一个功能,用于限制、记录和隔离进程组使用的物理资源(如 CPU、内存、磁盘 I/O 等)。cgroups 可以确保单个进程或一组进程不会耗尽整个系统的资源,从而提高系统的稳定性和性能。
到此,这道面试题基本分析完毕,其他的几个点各位码友参考文章开头或自行查阅吧~