在云计算中,虚拟化技术一般可以被分为两类,分别是虚拟机(VM,Virtual Machine)技术以及容器(Container)技术,这里我们只讲云原生中 Docker
虚拟化技术。
让我们通过回顾部署方式的过程,看看为什么容器如此有用。
早期,我们在物理服务器上运行应用程序。没有办法为物理服务器中的应用程序定义资源边界,这导致了资源分配问题。例如,如果在物理服务器上运行多个应用程序,则可能会出现一个应用程序占用大部分资源的情况,从而导致其他应用程序性能不佳。解决方案是在不同的物理服务器上运行每个应用程序。但由于资源未得到充分利用,这种方法无法扩展,而且组织维护许多物理服务器的成本很高。
传统模式部署最大的问题是造成资源浪费
在虚拟化技术被引入后,虚拟化技术允许我们在单个物理服务器的 CPU 上运行多个虚拟机(VM)。虚拟化允许应用程序在虚拟机之间隔离,不仅避免了资源冲突而且还能提供一定程度的安全性,因为一个应用程序的信息不能被另一个应用程序自由访问。
虚拟化允许我们更好地利用物理服务器中的资源,有更好的可伸缩性,因为可以轻松地添加或更新应用程序,降低硬件成本等等。通过虚拟化技术,我们可以将一组物理资源表示为一次性虚拟机的集群。
每个VM都是在虚拟化硬件之上运行所有组件(包括自己的操作系统)的完整机器。
容器类似于 VM,但它们具有松散的隔离属性,以便在应用程序之间共享操作系统。容器的本质是进程(使用了 NameSpace 做隔离,Cgroups 做限制, rootfs 做文件系统的特殊进程),因此,容器被认为是比 VM 更加轻量级的。与虚拟机类似,容器有自己的文件系统、CPU共享、内存、进程空间等。由于它们与底层基础设施分离,所以它们可以跨云和操作系统版本移植。
容器技术可以达到企业脱离云厂商的强制绑(绑)定(架)。
广泛对容器归纳总结为:
其实通过开始 应用部署方式的变革历程 讲解的内容就可以归纳总结容器主要解决的问题(也是其好处):
解决了上线流程繁琐问题
解决了资源利用率低问题
解决了扩容 / 缩容 不及时问题
解决了服务器环境臃肿问题
解决了环境不一致问题
广泛被大家使用的虚拟机和容器的对比图:
如果我们仔细观察虚拟机是如何在物理硬件上构建的,就会发现在物理硬件和操作系统之间有一层 Hypervisor
,从更广泛的角度来看,Hypervisor 用于对硬件进行虚拟化,然后按照用户希望的方式对硬件进行配置。
与虚拟机不同(虚拟机管理程序将物理硬件划分为多个部分),容器就像普通的操作系统进程。现在的问题是,如果容器就像普通进程,那么它是如何与其他进程隔离的呢?这就是 Namespaces 出现的地方。
Namespaces
是 Linux 中的一个高级概念,每个 Namespaces 都有自己的独立资源,而不需要底层硬件的实际分区。Namespaces 用于虚拟化底层操作系统。
由于容器只是操作系统进程,这就是为什么提升一个容器需要几秒钟,而提升一个虚拟机需要几分钟的原因。
虚拟机
容器
个人感觉我们不应该单纯的进行虚拟机和容器来对比,因为从我们上述的总结与对比中可以发现,
他们的侧重目的点和作用不同,之所以被大家拿出来对比,因为他们都是虚拟化的手段。
其实在云平台中,我觉得下面这个图(图片由bluetata
原创转载请注明出处)更能体现 虚拟机 和 容器的关系,他们是相辅相成相互合作的,有着不同的分工:
如果要真拿虚拟机和容器进行对比的话,总结起来的对比表格可以参照如下:
容器 Container | 虚拟机 VM | |
---|---|---|
启动速度 | 秒级 | 分钟级 |
运行性能 | 接近原生 | 5%左右损失 |
磁盘占用 | MB | GB |
数量 | 成百上千 | 一般几十台 |
版本控制 | 镜像 Images 可以保存差异,可以进行版本控制。Dockerhub 类似于 GitHub | 没有有效的差异,没有版本控制 |
隔离性 | 进程级 | 系统级(更底层) |
操作系统 | 主要支持 Linux | 几乎所有 |
封装程度 | 只打包项目代码和依赖关系,共享宿主机内核 | 完整的操作系统 |
Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud
公司内部的一个业余项目。它基于 Google 公司推出的 Go 语言实现。 项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护(相关资源请参照文末)。
Docker项目只是容器技术的其中一种实现,因为它是管理容器的最流行的工具,所以成为了容器技术的代名词,其他著名的容器工具还包括:rkt、Podman、LXC、containerd、Buildah 等。
Docker 使用客户端-服务器 (C/S) 架构模式,也就是分为客户端(Client)和服务端(Server)。
Docker 主要的架构组成如下(图片由bluetata
原创转载请注明出处):
Docker Client 通过命令行或者其他工具使用 Docker API/SDK与 Docker daemon 通信。例如:当使用docker run 命令时,Docker Client 将其发送到 dockerd 来实现相应的功能。
总结起来 Docker Client 客户端的一些特征
一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。
Docker daemon (dockerd) 监听 Docker API 请求并管理 Docker 对象,如镜像、容器、网络和卷。
例如:接收并处理 docker client 发送的请求。daemon 在后台启动一个server,server 负责接受docker client 发送的请求;接受请求后,server 通过路由与分发调度,找到相应的 handler 来执行请求。
类似于一个轻量级的沙盒,可以将其看作一个极简的 Linux 系统环境(包括 root 权限、进程空间、用户空间和网络空间等)。基于 Docker 镜像被创建,镜像是静态的定义,容器是镜像运行时的实体;容器可以被创建、启动、停止、删除、暂停等。容器是独立运行的一个或一组应用。
Docker镜像里包含了打包的应用程序及其所依赖的环境、可用的文件系统和其他元数据。Docker 镜像是用于创建 Docker 容器的模板。
仓库用来存储 Docker 镜像,分为公有仓库和私有仓库。可以上传镜像到一个镜像仓库,然后下载到另外一台电脑上并运行它。
Docker Hub 是一个 Docker 官方维护的公共仓库,Docker 默认从 Docker Hub 来查找镜像。我们也可以维护自己私有的镜像托管服务。
使用docker pull
或docker run
命令时,所需的图像将从配置的仓库中提取。使用该docker push命令时,会将镜像推送到配置的仓库中。
相比虚拟机来说,容器使用的是一系列非常轻量级的虚拟化技术,使得其启动、部署、升级跟管理进程一样迅速,用起来灵活又感觉跟虚拟机一样没什么区别,所以有些人直接使用 Docker 的 Ubuntu 等镜像创建容器,当作轻量的虚拟机来使用。
如果你仅仅把 Docker 容器当作一个轻量的固定虚拟机用,那其实只能算是另类用法,Docker 容器最重要价值在于提供一整套平台无关的标准化技术,简化服务的部署、升级、维护,只要把需要运维的各种服务打包成标准的集装箱,就可以在任何能运行 Docker 的环境下跑起来,达到开箱即用的效果,这个特点才是 Docker 容器风靡全球的根本原因。
如果说上面两种应用场景还不足以体现出与传统的 PaaS 平台相比的巨大优势的话,那么对微服务的架构这种复杂又灵活的使用场景的无缝支持绝对具有革命意义。
微服务架构将传统分布式服务继续拆分解耦,形成一些更小服务模块,服务模块之间独立部署升级,这些特性与容器的轻量、高效部署不谋而合。
Docker 官方主页:http://www.docker.com/
Docker 引擎的 GitHub 源代码:https://github.com/moby/moby
Docker Hub:https://hub.docker.com/
Docker CLI:https://github.com/docker/cli
Docker Forge(收集了各种Docker工具、组件和服务):https://github.com/dockerforge
Docker 官方博客:https://www.docker.com/blog/
Docker 的IRC频道:irc.freenode.net
Docker 的StackOverflow问答主页:https://stackoverflow.com/questions/tagged/docker
注:本文原创由
bluetata
发布于: https://bluetata.blog.csdn.net/ 转载请务必注明出处。