容器和Docker

网友投稿 718 2022-11-18

容器和Docker

容器和Docker

一、容器

1、虚拟机和容器的区别

(1)为什么要用docker

服务器端开发/部署:

实现更轻量级的虚拟化,方便快速部署, 对于部署来说可以极大的减少部署的时间成本和人力成本

Docker支持将应用打包进一个可以移植的容器中,重新定义了应用开发,测试,部署上线的过程,核心理念就是 Build once, Run anywhere。典型应用场景是开发运维上提供持续集成和持续部署的服务

1)标准化应用发布,docker容器包含了运行环境和可执行程序,可以跨平台和主机使用;

2)节约时间,快速部署和启动,VM启动一般是分钟级,docker容器启动是秒级;

3)方便构建基于SOA架构或微服务架构的系统,通过服务编排,更好的松耦合;

4)节约成本,以前一个虚拟机至少需要几个G的磁盘空间,docker容器可以减少到MB级;

5)方便持续集成,通过与代码进行关联使持续集成非常方便;

6)可以作为集群系统的轻量主机或节点,在IaaS平台上,已经出现了CaaS,通过容器替代原来的主机。

docker 优势:

1)交付物标准化

Docker是软件工程领域的“标准化”交付组件,最恰到好处的类比是“集装箱”。

集装箱将零散、不易搬运的大量物品封装成一个整体,集装箱更重要的意义在于它提供了一种通用的封装货物的标准,卡车、火车、货轮、桥吊等运输或搬运工具采用此标准,隧道、桥梁等也采用此标准。以集装箱为中心的标准化设计大大提高了物流体系的运行效率。

传统的软件交付物包括:应用程序、依赖软件安装包、配置说明文档、安装文档、上线文档等非标准化组件。Docker的标准化交付物称为“镜像”,它包含了应用程序及其所依赖的运行环境,大大简化了应用交付的模式。

2)一次构建,多次交付

类似于集装箱的“一次装箱,多次运输”,Docker镜像可以做到“一次构建,多次交付”。当涉及到应用程序多副本部署或者应用程序迁移时,更能体现Docker的价值。

3)应用隔离

沙盒技术:集装箱可以有效做到货物之间的隔离,使化学物品和食品可以堆砌在一起运输。Docker可以隔离不同应用程序之间的相互影响,但是比虚拟机成本更小。

(2)物理机、虚拟机以及容器的通俗定义

物理机:一栋楼一户人家、有自己独立的地基、还有自己独立的花园

虚拟机:一栋楼包含多套房(多户人家)、但是地基是共享、花园也是共享的,只有独立的卫生间、厨房、宽带;

容器:一套房隔成多个小隔间(比如:胶囊式公寓)、每个小隔间一位租户、共享的地基、共享的花园、还共享卫生间、厨房以及宽带。

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

(3)虚拟机和容器的区别

容器和虚拟机具有相似的资源隔离和分配优势,但功能有所不同,因为容器虚拟化的是操作系统,而不是硬件,因此容器更容易移植,效率也更高。

传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。

容器是一个应用层抽象,用于将代码和依赖资源打包在一起。多个容器可以在同一台机器上运行,共享操作系统内核,但各自作为独立的进程在用户空间中运行 。与虚拟机相比, 容器占用的空间较少(容器镜像大小通常只有几十兆),瞬间就能完成启动 。虚拟机 (VM) 是一个物理硬件层抽象,用于将一台服务器变成多台服务器。 管理程序允许多个 VM 在一台机器上运行。每个VM都包含一整套操作系统、一个或多个应用、必要的二进制文件和库资源,因此 占用大量空间 。而且 VM 启动也十分缓慢 。虚拟机更擅长于彻底隔离整个运行环境。例如,云服务提供商通常采用虚拟机技术隔离不同的用户。而 Docker通常用于隔离不同的应用 ,例如前端,后端以及数据库。

(4)容器与虚拟机(VM)两者是可以共存的

(5)生态概览

1)OCI

OCI(Open Container Initiative)致力于建立一个容器运行时和镜像格式的规范,其核心目的在于避免容器生态的分化,确保在不同容器引擎上构建的容器可以相互兼容。这是容器可移植性的根本保证。

OCI的runtime spec标准中对于容器的状态描述,以及对于容器的创建、删除、查看等操作进行了定义。

runtime specOCI Runtime Specification,主要定义如何container配置、执行环境以及container生命周期。image specOCI Image Format Specification,主要定义一个OCI image由一个manifest, 一个image index (optional), 一组filesystem layers, 以及一个configuration组成。该规范的目的在于确保能构建一套不同容器引擎间可互操作的工具,用于镜像的构建、传输,以及镜像运行准备工作。

2)runC

