当前位置 博文首页 > RtxTitanV的博客:Docker与容器的基本概念

    RtxTitanV的博客:Docker与容器的基本概念

    作者:[db:作者] 时间:2021-07-07 12:31

    本文主要对Docker和容器的一些基本概念进行一个总结。

    一、容器与虚拟机

    1.什么是容器

    Docker官方对容器的解释,一句话概括,容器(Container)就是将软件打包成标准化单元,以用于开发、交付和部署。容器是打包代码及其所有依赖的软件的标准单元,使应用可以从一个环境快速可靠地运行到另一个环境。容器镜像是轻量的、可执行的独立软件包 ,包含软件运行所需的所有内容:代码、运行时环境、系统工具、系统库和设置。容器化软件适用于基于Linux和Windows的应用,在任何环境中都能够始终如一地运行。容器赋予了软件独立性,将其与环境隔离开来,确保在例如开发和预演环境这种存在差异的环境中统一地运行。

    容器也是一种用于打包应用(已编译)代码以及运行时所需依赖的技术。运行的每个容器可以重复,通过包含依赖项实现标准化意味着在任何环境运行容器都可以得到相同的行为。容器将应用与主机基础结构分离,使其在不同的云和操作系统环境部署更加容易。容器是不可变的,无法更改已运行容器的代码。如果一个容器化应用需要更改,则需要构建一个包含更改的新容器,从更新的镜像从新创建容器。

    容器技术实质上是对系统资源的隔离和控制,使容器进程运行于属于自己的独立的命名空间(namespace)。容器可以拥有自己的文件系统、网络配置、进程空间等,容器内的进程是运行在一个隔离的环境里,使用起来就好像是在一个独立于宿主的系统下操作一样,也使得容器可以很方便的在任何地方运行。

    2.容器的优点

    容器的主要优点概括如下:

    • 使用简单高效:与虚拟机镜像相比,容器镜像更易用、更高效。容器体积小启动快,不需要与外部的基础架构环境绑定,完美解决从开发到生产环境的一致性问题。
    • 监测与管理:容器比虚拟机更加透明,有助于监测与管理。尤其是容器进程的生命周期由基础设施管理,而不是被进程管理器隐藏在容器内部。最后,每个应用程序用容器封装,管理容器部署就等同于管理应用程序部署。
    • 持续集成和部署:容器消除环境差异,保证应用生命周期环境一致性和标准化。开发人员使用镜像实现标准开发环境构建,开发完成后封装完整环境和应用镜像,测试运维人员可以直接部署镜像进行测试和发布,简化了持续集成、测试和发布过程。
    • 环境标准化与版本控制:基于容器提供的环境一致性和标准化,可以对容器镜像进行版本控制,即能够对整个运行环境进行版本控制,提供可靠与频繁的容器镜像构建、部署和快速简便的回滚。
    • 资源高效利用与隔离:容器没有管理程序的额外开销,与底层共享操作系统,性能优良,系统负载低,在相同条件可以运行更多应用实例,可以充分利用系统资源。容器还拥有不错的资源隔离与控制能力,可以精确地分配系统资源,保证应用之间互不影响。
    • 可观测:不仅显示操作系统的信息和度量,还显示应用自身的信息和度量。
    • 云和操作系统分发可移植性:可运行在Ubuntu、RHEL、 CoreOS、物理机、GKE以及其他任何地方。
    • 以应用为中心:从传统的硬件上部署操作系统提升到操作系统中部署应用程序。
    • 松耦合、分布式、弹性伸缩和微服务:应用程序被分成更小,更独立的模块,并可以动态管理和部署,而不是运行在专用设备上的大型单体程序。

    3.什么是虚拟机

    VMware官方对虚拟机的定义,虚拟机(virtual machines)是提供与物理计算机相同功能的软件计算机。它们像物理机一样运行应用程序和操作系统。但是,虚拟机是在物理机上运行的计算机文件,它的行为类似于物理计算机。换句话说,虚拟机表现为独立的计算机系统。一台主机可以同时存在多个虚拟机,组成虚拟机的关键文件包括日志文件,NVRAM设置文件,虚拟磁盘文件和配置文件。

    RedHat对虚拟机的解释为,虚拟机是一种创建于物理硬件系统、充当虚拟计算机系统的虚拟环境,它模拟出了自己的整套硬件,包括 CPU、内存、网络接口和存储器。通过被称为虚拟机监控程序(hypervisor)的软件可以将计算机的资源与硬件分开并进行适当分配,以供虚拟机使用。

    简单来说,虚拟机实现在一台物理计算机上模拟多台计算机运行任务。虚拟机的操作系统和应用共享一台或多台主机的硬件资源,每台虚拟机有自己的操作系统和虚拟化的硬件资源。但也消耗了大量内存和CPU。

    4.虚拟机的优缺点

    为什么使用虚拟机,虚拟机主要有以下优点:

    • 易于管理维护并可广泛使用
    • 一台物理机上可以运行多个操作系统环境以提高硬件利用率
    • 应用可以使用所有操作系统资源
    • 提供故障恢复(disaster recovery)和应用程序预防选项
    • 提供与系统其余部分隔离的环境使主机不受虚拟机内部干扰
    • 便于新应用测试和设置生产环境
    • 提供丰富的管理工具
    • 提供丰富的安全工具
    • 提供更好的安全控制

    但是虚拟机也有几个缺点:

    • 一台物理机运行多个虚拟机可能会导致性能不稳定
    • 效率不高且运行速度比物理计算机慢
    • 占用空间较大和消耗系统资源较多

    5.容器和虚拟机的区别

    容器和虚拟机看起来很相似,所以不能将容器和虚拟机混淆。其实容器和虚拟机具有相似的资源隔离和分配优势,但功能不同,因为容器虚拟化了操作系统,而不是硬件,所以容器更加便携和高效。Docker官网截取的容器和虚拟机的对比图如下:
    容器和虚拟机对比
    容器和虚拟机的区别:

    • 容器轻量级,虚拟机重量级。
    • 容器是一个应用层抽象,用于将代码和依赖打包在一起,即操作系统级虚拟化。虚拟机是一个用于将一台服务器变成多台服务器的物理硬件层抽象,即硬件级虚拟化。
    • 虽然多个容器和多个虚拟机都可以在同一台机器上运行,但容器共享操作系统内核,各自作为独立的进程在用户空间中运行。而每个虚拟机都运行在自己的操作系统中。
    • 容器占用的内存空间少,虚拟机由于包含一整套操作系统、一个或多个应用、必要的二进制文件和库资源,因此占用大量空间。
    • 容器性能接近本机,虚拟机性能有限。
    • 容器启动时间秒级(甚至毫秒级),虚拟机启动时间分钟级。
    • 容器属于进程级隔离,安全性比虚拟机低。虚拟机属于完全(操作系统级)隔离,安全性更高。
    • 容器的集群规模为上万级,虚拟机的集群规模为上百级。
    • 容器的高可用策略侧重于弹性、负载和动态。虚拟机的高可用策略侧重于备份、容灾和迁移。
    • 容器适合在更少的服务器运行更多的应用,可以充分利用系统资源。虚拟机适合运行时需要所有操作系统资源和功能的场景。

    通过对容器和虚拟机的简单了解,发现容器和虚拟机各有优劣,如何选择取决于具体需求,并且这两者是可以共存的。

    二、初识Docker

    1.什么是Docker

    Docker毫无疑问是从众多容器技术中脱颖而出的佼佼者,至于Docker具体是什么,通过下面几点总结:

    • Docker是一个开源容器项目,代码在GitHub维护,遵循Apache 2.0协议并已加入Linux基金会,受到主流操作系统以及云服务提供商支持,成立推动了开放容器联盟(OCI)。
    • Docker使用Google公司的Go语言进行开发实现,基于Linux内核的命名空间(namespace) 、控制组(cgroup)以及OverlayFS类的Union FS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。
    • Docker最初是基于Linux容器(LXC)实现,后来使用自己开发的libcontainer替代了LXC,然后进一步演化为使用runc和containerd。
    • Docker提供了高效、敏捷和轻量级的容器方案,可在容器内快速自动化部署应用,通过操作系统内核技术为容器提供资源隔离与安全保障,极大地简化了容器创建与维护,并支持部署到本地环境和多种云平台。换句话说,Docker为应用开发、运行和部署提供了一站式解决方案。

    runc是一个Linux命令行工具,用于根据OCI容器运行时规范创建和运行容器。

    containerd是一个守护程序,它管理容器生命周期,提供了在一个节点上执行容器和管理镜像的最小功能集。

    2.Docker的优势

    作为一种新兴的虚拟化方式,Docker跟传统的虚拟化方式相比具有众多的优势。具体总结如下:

    • 更高效的利用系统资源:容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker对系统资源的利用率更高,需求量更小,可以实现更高的性能。一个相同配置的主机,使用容器可以比虚拟机运行更多数量的应用。
    • 更快速的启动时间:Docker容器应用可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。
    • 一致的运行环境:Docker镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现同样的代码换个环境就无法运行这类问题。
    • 持续交付和部署:使用Docker可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员通过Dockerfile构建镜像并结合持续集成系统进行集成测试,运维人员可以直接在生产环境中快速部署该镜像,甚至结合持续部署系统进行自动部署。
    • 更轻松的迁移:Docker确保了执行环境的一致性,使得应用在不同平台之间的迁移更加容易,而不用担心运行环境的变化导致应用无法正常运行的情况。
    • 更轻松的维护和扩展:Docker使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。Docker还维护了一大批高质量官方镜像,进一步降低了应用服务的镜像制作成本。
    • 良好的隔离性:Docker为容器提供了可靠的资源隔离与安全保障,使容器精确地分配系统资源,保证应用之间互不影响。
    • 弹性伸缩:善于处理集中爆发的服务器使用压力,动态的管理应用。

    3.Docker容器技术与虚拟机技术的比较

    Docker容器技术与传统的虚拟机技术的比较见下表:

    特性容器虚拟机
    启动秒级(甚至毫秒级)分钟级
    性能接近原生较弱
    内存代价很小较大
    硬盘使用一般为MB一般为GB
    系统支持量单机上千一般几十
    隔离性安全隔离完全隔离
    迁移性优秀一般

    4.Docker和容器的关系

    现在一说到容器,第一时间就会想到Docker,但是容器并不等同于Docker,Docker只是容器技术的一种实现,用来管理容器,就像VMware是虚拟机的一种实现一样,除了Docker,还有LXC/LXD、rkt等容器技术实现,只是Docker最为出名。

    5.Docker与虚拟化

    前面多次提到了虚拟化一词,虚拟化技术是一个通用的概念,维基百科上对虚拟化技术的定义如下:

    虚拟化技术是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以用比原本的组态更好的方式来应用这些资源。这些资源的新虚拟部分是不受现有资源的架设方式,地域或物理配置所限制。一般所指的虚拟化资源包括计算能力和数据存储。

    虚拟化的核心是对资源的抽象,目标是在同一个主机上同时运行多个系统或应用,从而提高系统资源的利用率,并带来降低成本、方便管理和容错容灾等好处。虚拟化技术大体可分为基于硬件的虚拟化和基于软件的虚拟化。基于软件的虚拟化从对象所在的层次,又可以分为应用虚拟化和平台虚拟化。后者又可细分为以下几类:

    • 完全虚拟化:虚拟机模拟完整的底层硬件环境和特权指令的执行过程,客户操作系统无须进行修改。
    • 硬件辅助虚拟化:利用硬件(主要是CPU)辅助支持处理敏感指令来实现完全虚拟化的功能,客户操作系统无须修改。
    • 部分虚拟化:只针对部分硬件资源进行虚拟化,客户操作系统需要进行修改。
    • 超虚拟化(paravirtualization):部分硬件接口以软件的形式提供给客户机操作系统,客户操作系统需要进行修改。
    • 操作系统级虚拟化:内核通过创建多个虚拟的操作系统实例(内核和库)来隔离不同的进程。容器相关技术即在这个范畴。

    Docker以及其他容器技术都属于操作系统虚拟化。因为传统方式是硬件层面实现虚拟化,需要有额外的虚拟机管理应用和虚拟机操作系统层,而Docker容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,因此更加轻量级。

    三、Docker基本概念

    Docker的三个基本概念如下:

    • 镜像(Image)
    • 容器(Container)
    • 仓库(Repository)

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

    1.镜像

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

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

    分层存储
    Docker在设计时,就充分利用Union FS的技术,将其设计为分层存储的架构。镜像实际是由多层文件系统联合组成。

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

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

    2.容器

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

    容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。容器可以拥有自己的root文件系统、自己的网络配置、自己的进程空间,甚至自己的用户ID空间。容器内的进程是运行在一个隔离的环境里,这使得容器封装的应用比直接在宿主运行更加安全。

    容器和镜像一样使用的分层存储,容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。

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

    按照Docker最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。

    数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。

    3.仓库

    仓库注册服务(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
    上一篇:没有了
    下一篇:没有了