系列文章目录
【Kubernetes 入门实战课】Day01——虚拟机创建及安装
【Kubernetes 入门实战课】Day02——初识容器
文章目录
- 系列文章目录
- 前言
- 一、容器到底是什么?
- 二、为什么要隔离
- 三、与虚拟机的区别是什么
- 四、隔离是怎么实现的
前言
`上一节中我们完成了在Linux虚拟机中安装了当前最流行的容器Docker,并使用了Docker的一些基础命令进行了简单的操作容器,使得我们对容器有了一定的认识。今天我们就深层次的了解一下什么是容器?
一、容器到底是什么?
从字面上来看,容器就是 Container,一般把它形象地比喻成现实世界里的集装箱,它也正好和 Docker 的现实含义相对应,因为码头工人(那只可爱的小鲸鱼)就是不停地在搬运集装箱。
集装箱的作用是标准化封装各种货物,一旦打包完成之后,就可以从一个地方迁移到任意的其他地方。相比散装形式而言,集装箱隔离了箱内箱外两个世界,保持了货物的原始形态,避免了内外部相互干扰,极大地简化了商品的存储、运输、管理等工作。
再回到我们的计算机世界,容器也发挥着同样的作用,不过它封装的货物是运行中的应用程序,也就是进程,同样它也会把进程与外界隔离开,让进程与外部系统互不影响。
我们还是来实际操作一下吧,来看看在容器里运行的进程是个什么样子。
首先,我们使用 docker pull 命令,拉取一个新的镜像——操作系统 Alpine:
然后我们使用 docker run 命令运行它的 Shell 程序:
[root@bogon ~]# docker run -it alpine sh
注意我们在这里多加了一个 -it 参数,这样我们就会暂时离开当前的 CentOS操作系统,进入容器内部。
现在,让我们执行 cat /etc/os-release ,还有 ps 这两个命令,最后再使用 exit 退出,看看容器里与容器外有什么不同:
也就是说,在容器内部是一个全新的 Alpine 操作系统,在这里运行的应用程序完全看不到外面的 CentOS 系统,两个系统被互相“隔离”了,就像是一个“世外桃源”。
结论:容器,就是一个特殊的隔离环境,它能够让进程只看到这个环境里的有限信息,不能对外界环境施加影响。
二、为什么要隔离
对于 Linux 操作系统来说,一个不受任何限制的应用程序是十分危险的。这个进程能够看到系统里所有的文件、所有的进程、所有的网络流量,访问内存里的任何数据,那么恶意程序很容易就会把系统搞瘫痪,正常程序也可能会因为无意的 Bug 导致信息泄漏或者其他安全事故。虽然 Linux 提供了用户权限控制,能够限制进程只访问某些资源,但这个机制还是比较薄弱的,和真正的“隔离”需求相差得很远。
而现在,使用容器技术,我们就可以让应用程序运行在一个有严密防护的“沙盒”(Sandbox)环境之内,就好像是把进程请进了“隔离酒店”,它可以在这个环境里自由活动,但绝不允许“越界”,从而保证了容器外系统的安全。
除此之外,使用容器技术还可以节约计算机的各种资源,使得在系统里面切分出一部分资源,让容器能够使用指定的配额。保证了整个系统的安全,而且只要进程遵守隔离规定,不做什么出格的事情,也完全是可以正常运行的。
三、与虚拟机的区别是什么
其实容器和虚拟机面对的都是相同的问题,使用的也都是虚拟化技术,只是所在的层次不同,我们可以参考 Docker 官网上的两张图,把这两者对比起来会更利于学习理解。
首先,容器和虚拟机的目的都是隔离资源,保证系统安全,然后是尽量提高资源的利用率。
之前在使用 VirtualBox/VMware 创建虚拟机的时候,你也应该看到了,它们能够在宿主机系统里完整虚拟化出一套计算机硬件,在里面还能够安装任意的操作系统,这内外两个系统也同样是完全隔离,互不干扰。
而在数据中心的服务器上,虚拟机软件(即图中的 Hypervisor)同样可以把一台物理服务器虚拟成多台逻辑服务器,这些逻辑服务器彼此独立,可以按需分隔物理服务器的资源,为不同的用户所使用。
从实现的角度来看,虚拟机虚拟化出来的是硬件,需要在上面再安装一个操作系统后才能够运行应用程序,而硬件虚拟化和操作系统都比较“重”,会消耗大量的 CPU、内存、硬盘等系统资源,但这些消耗其实并没有带来什么价值,属于“重复劳动”和“无用功”,不过好处就是隔离程度非常高,每个虚拟机之间可以做到完全无干扰。
容器(即图中的 Docker),它直接利用了下层的计算机硬件和操作系统,因为比虚拟机少了一层,所以自然就会节约 CPU 和内存,显得非常轻量级,能够更高效地利用硬件资源。不过,因为多个容器共用操作系统内核,应用程序的隔离程度就没有虚拟机那么高了。
运行效率,可以说是容器相比于虚拟机最大的优势,在这个对比图中就可以看到,同样的系统资源,虚拟机只能跑 3 个应用,其他的资源都用来支持虚拟机运行了,而容器则能够把这部分资源释放出来,同时运行 6 个应用。
四、隔离是怎么实现的
我们知道虚拟机使用的是 Hypervisor(KVM、Xen 等),那么,容器是怎么实现和下层计算机硬件和操作系统交互的呢?为什么它会具有高效轻便的隔离特性呢?
其实奥秘就在于 Linux 操作系统内核之中,为资源隔离提供了三种技术:namespace、cgroup、chroot,虽然这三种技术的初衷并不是为了实现容器,但它们三个结合在一起就会发生奇妙的“化学反应”。
namespace 是 2002 年从 Linux 2.4.19 开始出现的,和编程语言里的 namespace 有点类似,它可以创建出独立的文件系统、主机名、进程号、网络等资源空间,相当于给进程盖了一间小板房,这样就实现了系统全局资源和进程局部资源的隔离。
cgroup 是 2008 年从 Linux 2.6.24 开始出现的,它的全称是 Linux Control Group,用来实现对进程的 CPU、内存等资源的优先级和配额限制,相当于给进程的小板房加了一个天花板。
chroot 的历史则要比前面的 namespace、cgroup 要古老得多,早在 1979 年的 UNIX V7 就已经出现了,它可以更改进程的根目录,也就是限制访问文件系统,相当于给进程的小板房铺上了地砖。
你看,综合运用这三种技术,一个四四方方、具有完善的隔离特性的容器就此出现了,进程就可以搬进这个小房间,过它的“快乐生活”了。我觉得用鲁迅先生的一句诗来描述这个情景最为恰当:躲进小楼成一统,管他冬夏与春秋。