在早期的Docker Engine中,主要用LXC工具来运行和管理容器;后来采用自研的libcontainer来做这类事情,libcontainer直接使用Linux内核提供的相关隔离技术,比如cgroups、namespace等等。runC是一个轻量级的工具,做且只做一件事情,那就是运行一个容器。由libcontainer演变而来,并且由Docker捐献给Linux基金会,作为OCI的参考实现,可以用于创建和运行容器的CLI(command-line interface)工具。runc直接与容器所依赖的cgroup/linux kernel等进行交互,负责为容器配置cgroup/namespace等启动容器所需的环境,创建启动容器的相关进程。runC基本上就是一个命令行小工具,它可以不用通过Docker引擎,直接就可以创建容器。这是一个独立的二进制文件,使用OCI容器就可以运行它。

3)containerdDocker 1.11的Docker Engine里就包含了containerd,而现在则是把containerd从Docker Engine里彻底剥离出来,作为一个独立的开源项目独立发展,目标是提供一个更加开放、稳定的容器运行基础设施。和原先包含在Docker Engine里containerd相比,独立的containerd将具有更多的功能,可以涵盖整个容器运行时管理的所有需求。containerd并不是直接面向最终用户的,而是主要用于集成到更上层的系统里,比如Swarm, Kubernetes, Mesos等容器编排系统。containerd以Daemon的形式运行在系统上,通过unix domain docket暴露很低层的gRPC API,上层系统可以通过这些API管理机器上的容器。每个containerd只负责一台机器,Pull镜像,对容器的操作(启动、停止等),网络,存储都是由containerd完成。具体运行容器由runC负责,实际上只要是符合OCI规范的容器都可以支持。

containerd 是一个守护进程,它可以使用runC管理容器,并使用gRPC暴露容器的其他功能。相比较Docker引擎,使用 gRPC ,containerd暴露出针对容器的增删改查的接口,Docker engine调用这些接口完成对于容器的操作。    4)CRI(容器运行时的接口)CRI中定义了容器和镜像的服务的接口,因为容器运行时与镜像的生命周期是彼此隔离的,因此需要定义两个服务,该接口使用Protocol Buffer,基于gRPC。Container Runtime实现了CRI gRPC Server,包括RuntimeService和ImageService。该gRPC Server需要监听本地的Unix socket,而kubelet则作为gRPC Client运行

2、概念

官方版:

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

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

通俗版:

容器是一种沙盒技术,又像集装箱,把应用整体封装起来的技术;封装后,应用于应用之间,在各自的边界内运行,不会相互干扰;而被装进集装箱的应用,也可以被方便搬来搬去。

集装箱的作用:比如在一艘船上,可以把货物规整的摆放起来。并且各种各样的货物被集装箱标准化,集装箱和集装箱之间不会互相影响。那么我就不需要专门运送水果的船和专门运送化学品的船了。只需要这些货物在集装箱里封装的好好的,那么我就可以用一艘大船把它们都运走。

本质版:

一组受到资源限制,彼此间相互隔离的进程;就是将所有软件整合成一个应用,一个应用。

3、实现原理

技术核心:

约束、修改进程的动态表现,从而创造一个“边界”,所以,容器只是运行在宿主机上的一种特殊的进程,使用的还是同一个宿主机的LINUX操作系统的内核。

4、容器的主要技术

namespace:

用来修改进程视图的主要方法,做访问隔离(每个容器进程都有自己独立的进程空间,看不到其他进程),是LINUX提供的一种内核级别环境隔离方法。

cgroups:用来制造约束的主要手段;主要做资源限制(CPU、内存、存储、网络的使用限制);

二、Docker

1、定义

基于 Linux 内核 的cgroup,namespace,以及AUFS类的UnionFS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。 由于隔离的进程独立于宿主和其它的隔离的进 程,因此也称其为容器。Docke最初实现是基于 LXC.

2、基本概念

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

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

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

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

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

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

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

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

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

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

按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据 ,容器存储层要保持无状态化。所有的文件写入操作,都应该使用数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此, 使用数据卷后,容器可以随意删除、重新 run ,数据却不会丢失。

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

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

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

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

这里补充一下Docker Registry 公开服务和私有 Docker Registry的概念:

Docker Registry 公开服务 是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、-公开的镜像,并可能提供收费服务供用户管理私有镜像。

除了使用公开服务外,用户还可以在 本地搭建私有 Docker Registry 。Docker 官方提供了 Docker Registry 镜像,可以直接使用做为私有 Registry 服务。开源的 Docker Registry 镜像只提供了 Docker Registry API 的服务端实现,足以支持 docker 命令,不影响使用。但不包含图形界面,以及镜像维护、用户管理、访问控制等高级功能。

3、Docker的架构

(1)Docker Engine用来管理镜像

(2)Containerd向docker提供运行容器的API,二者通过grpc进行交互。

(3)containerd最后会通过runc来实际运行容器

(4)containerd-shim称之为垫片,它使用runC命令行工具完成容器的启动、停止以及容器运行状态的监控。containerd-shim进程由containerd进程拉起,并持续存在到容器实例进程退出为止(和容器进程同生命周期)。只要是符合OCI规范的容器,都可以通过containerd-shim来进行调用(比如kata-runtime);

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:windows下通过bat脚本调用sql脚本
下一篇:SpringBoot下载文件的实现及速度对比
相关文章

 发表评论

暂时没有评论,来抢沙发吧~