云是一种能够抽象、汇集和共享整个网络中的可扩展资源的IT环境,云计算是指在云中运行工作负载的功能。云计算正在快速取代原本通过硬布线连接进行资源共享的方式。
云计算的环境
云计算的环境主要分为四种类型:私有云、公有云、混合云和多云。
私有云
私有云是一种专为最终用户而创建,而且通常位于用户的防火墙内的云环境。如果底层 IT 基础架构归某个拥有完全独立访问权限的客户专有,那这种云就是私有云。
公共云:
公有云是云厂商资源创建的云环境,可分发给其他租户。全球规模最大的公共云提供商如:阿里云、Amazon Web Services(AWS)、Google云、IBM Cloud及Microsoft Azure等等。
公共云通常不会作为独立的基础架构解决方案来部署,而是被作为异构混合环境的一部分部署,这样即可以提高安全性和性能,降低成本,还可以改进基础架构、服务和应用的可用性。
混合云:
混合云是一种IT架构,在两个或更多环境中进行业务的编排和管理。混合云中的环境因企业而异,一般包括至少1个私有云与至少1个公共云。
多云:
多云是含有多个云环境(公共云或私有云)的IT系统,云与云之间可能联网也可能不联网。多云是一种云架构,由多个云供应商提供的多个云服务组合而成,既可以是公共云,也可以是私有云。
云计算的服务
云计算服务主要有三种:SaaS、PaaS、IaaS
SaaS
软件服务,Software-as-a-service。SaaS 是软件的开发、管理、部署都交给第三方,不需要关心技术问题,可以拿来即用。普通用户接触到的互联网服务,几乎都是 SaaS
PaaS
平台服务,Platform-as-a-service。PaaS 提供软件部署平台(runtime),抽象掉了硬件和操作系统细节,可以无缝地扩展(scaling)。开发者只需要关注自己的业务逻辑,不需要关注底层。
IaaS
基础设施服务,Infrastructure-as-a-service。IaaS 是云服务的最底层,主要提供一些基础资源。它与 PaaS 的区别是,用户需要自己控制底层,实现基础设施的使用逻辑。
三种云服务中,用户所承担的工作量:IaaS > PaaS > SaaS,如下图所示:
虚拟化
虚拟化是以单个物理硬件系统为基础创建多个模拟环境或专用资源的技术,很明显,虚拟化是发生在IaaS层的技术。
虚拟化和云计算经常被混为一谈,但是实际上虚拟化有助于创建云,但它并非实现云计算的决定性技术,云计算是一种方法,为用户提供多种虚拟资源访问服务的方法。
Docker 是一个C/S架构程序。Docker 客户端只需要向 Docker 服务器发出请求,服务器将完成所有工作并返回结果。Docker 提供了一个命令行工具 Docker 以及一整套 RESTful API。整体架构如下图所示:
容器是运行在一个隔离的环境里,使用起来好像在一个独立于宿主的系统下操作一样,拥有自己的root文件系统、自己的网络配置、自己的进程空间、甚至自己的用户ID。
要理解Docker,首先需要明白Docker的三个核心概念:NameSpace、CGroups、UnionFS
NameSpace
NameSpace(命名空间)是Linux内核的一个强大的特性,它可以将某个特定的全局系统资源(global system resource)通过抽象方法使得namespace中的进程看起来拥有它们自己的隔离的全局系统资源实例,命名空间保证了容器之间实现了运行环境的隔离,互不影响。每个容器都有自己的命名空间,运行在其中的应用都是在独立操作系统中运行一样。
CGroups
Docker容器仅有运行环境的隔离还不够,因为这些进程还是可以不受限制地使用系统资源,比如网络、磁盘、CPU以及内存等,如果一个进程占用了太多的资源,会影响到其它进程;另一方面,在系统资源耗尽的时候,Linux内核会触发OOM (out of memory killer)机制,在系统内存耗尽的情况下,选择性地干掉一些进程以求释放一些内存,这会杀掉一些其他进程。因此为了让容器中的进程更加可控,Docker使用Linux CGroups来限制容器中的进程允许使用的系统资源。Linux Cgroup可以让系统中所运行进程的用户定义组分配资源,实现了容器之间的资源隔离。
UnionFS
要理解unionFS,需要先了解bootfs和rootfs
boot file system (bootfs) 包含操作系统boot loader和kernel。用户不会修改这个文件系统,一旦启动成功后,整个Linux内核加载进内存,之后bootfs会被卸载掉,从而释放内存。同样的内核版本不同Linux发行版,其bootfs都是一样的。
root file system (rootfs) 包含典型的目录结构(/dev/,/proc,/bin,/etc,/lib,/usr,/tmp)Linux系统在启动时,rootfs首先会被挂载为只读模式,然后在启动完成后被修改为读写模式,随后它们就可以被修改了
镜像是分层的,通过镜像构建容器进行启动时,会在镜像的上方增加容器的初始层(init Layer)和读写层(Read-write Layer),UnionFS的作用是把不同的文件系统中的文件和目录,透明地覆盖,联合挂载到一个单一、一致的文件系统服务中。UnionFS的思想是:如果一个资源是重复的,并且没有任何修改,这时并不需要立即创建一个新的资源,这个资源可以被新旧实例共享。UnionFS通过一个关键的资源管理技术:写时复制技术(copy-on-write),当需要对文件进行操作的时候,它并没有改变原来的文件,而是写到了新的文件中,即容器中的读写层。
Docker的UnionFS最初使用的存储驱动是AUFS,目前大多是overlay2,不过对于AUFS也是支持的。
镜像
Docker镜像(Images
)就是一个Linux的文件系统,这个文件系统里面包含可以运行在Linux内核的程序以及相应的数据,本质上是打包了一个用户空间,包含了运行的应用及其整个运行时环境(包括全部所需文件)。
区别于Linux镜像,Linux镜像包括Linux内核和用户空间,比如CentOS和Ubuntu的镜像,它们本质上是在相同的Linux内核(Linux kernel)上封装了自己的软件和工具集(tools),形成了不同的发行版本(Linux Distribution)。
Docker镜像打包的是用户空间,使用宿主机的Linux内核,所以能够在不同的Linux发行版上运行。
需要注意的是,镜像的两个特征
Layer
)的:即一个镜像可以多个中间层组成,多个镜像可以共享同一中间层,我们也可以通过在镜像添加多一层来生成一个新的镜像。read-only
):镜像在构建完成之后,便不可以再修改,而上面我们所说的添加一层构建新的镜像,这中间实际是通过创建一个临时的容器,在容器上增加或删除文件,从而形成新的镜像,因为容器是可以动态改变的。容器
容器(Containers
)是一个独立于宿主机的隔离进程,并且有属于容器自己的网络和命名空间。容器是通过镜像来创建的,所以必须先有镜像才能创建容器,通过镜像构建容器之后,在镜像上面添一层读写层(writer/read layer),也称为容器层,因此容器是可读可写的。
所有对容器的改动,无论添加、删除、还是修改文件都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的。
文件操作 | 说明:只有当需要修改时才复制一份数据,这种特性被称作 Copy-on-Write。 |
---|---|
添加文件 | 在容器中创建文件时,新文件被添加到容器层中。 |
读取文件 | 在容器中读取某个文件时,Docker 会从上往下依次在各镜像层中查找此文件。找到后将其复制到容器层,然后打开并读入内存。 |
修改文件 | 在容器中修改已存在的文件时,Docker 会从上往下依次在各镜像层中查找此文件。找到后将其复制到容器层,然后修改之。 |
删除文件 | 在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。找到后在容器层中记录下此删除操作,并不真正删除。 |
容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改。所以镜像可以被多个容器共享
仓库
仓库(Repository
)也称为注册中心(Registry
),是集中存储镜像的地方,仓库分为公共仓库和私有仓库
公共仓库一般是指Docker Hub
,我们可以从Docker Hub
获取镜像,也可以将自己构建的镜像存放到Docker Hub
,这样,别人也可以使用我们构建的镜像。
私有仓库是自己搭建的私有仓库服务,用于存储和分布我们的镜像。
数据卷
容器中只安装了我们的程序运行所需要的环境,那么如果容器中的程序产生需要持久化的数据,就需要数据卷(volume
)来解决。
数据卷将数据持久化到宿主机上,简单的说就是将宿主机的目录映射到容器中的目录,应用程序在容器中的目录读写数据会同步到宿主机上,这样容器产生的数据就可以存储到我们宿主机上的真实磁盘中,与容器间实现数据共享。
安装Docker的方法较多,本次选用yum安装,在一台机器上安装服务端和客户端
1 | # 卸载旧的软件包和依赖 |
如果在不同的机器上分别安装服务端和客户端
1 | # 服务端安装docker引擎和容器运行时 |