当前位置 博文首页 > RtxTitanV的博客:Docker与容器的基本概念
本文主要对Docker和容器的一些基本概念进行一个总结。
Docker官方对容器的解释,一句话概括,容器(Container)就是将软件打包成标准化单元,以用于开发、交付和部署。容器是打包代码及其所有依赖的软件的标准单元,使应用可以从一个环境快速可靠地运行到另一个环境。容器镜像是轻量的、可执行的独立软件包 ,包含软件运行所需的所有内容:代码、运行时环境、系统工具、系统库和设置。容器化软件适用于基于Linux和Windows的应用,在任何环境中都能够始终如一地运行。容器赋予了软件独立性,将其与环境隔离开来,确保在例如开发和预演环境这种存在差异的环境中统一地运行。
容器也是一种用于打包应用(已编译)代码以及运行时所需依赖的技术。运行的每个容器可以重复,通过包含依赖项实现标准化意味着在任何环境运行容器都可以得到相同的行为。容器将应用与主机基础结构分离,使其在不同的云和操作系统环境部署更加容易。容器是不可变的,无法更改已运行容器的代码。如果一个容器化应用需要更改,则需要构建一个包含更改的新容器,从更新的镜像从新创建容器。
容器技术实质上是对系统资源的隔离和控制,使容器进程运行于属于自己的独立的命名空间(namespace)。容器可以拥有自己的文件系统、网络配置、进程空间等,容器内的进程是运行在一个隔离的环境里,使用起来就好像是在一个独立于宿主的系统下操作一样,也使得容器可以很方便的在任何地方运行。
容器的主要优点概括如下:
VMware官方对虚拟机的定义,虚拟机(virtual machines)是提供与物理计算机相同功能的软件计算机。它们像物理机一样运行应用程序和操作系统。但是,虚拟机是在物理机上运行的计算机文件,它的行为类似于物理计算机。换句话说,虚拟机表现为独立的计算机系统。一台主机可以同时存在多个虚拟机,组成虚拟机的关键文件包括日志文件,NVRAM设置文件,虚拟磁盘文件和配置文件。
RedHat对虚拟机的解释为,虚拟机是一种创建于物理硬件系统、充当虚拟计算机系统的虚拟环境,它模拟出了自己的整套硬件,包括 CPU、内存、网络接口和存储器。通过被称为虚拟机监控程序(hypervisor)的软件可以将计算机的资源与硬件分开并进行适当分配,以供虚拟机使用。
简单来说,虚拟机实现在一台物理计算机上模拟多台计算机运行任务。虚拟机的操作系统和应用共享一台或多台主机的硬件资源,每台虚拟机有自己的操作系统和虚拟化的硬件资源。但也消耗了大量内存和CPU。
为什么使用虚拟机,虚拟机主要有以下优点:
但是虚拟机也有几个缺点:
容器和虚拟机看起来很相似,所以不能将容器和虚拟机混淆。其实容器和虚拟机具有相似的资源隔离和分配优势,但功能不同,因为容器虚拟化了操作系统,而不是硬件,所以容器更加便携和高效。Docker官网截取的容器和虚拟机的对比图如下:
容器和虚拟机的区别:
通过对容器和虚拟机的简单了解,发现容器和虚拟机各有优劣,如何选择取决于具体需求,并且这两者是可以共存的。
Docker毫无疑问是从众多容器技术中脱颖而出的佼佼者,至于Docker具体是什么,通过下面几点总结:
runc是一个Linux命令行工具,用于根据OCI容器运行时规范创建和运行容器。
containerd是一个守护程序,它管理容器生命周期,提供了在一个节点上执行容器和管理镜像的最小功能集。
作为一种新兴的虚拟化方式,Docker跟传统的虚拟化方式相比具有众多的优势。具体总结如下:
Docker容器技术与传统的虚拟机技术的比较见下表:
特性 | 容器 | 虚拟机 |
---|---|---|
启动 | 秒级(甚至毫秒级) | 分钟级 |
性能 | 接近原生 | 较弱 |
内存代价 | 很小 | 较大 |
硬盘使用 | 一般为MB | 一般为GB |
系统支持量 | 单机上千 | 一般几十 |
隔离性 | 安全隔离 | 完全隔离 |
迁移性 | 优秀 | 一般 |
现在一说到容器,第一时间就会想到Docker,但是容器并不等同于Docker,Docker只是容器技术的一种实现,用来管理容器,就像VMware是虚拟机的一种实现一样,除了Docker,还有LXC/LXD、rkt等容器技术实现,只是Docker最为出名。
前面多次提到了虚拟化一词,虚拟化技术是一个通用的概念,维基百科上对虚拟化技术的定义如下:
虚拟化技术是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以用比原本的组态更好的方式来应用这些资源。这些资源的新虚拟部分是不受现有资源的架设方式,地域或物理配置所限制。一般所指的虚拟化资源包括计算能力和数据存储。
虚拟化的核心是对资源的抽象,目标是在同一个主机上同时运行多个系统或应用,从而提高系统资源的利用率,并带来降低成本、方便管理和容错容灾等好处。虚拟化技术大体可分为基于硬件的虚拟化和基于软件的虚拟化。基于软件的虚拟化从对象所在的层次,又可以分为应用虚拟化和平台虚拟化。后者又可细分为以下几类:
Docker以及其他容器技术都属于操作系统虚拟化。因为传统方式是硬件层面实现虚拟化,需要有额外的虚拟机管理应用和虚拟机操作系统层,而Docker容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,因此更加轻量级。
Docker的三个基本概念如下:
理解了这三个概念,就理解了Docker的整个生命周期。
操作系统分为内核和用户空间。对于Linux而言,内核启动后,会挂载root文件系统为其提供用户空间支持。而Docker镜像(Image)就相当于是一个root文件系统。
Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
分层存储
Docker在设计时,就充分利用Union FS的技术,将其设计为分层存储的架构。镜像实际是由多层文件系统联合组成。
镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行时,虽然不会看到这个文件,但实际上该文件会一直跟随镜像。因此,在构建镜像的时候,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。
分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。
镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。容器之间互相隔离,互不可见。
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。容器可以拥有自己的root文件系统、自己的网络配置、自己的进程空间,甚至自己的用户ID空间。容器内的进程是运行在一个隔离的环境里,这使得容器封装的应用比直接在宿主运行更加安全。
容器和镜像一样使用的分层存储,容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。
容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
按照Docker最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。
数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。
仓库注册服务(Docker Registry)
仓库注册服务(Docker Registry)是一个集中的存储、分发镜像的服务。一个仓库注册服务(Docker Registry)中可以包含多个仓库(Repository)。有时候我们会将Docker仓库(Repository)和仓库注册服务(Docker Registry)混为一谈,并不严格区分。用户可以在自己的数据中心搭建私有的Registry,也可以使用公用Registry服务。
Docker Registry 公开服务
Docker Registry 公开服务是开放给用户使用、允许用户管理镜像的Registry服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。
最常使用的Registry公开服务是官方的Docker Hub,这也是默认的Registry,并拥有大量的高质量的官方镜像。Docker Hub中有用户仓库和顶层仓库两种类型的仓库,用户仓库为普通Docker Hub用户创建,顶层仓库则由Docker官方负责维护,提供官方版本镜像。
Docker Registry 公开服务除了官方的Docker Hub,还有Red Hat的Quay.io,Google的Google Container Registry,国内一些云服务商也提供了类似的公开服务。如网易云镜像服务、阿里云镜像库等。
私有 Docker Registry
用户可以在本地搭建私有Docker Registry。Docker官方提供了Docker Registry镜像,可以直接使用做为私有Registry服务。
开源的Docker Registry镜像只提供了Docker Registry API的服务端实现,足以支持docker命令,不影响使用。但不包含图形界面,以及镜像维护、用户管理、访问控制等高级功能。在官方的商业化版本Docker Trusted Registry中,提供了这些高级功能。
除了官方的Docker Registry外,还有第三方软件实现了Docker Registry API,甚至提供了用户界面以及一些高级功能。比如,Harbor和Sonatype Nexus。
仓库(Repository)
一个仓库(Repository)可以包含多个标签(Tag),每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。可以通过<仓库名>:<标签>
的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以latest
作为默认标签。
仓库通过命名规范对用户仓库和顶层仓库进行组织,用户仓库的命名由用户名和仓库名两部分组成,中间以/
隔开,即username/repository_name
的形式。仓库名通常表示镜像所具有的功能,如ansible/ubuntu14.04-ansible
,而顶层仓库则只包含仓库名的部分,如ubuntu
。
事实上仓库是一个镜像集合,其中包含了多个不同版本的镜像,使用标签进行版本区分。简单来说,Registry是仓库的集合,仓库是镜像的集合。
cs