天天看点

容器技术学习渐进——容器和虚拟机的区别(一)

从开始接触并学习容器,至今已经数年。在离开技术运维团队支持的情况下,叔独自摸索,偶然拾起了容器技术,一头扎进里面,慢慢学习,逐步部署应用。在这个过程中发现问题,解决问题,精进学习,管中窥豹。回顾这个学习过程中犯过的概念性错误、走过的弯路、掉过的坑,有趣且转折。且抽空记录在此,供初学者们借鉴。

如果在学习容器技术之前,未接触过虚拟化技术,那么恭喜你,你不太容易产生概念混淆,会比较容易地融入容器世界。当然,这不符合我的状况。事实是,在接触容器之前,基于XEN、KVM,我们深入研发了一套弹性计算平台,并基于这个平台发布了我们自己的虚拟桌面和虚拟服务器系统多年,虚拟化的概念已经深入骨髓。

容器技术跟虚拟化技术有共同点也有差异。最容易看到也让人产生兴趣的,是它们的共同点:计算单元隔离。基于对这个需求的理解,也很容易让初学者觉得使用容器很容易上手。

所以,容器技术“速成”后,叔并没有花时间深入去了解这种差异。叔最喜欢做的一件事,就是启动一个目标操作系统的容器,比如CentOS7.9的容器,然后在这个容器里面装上SSHD,使用Yum在这个容器里面安装各种服务比如nginx、mysql、redis、mqtt等等。这简直是对虚拟化的应用模式的完整复制。

docker run -d --name="server1" --entrypoint="/sbin/init" centos:centos7.9.2009
docker exec -it -uroot server1 /bin/bash
yum install -y net-tools mysql openssh openssh-server           

这个阶段并未真正去理解上面命令行中的entrypoint的意义,知道通过这个方式可以得到一个完全隔离的操作环境,然后在上面安装和部署需要的服务和应用,这就够了。但是看到运行中日益庞大的容器文件系统,以及容器内数量渐增的系统进程数量后,隐隐觉得这样不对。

于是产生了一个灵魂拷问:如果这样使用,为什么需要容器技术?它跟虚拟化技术到底有何差异?

先回顾一下虚拟化技术。

虚拟化技术(不管是半虚拟化还是全虚拟化)是从硬件层开始构建,从用户视角构建了一台虚拟存在的PC:它具备BIOS,具备独立的CPU、内存、硬盘、网卡、声卡、USB外设等等你在普通PC上可以看到的一切。用户通过虚拟化软件操作这台PC,控制它的启动和停止,将安装介质挂载到它里面进行操作系统安装;在装好的操作系统里面安装和操控各种应用;管理这台机器的网络模式,可以让它在宿主机所在的网络里看起来就是一台真实存在的PC设备。

为了达成这些目的,虚拟化技术需要硬件的支持,主板和CPU必须支持虚拟化。Intel CPU 的虚拟化技术叫做 Intel Virtualization Technology (VT-x),AMD CPU 的虚拟化技术叫做 AMD Virtualization (AMD-V)。使用时,需要进入主板的BIOS设置内,确认上述选项的支持和开启。

虚拟化技术让用户将一台物理上的宿主机,灵活地分割成多台虚拟但又真实存在的”虚拟机“,这些虚拟机之间互相之间从操作系统层就完全隔离。所以,每个虚拟机内可以安装互不相同的操作系统,比如Windows、Android、MacOS、FreeBSD、各种Linux等等,而这些操作系统并不需要与宿主机操作系统相同或者类似。虚拟机的操作系统拥有自己独立的完整的文件系统,它的文件系统可以是宿主机上的一个独立存在的文件,也可以是宿主机上的一个独立分区,当然,它也可以共用宿主机的分区和文件系统——这种模式下需要非常小心,这个不是虚拟机技术的典型应用模式。

虚拟机的这种隔离带来的好处是,用户可以将需要分隔的服务分别部署到不同的虚拟机里面,而不需要考虑互相之间的进程级别的安全问题和干扰因素。虚拟机内的应用和服务的影响,被约束在虚拟机的框架之内。

从上面可以看到,由于每台虚拟机都拥有自己独立的”硬件“和”操作系统“,那么,”硬件层“和”操作系统层“就成了同一台宿主机上多台虚拟机额外消耗的资源。有没有一种技术,既能实现进程之间的隔离,又不需要独自虚拟化出一套单独的”硬件“和”操作系统“,只需要共用宿主机的硬件和操作系统呢?

容器技术生来就是解决上述问题的。

容器技术在容器内共用了宿主机的硬件和操作系统内核,仅仅在操作系统之上、应用及服务之下,构建了简单的一层操作环境(比如文件系统、环境变量、操作系统差异),仅仅用于满足容器本身运行的应用或者服务所需。通过容器技术,将宿主操作系统的公用操作系统进程、文件系统、操作系统API接口等等,映射到容器内,实现了节约资源的同时又隔离进程运行空间的目的。

看到这里,玩过FreeBSD的同学可能很自然就会想起一个技术:jail。Jail内完整模拟了一个宿主机的操作系统操作环境,从操作体验上看,Jail更接近虚拟机,它有完整的宿主操作系统操作体验。使用Jail时,一般会登录到Jail内,通过shell操作Jail内资源和应用。但是容器技术比Jail节约的更纯粹。

容器技术可以仅仅只保留应用和服务必须的那部分宿主操作系统资源依赖,从宿主文件系统中继承来的文件系统中裁剪掉其他不需要的库和资源。如果需要,用户甚至可以把容器当成宿主机内的一个独立进程来对待——这就是容器的entrypoint的意义——它并不需要自己独自的shell,用户可以在宿主机上通过容器命令直接操作容器内的文件、日志、进程。只有体会了这一层,才能完整理解容器技术跟虚拟化技术的差异和应用精髓,才不会再在CentOS或者Ubuntu或者Debian的容器里面部署多个应用。

当然,在单独的CentOS等操作系统容器内部署关联应用和服务,也可以是容器的一种应用模式,结合容器的嵌套技术,完全可以通过在容器内嵌套运行容器的方法来达成:https://blog.csdn.net/mycosmos/article/details/126247521 。

继续阅读