01 容器技术介绍

容器技术介绍

docker是一种容器技术,容器技术可以理解为一种轻量级虚拟化方案,那么什么是虚拟化,什么是容器,它们是为了解决什么问题而诞生的呢,发展历程是什么?带着这些疑问让我们往下看

一 容器技术的由来

物理机部署软件已经很好了,为何要有虚拟化,为何要有容器?

~~~这便引出了虚拟化的发展历程

1、没错,物理机部署应用是可以的,
但为了花的钱值,一台服务器利用率必须提高(买来一台机器,有非常多cpu内存资源,但你一天24小时只用了10%不到,仔细想想是不是亏钱了,最好能用到80% 那你花钱买的这么多配置才算真的值)
怎么提高?那就是把这台服务器的cpu内存硬盘等都利用起来,怎么利用?
多跑一些应用行不行,肯定可以啊,
于是一台服务器上开始跑了很多应用,几十个上百个的跑

此时,服务器利用率确实也上去了

某一天突然服务器宕机了,完犊子了,这上百个服务一起挂掉了

大家突然明白过来,不能把所有应用不加区分地都扔到一台服务器上,鸡蛋都在一个篮子里,要碎就全碎了,应该做到不同的服务彼此隔离,怎么做呢?

难道还是分离出专门安装数据库应用的服务器,专门装负载均衡的服务器…这种方法当然可以做到隔离、彼此不干扰,

但这岂不是不又回到最开始的问题:单台服务器上运行的应用少导致利用率不足?禁止套娃

2、总结下现在的需求
(1)把单台物理服务器的利用率提上去
(2)把应用分散到不同的服务器(这个服务器不一定要是物理服务器,只要与别的应用隔离开就行)

为了同时满足上述两个需求,于是诞生了虚拟化技术,例如win下的vmware workstation,linux下的kvm,还有esxi、xen等

虚拟化技术可以在单台物理机的操作系统上虚拟出多台虚拟的机器,以此达到隔离的目的(运行在每个虚拟机里的应用肯定互相隔离的,此时一台虚拟机挂掉了肯定不会影响另外一台),同时因为多台虚拟机都寄生在物理机上,所以物理机的利用率也提升了上来

3、但后来大家发现,虚拟机太繁重了,不够轻量级,再次复述一下我们的当初的诉求就是两个
(1) 隔离,应用认为自己是运行在自己独有的空间里,不与其他应用相互影响。
(2) 把单台物理机的利用率提升上去

大家思来想去,利用虚拟机达到上述目标太繁重了,冷静下来仔细分析一下,虚拟机隔离的是什么?不同的虚拟机隔离的关键部分在于它们彼此有各自独立的磁盘、主机名、IPC、PID、网络、用户等,既然是这样那有没有什么方法可以抛弃虚拟机的实现,采用更轻量级的方法去实现这些隔离呢?

咦?等等,进程的内存空间不是天生就彼此隔离的吗,但其进程之间的其他资源都是共享的,比如硬盘,网络等,所以如果我们可以在进程内存隔离的基础上,通过技术手段让一个进程的网络空间、硬盘空间、pid等与其他进程隔离开,那此进程不达到了虚拟机一样的隔离效果了吗!而且这可是一个进程啊,启动一个进程,与启动一台虚拟机,你猜猜哪个更轻量级!!!

强调:要区分好共享与隔离的概念
一、我们此处所说的共享与隔离的概念,指的都是在使用时,而不是申请时。
1.1、申请时
在虚拟化大背景下,一台物理机的资源对寄生在它身上的虚拟机或容器都是公共的,大家都可以去申请,这叫申请时大家是共享的。
1.2、使用时
针对申请到的资源,如果A申请到的,B同样可以对其进行读写,那就代表这一申请到的资源是共享的
如果A与B申请到的资源,各自的读写互不干扰,那就是隔离的
我们谈到的隔离指的就是这一使用时的概念,即申请时都去物理机申请,而使用时则互不干扰

二、如何理解进程的内存空间隔离,磁盘共享呢?
首先你要知道,在申请时,物理机的所有资源对进程们都是公开的,也就说在资源的申请上,大家是共享的。

如何理解进程的内存空间是隔离的呢?多个进程都去申请物理机的物理内存,但是申请到一块内存之后,只要不释放,其他进程便无法对该内存进行读写,这就是隔离,即在内存的使用上,进程之间默认隔离。

