Docker的诞生
dotCloud公司(PaaS)自身业务发展并不如愿,创始人Solomon Hykes决定投向容器技术,并从一开始就在Github上开源,2013年项目命名为Docker,并取得广泛的关注。
Docker是基于LXC技术之上构建的Container容器引擎,基于Go语言并遵循Apache 2.0协议开源。
容器技术其实早在2000年早起的UNIX系统上就出现了,直到2007年才加入Linux。容器的行为表现与虚拟机非常类似。现在人们提起容器,基本上指的都是Docker容器了。Docker极大地简化了容器的使用方法,将基于Linux内核隔离机制的容器实现细节统统隐藏在一条简单的命令:docker run之后。另外,Docker提供了一种容器格式,允许将应用和服务打包成一个理论上可以运行在任何安装了Docker Daemon的Linux系统上的容器。
Hypervisor与Docker
Hypervisor
Hypervisor是一种运行在物理服务器和操作系统之间的中间软件层,可允许多个操作系统和应用共享一套基础物理硬件,因此也可以看作是虚拟环境中的“元”操作系统,它可以协调访问服务器上的所有物理设备和虚拟机,也叫虚拟机监视器(Virtual Machine Monitor)。Hypervisor是所有虚拟化技术的核心。
Hypervisor是一种运行在基础物理服务器和操作系统之间的中间软件层,可允许多个操作系统和应用共享硬件。也可叫做VMM( virtual machine monitor ),即虚拟机监视器。 Hypervisors是一种在虚拟环境中的“元”操作系统。他们可以访问服务器上包括磁盘和内存在内的所有物理设备。Hypervisors不但协调着这些硬件资源的访问,也同时在各个虚拟机之间施加防护。当服务器启动并执行Hypervisor时,它会加载所有虚拟机客户端的操作系统同时会分配给每一台虚拟机适量的内存,CPU,网络和磁盘。
Docker
Docker也是虚拟化的一种,是通过内核虚拟化技术(namespaces和cgroups等)来提供容器的资源隔离与安全保障等。由于Docker通过操作系统层虚拟化实现隔离,所以Docker容器在运行时,不需要类似虚拟机(VM)额外的操作系统开销,提高资源利用率。
Docker要解决的问题
- 消除环境的不一致
- 隔离运行环境
- 应用的打包和分发
- 简单便捷的操作(统一的API)
Docker配合运维的优势
- 环境一致性——减少环境切换带来的问题
- 交付标准化——统一的交付件规格便于管理
- 自动化运维——提高运维效率,Docker提供了API
- 资源利用率——降低基础设施成本
Docker配合运维的劣势
- 操作习惯的变化——ssh/cronjob等变动
- 监控方式的变化——系统指标/日志等方面
- 网络/存储的变化——学习成本
- 周边系统的变化——架构成本
Docker的架构及工作流
Docker的基本组成:
- Docker Client 客户端
- Docker Daemon 守护进程
- Docker Image 镜像
- Docker Container 容器
- Docker Registry 仓库
docker是C/S架构的程序。客户端对服务器端的访问既可以是在本地,也可以通过远程来访问。
我们通过docker客户端来执行各种命令,docker客户端会将这些命令发送给守护进程,从而操作docker的容器,而容器是通过镜像来创建,而镜像是保存在仓库中。守护进程执行的结果还会传回给客户端。这样我们就可以通过客户端来查看命令运行的结果。
Docker Image镜像
镜像是docker容器的基石,容器基于镜像启动和运行。镜像就好比容器的源代码,保存了用于启动容器的各种条件。
深层次的理解镜像:docker的镜像是个层叠的只读文件系统,它的最底端是个引导文件系统,即bootfs。这很像典型的Linux文件系统,docker用户几乎永远不可能和底层引导文件系统有交互。实际上,当一个容器启动后,它将会被移到内存中,而引导文件系统则会被卸载。
docker镜像的第二层是root文件系统,即rootfs。root文件系统可以是一种或多种的文件系统,比如Ubuntu或者CentOS等。在传统的linux引导过程中,root文件系统会最先以只读的方式加载,但引导结束并完成了完整性检查后,它才会切换为读写模式。但是在docker里,root文件系统永远只能是只读的。并且docker利用联合加载技术又会在root文件系统之上加载更多的只读文件系统。联合加载:一次加载多个文件系统,但是在外面看起来只能看见一个文件系统。联合加载会将各层文件系统叠加到一起。docker将这样的文件系统称为镜像。一个镜像可以放到另一个镜像的顶部,位于下面的镜像称为父镜像,以此类推,最底部的镜像称为基础镜像。也就是图中的root文件系统。
bootfs (boot file system) 主要包含 bootloader 和 kernel, bootloader主要是引导加载kernel, 当boot成功后 kernel 被加载到内存中后 bootfs就被umount了. rootfs (root file system) 包含的就是典型 Linux 系统中的 /dev, /proc,/bin, /etc 等标准目录和文件。
对于不同的linux发行版, bootfs基本是一致的, 但rootfs会有差别, 因此不同的发行版可以公用bootfs 如下图:
【补充】:BusyBox就是一个工具,使用它可以对linux进行定制,可以制作非常小的系统。BusyBox生成的系统映像可以独立安装在硬盘上。
Docker Container容器
容器通过镜像来启动,docker的容器是docker的执行单元,容器中可以运行客户的一个或多个进程。如果说镜像是docker生命周期中的构建和打包阶段,那么容器则是启动和执行阶段。
那么容器是怎样通过镜像来启动的呢?当一个容器启动时,会在该镜像的最顶层加载一个读写文件系统,也就是一个可写的文件层。我们在docker中运行的程序就是在这层中运行的。当docker第一次启动一个容器时,初始的读写层是空的,当文件系统发生变化时,这些变化都会应用到这一层上,比如如果想修改一个文件,这个文件首先会从该读写层下面的只读层复制到该读写层,该文件的只读版本依然存在,但是已经被读写层中的文件副本所隐藏。这就是docker中的一个重要技术,“写时复制”。每个只读镜像层都是只读的,并且以后永远不会变化。
当创建一个新容器时,docker会构建一个镜像站,就像右图所示。在站的最顶层添加可写层,这个读写层加上下面的镜像层以及一些配置数据就构成了一个容器。
Docker Registry仓库
docker用仓库保存用户构建的镜像。仓库分为公有和私有两种。docker公司自己提供了一个公有的仓库,叫Docker Hub。我们可以在docker hub上注册账号,分享并保存自己的镜像。目前docker上已经有了非常丰富的镜像。所以我们也可以通过docker hub来查找我们需要的镜像。当然我们也可以架设自己私有的仓库。