虚拟化技术
虚拟化技术是一-种计算机资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来。虚拟化技术打破了计算机实体结构间的不可切割的障碍。使用户可以比原本的组态更好的方式来应用这些资源。
虚拟化技术主要作用:
●高性能的物理硬件产能过剩和老的旧的硬件产能过低的重组重用,透明化底层物理硬件。
●软件跨环境迁移问题(代码的水土不服)。
在一台主机上实现多个操作系统,关键技术就是硬件的虚拟化。
首先,我们先来看几个问题:
这里我们以ava Web应用程序为例,-个lava Web应用程序涉及很多东西,比如DK、Tomcat. Spring等。 当这些其中某一项版本不一致的时候, 可能就会导致应用程序跑不起来这种情况。Docker则将程序直接打包成镜像,直接运行在容器中即可。
这种也是一-种比较常见的情况,如果你的程序重要性不是特别高的话, 公司基本上不可能让你的程序独享-台服务器的, 这时候你的服务器就会跟公司其他人的程序共享- - 台服务器,所以不可避免地就会受到其他程序的干扰,导致自己的程序出现问题。Docker就很好解决了环境隔离的问题,别人程序不会影响到自己的程序。
开发阶段部署一套软件环境,测试人员在开发中测试没有问题,运维进行部署(同-套代码)。但是正式部署到服务器时,发生了问题(启动参数、环境问题、漏配了参数)等意外。
在没有Docker的情况下,要在几天内部署几十台服务器,这对运维来说是一件非常折磨人的事,而且每台服务器的环境还不一定一样,这时就会出现各种问题,最后部署地头皮发麻。用Docker的话, 我只需要将程序打包到镜像, 你要多少台服务,我就给你跑多少容器,极大地提高了部署效率。
随着微服务技术的兴起,一个大的应用需要拆分成多个微服务。多个微服务的生成,就会面临庞大系统的部署效率,开发协同效率问题。然后通过服务的拆分,数据的读写分离、分库分表等方式重新架构,而且这种方式如果要做的彻底,需要花费大量人力物力。可能需要部署很多个服务器。
持续的软件版本发布、测试项目到线上环境的集成。用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码样。
Docker是一个开源的应用容器引擎,诞生于2013年初, 基于Go语言实现,dotCloud公司出品(后改名为Docker Inc),并遵从Apache2.0协议开源。从17.03版本之后,Docker分为CE (Community Editin-社区版)和EE (Enterprise Edition-企业版)版本,Docker CE是免费版。
Docker可以让开发者打包他们的应用,以及依赖包到-个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上。Docker容器是完全使用沙箱机制,相互隔离,性能开销也极低。
Docker通俗的讲是服务器中高性能的虚拟机,可以将一台物理机虚拟N多台虚拟机的机器,互相之间隔离,互不影响。
“Debug your app, not your environment!”.调试您的应用程序,而不是您的环境!
官网的介绍是"Docker is the world’s leading software container platform.".官方给Docker的定位是一个应用容器平台。
想要搞懂Docker,其实看它的两句口号就行。第一句是"Build, Ship and Run"。也就是“搭建、发送、运行”,三板斧。
Docker的第二句口号就是"Build once, Run anywhere.“,意思是"搭建一次,到处能用”。
Docker让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Lnux机器上,便可以实现应拟化。Docker改变了虚拟化的方式,使开发者可以直接将自己的成果放入Docker中进行管理。方便快捷已经是Docker的最大优势,过去需要用数天乃至数周的任务,在Docker容 器的处理下,只需要数秒就能完成。
如果你有选择恐惧症,还是资深患者。Docker 帮你打包你的纠结! Docker镜像中包含了运行环境和配置,所以Docker可以简化部署多种应用实例工作。比如Web应用、后台应用、数据库应用、大数据应用,再如Hadoop集群、 消息队列等都可以打包成一个镜像部署。
一方面, 云计算时代到来,使开发者不必为了追求效果而配置高额的硬件,Docker改变 了高性能必然高价格的思维定势。Docker与云的结合,让云空间得到更充分的利用。不仅解决了硬件管理的问题,也改变了虚拟化的方式。
对开发和运维(DevOps) 人员来说,最希望的就是一-次创建或配置, 可以在任意地方正常运行。使用Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过Dockerfile来进行镜像构建,并结合持续集成(Continuous Integration)系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合持续部署(Continuous Delivery/Deployment)系统进行自动部署。而且使用Dockerfile使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部暑该镜像。
由于Docker确保了执行环境的一致性,使得应用的迁移更加容易。Docker可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的, 因此用户可以很轻易的将在一个平台上运行的应用,迁移到另个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
标准化交付: Docker将应用打包成标准化单元,用于交付、部署。
轻量级:容器及包含了软件运行所需的所有环境,而且非常轻量级。
高可靠:容器化的应用程序,可以在任何Linux环境中始终如一的运行。
隔离性:容器化的应用程序,具备隔离性,这样多团队可以共享同一Linux系统资源。
1.Web应用的自动化打包和发布。
2.自动化测试和持续集成、发布。
3.在服务型环境中部署和调整数据库或其他的后台应用。
4.从头编译或者扩展现有的OpenShift或Cloud Foundry平台来搭建自己的PaaS环境。
●PaaS: Platform as a Service, 平台即服务
●SaaS: Software as a Service, 软件即服务
●laas: Infrastructure as a Service,基础设施即服务
下面的图片比较了传统虚拟化方式和Docker的不同之处,
虚拟机通过硬件虚拟化,即每台虚拟机事先从物理机分配好cpu核数,内存, 磁盘,每台虚拟机一般只部署一个应用。
传统虚拟机的组成结构图:
比较上面两张图,可见Docker是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统方式(VMware)则是在硬件层面实现。
Docker和虚拟机的相同点是: Docker和虚拟机都是虚拟化技术,具备资源隔离和分配优势。
Docker容器作为一种轻量级的虚拟化技术,和传统虚拟机技术的特性差异如下表所示:
特性 | 容器 | 虚拟机 |
---|---|---|
启动速度 | 秒级 | 分钟级 |
存储占用 | MB级 | GB级 |
性能对比 | 接近原生级别 | 理论达不到原生级别 |
系统量级 | 单机可支持上千个 | 单机支持几十个 |
安全能力 | 依赖宿主系统安全能力 | 完全隔离 |
若需要资源的完全隔离并且不考虑资源的消耗,可以使用虚拟机。若是想隔离进程井且需要运行大量进程实例,应该选择Docker容器.
Docker容器与主机共享操作系统内核,不同的容器之间可以共享部分系统资源,因此更加轻量级,消耗的资源更少。虚拟机会独占分配给自己的资源,不存在资源共享,各个虚拟机之间近乎完全隔离,更加重量级,也会消耗更多的资源。
虚拟机是用来进行硬件资源划分的完美解决方案,利用的是硬件虚拟化技术,如此VT-x、 AMD-V会通过一个Hypervisor层来实现对资源的彻底隔离。而容器则是操作系统级别的虚拟化,利用的是内核的cgroup和namespace特性,此功能通过软件来实现,仅仅是进程本身就可以实现互相隔离,不需要任何辅助。
Docker使用客户端-服务器C/S架构模式,使用远程API来管理并创建Docker容器
Docker采用C/S架构。Docker Server负责构建、运行和分发Docker镜像。Docker Client和Docker Server可以运行在同一台机器上,也可以通过RESTful或其他网络接口进行远程通信,如下图所示:
从上图能够看到,Docker体系的核心组件包括如下几部分:
●Docker Client: Docker客户端。
●Docker Daemon: Docker守护进程。
●Docker Container: Docker容器。
●Docker Image: Docker镜像。
●Docker Regitry: Docker仓库。
Docker镇像和虚拟机镜像的概念是一样的,可以将其理解为-一个面向Docker引擎的只读模板,可用于批量创造可运行的容器实例。Docker镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如环境变量、用户等) .镜像不包含任何动态数据,其内容在构建之后也不会被改变。镜像是创建Docker容器的基础,而Docker体系能够提供一套简单的机制创建和更新已有的镜像,也可以从网上下载一个制作好的现成的镜像。
分层储层。因为镜像包含操作系统完整的root文件系统,其体积往往是庞大的,因此在Docker设计时,将其设计为分层存储的架构。所以严格来说,镜像并非是像个ISO那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说, 由多层文件系统联合组成。
镜像构建时,会一层层构建,前一层是后一层的基础。每-层构建完就不会再发生改变,后-层 上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件.而是仅在当前层标记为该文件已副除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。 因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。
分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层, 以定制自己所需的内容,构建新的镜像。
Docker容器是一个镜像运行时的概念,实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的root文件系统、自己的网络配置、自己的进程空间,甚至自己的用户ID空间。容器内的进程是运行在一个隔离的环境里, 使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。
前面讲过镜像使用的是分层存储,容器也是如此。每-个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。
容器存储层的生存周期和容器一样, 容器消亡时,容器存储层也随之消亡。按照Docker最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用数据卷(Volume) 、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储) 发生读写,其性能和稳定性更高。
数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。Docker容器与Docker镜像的关系类似于面向对象编程中的对象与类。
Docker 镜像是只读的。当 Docker 运行一个从镜像建立的容器,它会在镜像顶部添加一个可读写的层,应用程序可以在这里运行。
$ sudo docker run -i -t ubuntu /bin/bash
Docker 客户端使用docker命令来运行,run参数表名客户端要运行一个新的容器。
容器以哪个镜像为模板创建忙,这里是ubuntu镜像。
在容器中要运行的命令,这里是/bin/bash,在容器中运行 Bash shell。
按照顺序,Docker 做了这些事情:
你现在拥有了一个运行着的容器!从这里开始你可以管理你的容器,与应用交互,应用完成之后,可以停止或者删除你的容器。
Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。
Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。
一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。
Docker利用仓库管理镜像的理念类似于Git,默认情况下Docker会在中央仓库(Docker Hub和Docker Cloud)寻找镜像文件。
Docker Registry公开服务是开放给用户使用、允许用户管理镜像的Registy服务。- -般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。
最常使用的Registry公开服务是官方的Docker Hub,这也是默认的Registry, 并拥有大量的高质量的官方镜像。
由于某些原因,在国内访问这些服务可能会比较慢。国内的一些云服务商提供 了针对Docker Hub的镜像服务(Reglsry Mrron),这些镇像服务被称为加速器,常见的有阿里云加速器、DaoCloud加速器等。
除了使用公开服务外,用户还可以在本地搭建私有Docker Registry, Docker官方提供了Docker Registry镜像,可以直接使用做为私有Registry服务。
开源的Docker Registry镜像只提供了Docker Registry API的服务端实现、足以支持docker命令,不影响使用。但不包含图形界面,以及镜像维护、用户管理、访问控制等高级功能。在官方的商业化版本Docker Trusted Registry中,提供了这些高级功能。
Docker Client提供了命令行界面(CLI) ,是用户与Docker进行交互的主要窗口。通过Client可以构建、运行和停止容器,还可以与运程的Docker Server进行交互。
Docker Daemon是最核心的后台服务进程,管理容器的进程,以Linux后台服务的方式运行,也称为守护进程。它负责响应来自Docker Client的请求,内部对请求进行路由分发,交给具体的管理模块进行处理。
每个容器都有自己单独的名字空间,运行在其中的应用都像是在独立的操作系统中运行一样。Docker 为该容器创建了一个命名空间集合,使容器之间互不影响。
一些 Docker 使用到的命名空间有:
使用在进程隔离 (PID: Process ID)。
使用在管理网络接口 (NET: Networking)。
使用在管理进程间通信资源 (IPC: InterProcess Communication)。
使用在管理挂载点 (MNT: Mount)。
使用在隔离内核和版本标识 (UTS: Unix Timesharing System)。
Docker 还使用到了cgroups技术来管理群组。控制分配到容器的资源,才能避免当多个容器同时运行时的对系统资源的竞争。群组控制允许 Docker 分享或者限制容器使用硬件资源。例如,限制指定的容器的内容使用。
联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into asingle virtual filesystem)。
联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
另外,不同 Docker 容器就可以共享一些基础的文件系统层,同时再加上自己独有的改动层,大大提高了存储的效率。
Docker 连接这些组建到一个包装中,称为一个 container format(容器格式)。默认的容器格式是libcontainer。Docker 同样支持传统的 Linux 容器使用LXC。