那么为何说默认进程的磁盘空间是共享的呢?我们操作磁盘都是通过文件,一个文件映射到一块磁盘空间,进程A打开一个磁盘文件a.txt进程读写,进程B同样可以对a.txt进行读写,所以在磁盘的使用上,进程之间默认是共享的。

有人会说,隔离你是实现了,那操作系统怎搞,虚拟机里可以安装自己独有的操作系统,但是你怎么让一个进程里有自己独立的操作系统?其实道理都一样啊,虚拟机里可以安装操作系统,而操作系统来源于系统镜像,所以,我们完全可以仿照操作系统镜像制作类似的容器的镜像,然后把容器镜像内容“放”到进程里,这个进程也就有了操作系统,理论上完全行得通,没错,就是这个样子。

围绕上述需求有人开发了一款软件,并将该软件命名为docker,值得说一嘴的是,类似的技术早就有了比如lxc,docker也只是在它的基础上发扬光大。

所以启动一个容器其实就是启动一个进程,该进程与普通进程不同的是,该进程出了内存空间与其他进程隔离之外,该进程内可以拥有自己的root文件系统、自己的网络配置、自己的进程空间、甚至自己的用户ID,所以其使用起来,就好像在一个独立于宿主的系统下操作一样。

另外一点,容器的轻量级带来了另外一个优点的大幅度提升,就是可迁移性,一次打包到处使用(之前的虚拟机方案当然也可以,但打包一个虚拟机数据量太大了,动不动十几个g,而打包一个容器就少很多了,少的几十m就行)

二 容器技术的三大核心

上一小节,我门提高到了容器技术的产生背景,说白了就是追求一个轻量级的虚拟化方案,来达到隔离的目的(同时提高硬件利用率),这个空间隔离就是容器技术的第一个核心技术:namespace名称空间

此外需要注意的是,光有隔离还不够,因为空间隔离之后,多个容器寄生在一台机器之上,虽然你们是隔离的,但归根结底都是在共用或者说共同消耗该物理主机的硬件资源,比如内存,如果不加以限制,当内存不足时会触发linux的OOM机制,杀掉一些进程。为了解决这个问题,于是容器技术在隔离的基础之上引入来cgroup机制,来对资源进行限制(包括磁盘、cpu等资源)

还有就是上一小节我们提及,一个容器的启动需要有一个容器镜像,容器的镜像与操作系统的镜像还是有很大区别的,系统镜像的主要构成是bootfs(包含内核)+ rootfs,而容器镜像里没有bootfs内存相关、只有一个rootfs,而且容器的rootfs文件系统并非传统文件系统ext4、xfs等,而是一种采用一种联合文件系统技术称之为UnionFS,该技术会在启动时把容器镜像挂载到(而不是拷贝到)容器里使用的。UnionFS是一个技术概念而不是某一种具体的技术,多个目录联合挂载到同一个目录下,我会在后续介绍容器镜像时详细讲解该技术。

总结,容器技术有三大核心

  • 1、namespace名称空间:保证容器之间的运行环境(使用时资源)互相隔离,彼此互不影响
    linux内核2.4.19引入namespace,是内核强大的特性
    可以使每个进程看起来都拥有自己的隔离的全局系统资源,即每个进程都有自己的命名空间
    每个进程中运行的应用程序都像是运行在一个独立的系统中一样

  • 2、cgroup机制:限制资源使用

    容器的本质就是进程,多个进程不受限制地占用系统资源,如cpu、磁盘、内存、网络等
    当某个进程占用过多资源,以致于将主机系统资源耗尽时,linux内核会触发OOMout of memory killer机制
    OOM会在系统内存耗尽的情况下跳出来,选择性的干掉一些进程以求释放一些内存)这会让一些被杀掉的进程成了无辜的替死鬼,
    因此为了让容器中的进程更加可控,
    Docker使用Linux cgroups来限制容器中的进程允许使用的系统资源 Linux Cgroup可以让系统中所运行任务(进程)的用户定义组分配资源,比如CPU时间、系统内存、网络带宽

  • 3、UnionFS联合文件系统:镜像、分层挂载

    UnionFS顾名思义,可以把主机文件系统上多个目录(分支)内容联合挂载到同一个目录下,而主机上文件系统的多个目录的物理位置是分开的,这可以让多个容器进程共享同一份镜像,而不是向传统虚拟化那样每台vm都有一个完整的操作系统,把轻量级追求到极致。

