容器简介

什么是容器

一句话概括容器:容器就是将软件打包成标准化单元,以用于开发、交付和部署。

容器镜像是轻量的,可执行的独立软件包,包含软件运行所需的所有内容:代码,运行时环境,系统工具,系统库和设置。

容器化软件适用于基于Linux和Windows的应用,在任何环境中都能够始终如一地运行。

容器赋予了软件独立性,使其免受外在环境差异(例如,开发和预演环境的差异)的影响,从而有助于减少团队间在相同基础设施上运行不同软件时的冲突。

我觉得容器就是一个存放东西的地方,就像房子可以装各种家具,书架可以放各种书。我们现在所说的容器存放的东西可能更偏向于应用,比如网站,程序甚至是系统环境。

虚拟机和容器

虚拟机

虚拟机就是带环境安装的一种解决方案,他可以在一种操作系统里面运行另一种操作系统,比如在Windows系统里面运行Linux系统,应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。

虽然用户可以通过虚拟机还原软件的原始环境。但是如下缺点:

资源占用多

虚拟机会独占一部分内存和硬盘空间。他运行的时候,其他程序就不能使用这些资源了。哪怕虚拟机里面的应用程序,真正使用的内存只有1MB,虚拟机却需要几百MB的内存才能运行。一个系统一般只支持几十个虚拟机。

冗余步骤多

虚拟机是完整的操作系统,一些系统级别的操作步骤,往往无法跳过,比如用户登陆。

启动慢

启动系统需要多久,启动虚拟机就需要多久。可能要等几分钟,应用程序才能真正运行。

Linux容器

由于虚拟机存在这些缺点,Linux发展出了另一种虚拟化技术,Linux容器。

Linux容器不是模拟一个完整的操作系统,而是对程序进行隔离。或者说,在正常进程的外面套了一个保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。

由于容器是进程级别的,相比虚拟机有很多优势:

启动快

容器里面的应用,直接就是底层系统的一个进程,而不是虚拟机内部的进程。所以,启动容器相当于启动本机的一个进程,而不是启动一个操作系统,速度就快很多。

资源占用少

容器只占用需要的资源,不占用那些没有用到的资源;虚拟机由于是完整的操作系统,不可避免要占用所有资源。另外,多个容器可以共享资源,虚拟机都是独享资源。一个单机上支持上千个容器。

体积小

容器只要包含用到的组件即可,而虚拟机是整个操作系统的打包,所以容器文件比虚拟机文件要小很多。

两者对比

传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程,容器虚拟化的是操作系统而不是硬件,容器之间是共享同一套操作系统资源的。虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统。因此容器的隔离级别会稍低一些。

简单来说,容器和虚拟机具有相似的资源隔离和分配优势,但功能有所不同,因为容器虚拟化的是操作系统,而不是硬件,因此容器更容易移植,效率也更高。而容器的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更轻便。

容器是一个应用层抽象,用于将代码和依赖资源打包在一起。多个容器可以在同一台机器上运行,共享操作系统内核,但各自作为独立的进程在用户空间中运行。与虚拟机相比,容器占用的空间较少,瞬间就能完成启动。

虚拟机是一个物理硬件层抽象,用于将一台服务器变成多台服务器。管理程序允许多个VM在一台机器上运行。每个VM都包含一整套操作系统,一个或多个应用,必要的二进制文件和库资源,因此占用大量空间。而VM启动也非常缓慢。

什么是Docker

Docker是属于Linux容器的一种封装,提供简单易用的容器使用接口,他是目前最流行的Linux容器解决方案。

Docker将应用程序与该程序的依赖,打包在一个文件里。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了Docker,就不用担心环境问题。

总体来说,Docker的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。

Docker基本概念

Docker中有三个核心概念:Image、Container、Repository。

镜像(Image)

容器(Container)

仓库(Repository)

理解了这三个概念,就理解了Docker的整个生命周期。

镜像(Image):一个特殊的文件系统

操作系统分为内核和用户空间。对于Linux而言,内核启动后,会挂载root文件系统为其提供用户空间支持。而Docker镜像(Image),就相当于一个root文件系统。

Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。

分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。

和Windows的那种ISO镜像相比,Docker中的镜像的概念不会陌生。但是和Windows的那种ISO镜像相比,Docker中的镜像是分层的,可复用的,而非简单的一堆文件叠在一起(类似于一个压缩包的源码和一个Git仓库的区别)。

容器(Container):镜像运行时的实体

镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。前面讲过镜像使用的是分层存储,容器也是如此。

容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。

容器的存在离不开镜像的支持,他是镜像运行时的一个载体(类似于实例和类的关系)。依托Docker的虚拟化技术,给容器创建了独立的端口,进程,文件等空间,Container就是一个宿机隔离“容器”。容器可宿主机之间可以进行port,volumes,network等通信。

仓库(Repository):集中存放镜像文件的地方

镜像构建完成后,可以很容易地在当前宿主上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务。

一个Docker Registry中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。所以说:镜像仓库是Docker用来集中存放镜像文件的地方,类似于我们之前常用的代码仓库。

通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本 。我们可以通过<仓库名>:<标签>的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以latest作为默认标签。

Docker的仓库和Git的仓库比较相似,拥有仓库名、tag。在本地构建完镜像之后,即可通过仓库进行镜像的分发。常用的Docker hub有https://hub.docker.com/ 、 https://cr.console.aliyun.com/等。

Docker作用

多环境的部署切换

业务开发中往往需要区分开发环境与线上环境,利用Docker能原封不动的将开发环境中的代码与环境原封不动无污染的迁移到线上环境,配合一定的自动化流程即可实现自动的发布。

复杂环境一键配置

某些场景下可能会配一些超级复杂的环境,这个时候可以对Docker环境配置做封装,直接生成镜像,让大家低成本使用。

持续集成单元测试

类似于Travis CI这种。

同应用多版本隔离,文件隔离

比如这个项目依赖Java 7 ,那个项目依赖Java 8,同一个服务器上跑了100个程序,可以用Docker建立隔离开,防止互相传染。

云构建

同一个仓库下不同人开发往往会遇到不同的人使用不同的包版本,且自己根本不知道与别人不一样,最终导致发布之后产生线上问题。利用Docker可以在云端新建容器,远程无污染、低成本构建代码,实现不同人用的一定是同一个版本。

省钱

低成本安全超售。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