所需后续我们深入研究容器,必须要研究明白上述三大核心。

三 容器VS虚拟机

docker是容器技术的一种,docker也称之为docker守护进程、docker引擎,可以创建出容器(下图中docker守护进程上层的bins/libs与app代表的就是容器里的内容),容器与虚拟机类似,但是更轻量级,架构如下

1、虚拟机架构
    app
    Bins/Libs文件系统及可执行命令+依赖库
    Guest os虚拟机操作系统
    Hypervisor虚拟机管理系统
    主机操作系统
    计算机硬件

2、docker容器架构
    app
    Bins/Libs文件系统及可执行命令+依赖库
    docker守护进程
    主机操作系统
    计算机硬件

3、当然了,docker也可以运行在虚拟机操作系统,即Guest os中,如下架构
    app
    Bins/Libs文件系统及可执行命令+依赖库

    ===》docker守护进程《===

    Guest os虚拟机操作系统
    Hypervisor虚拟机管理系统
    主机操作系统
    计算机硬件

总结虚拟机与容器的区别:

  • 1、容器适用场景更广

    虚拟机里通常不会再跑虚拟机(即便支持,那也会因为虚拟机的繁重拉胯效率),但是虚拟机里可以继续跑容器

    虚拟化技术依赖的是物理CPU和内存,是硬件级别的;

    而我们的Docker是构建在操作系统层面的,利用操作系统的容器化技术,是进程级别,所以Docker同样的可以运行在虚拟机上面

  • 2、容器更加轻量级

    一个虚拟机需要具备三要素:虚拟硬件、bootfs、rootfs,而一个容器的启动只需要有一个rootfs,那什么是bootfs与rootfs呢?

    虚拟机操作系统来源于操作系统镜像,操作系统镜像由bootfs(包含系统内核)与rootfs(bin目录、etc目录、home目录等一系列目录)构成

    容器中的“操作系统“源自于容器的镜像,该镜像只包含了rootfs(rootfs就是容器镜像),所以容里是没有操作系统内核的。

    总结容器不需要虚拟硬件、不需要安装操作系系统,只有一个rootfs,所以更加轻量级。

    ps:容器内只有rootfs相当于欺骗了上层的应用,上层的应用看到rootfs的内容还以为自己就工作在操作系统之上。

    此外,在传统的虚拟化技术是通过快照来保存的;而Docker引用了类似于源码的管理机制,将容器的快照历史版本一一记录下来。

  • 3、容器可移植性/跨平台性更强

    容器本质就是一个进程,不依赖硬件,只要硬件之上的操作系统支持docker容器技术,那么容器就可以跑起来,所以其可移植性强,但是虚拟机依赖硬件,可移植性差

    补充:
    对于linux系统,不同的发行版bootfs基本一致,主要不同就是rootfs,也就是容器镜像,所以如果一个容器的镜像打包的是linux系统的rootfs,那么它可以在不同的发行版上运行良好,别问能不能在windows上跑这么愚蠢的问题,当然不能了,你心里反复默读几遍,linux系统=bootfs+rootfs,容器镜像打包的是rootfs,windows系统的内核与linux的bootfs肯定不一样啊。当然你如果在windows系统里装个虚拟机工具vmware workstation然后创建出一台虚拟机装个linux系统,然后在这个linux系统里跑我们的此处提到的容器,那么肯定是可以跑起来的。

    传统的虚拟化技术在构建系统的时候非常复杂;而Docker可以通过一个简单的Dockerfile文件来构建整个容器,更重要的是Dockerfile可以手动编写,这样应用开发人员可以通过发布Dockerfile来定义应用的环境和依赖,这样对于持续交付非常有利

接下来egon按照这个顺序进行讲解

1、容器三大核心技术之namespace

2、容器三大核心技术之容器镜像与UnionFS

3、docker部署配置、常用操作、镜像制作、网络等

4、容器三大核心技术之cgroup

5、容器技术深入

上一篇
下一篇
Copyright © 2022 Egon的技术星球 egonlin.com 版权所有 帮助IT小伙伴学到真正的技术