Docker,超轻量级虚拟机,它可以让你轻松完成持续集成、自动交付、自动部署,并且实现开发环境、测试环境、运维环境三方环境的真正同步
参考内容:
什么是Docker
Docker从狭义上来讲就是一个进程,从广义上来讲是一个虚拟容器,其实更专业的叫法是应用容器( Application Container ),Docker进程和普通的进程没有任何区别,它就是一个普通的应用进程。不过是用来操作镜像文件的。所以Docker进程+构建的应用镜像文件就等于Docker容器。本文所有讲的Docker都是指Docker容器。
镜像
镜像 Docker images,就类似于VM虚拟机里面的快照,可以把images直接理解成一个文件夹。我们可以通过ID或者易识别的名字+tag来确认唯一的目标镜像。ImagesID是一个64位的字符,但是一般我们都是使用前面12位就足够区别了。
VM中的快照及克隆
- 快照的含义:
- 对某一个特定文件系统在某一个特定时间内的一个具有只读属性的镜像。当你需要重复的返回到某一系统状态,又不想创建多个虚拟机的时候,就可以使用快照功能。多重快照不只是简单的保存了虚拟机的多个状态,通过建立多个快照,可以为不同的工作保存多个状态,并且不相互影响。例如,当我们在虚拟机上做实验或是作测试时,难免碰到一些不熟悉的地方,此时做个快照,备份一下当前的系统状态,一旦操作错误,可以很快还原到出错前的状态,完成实验,最终避免一步的失误导致重新开始整个实验或测试的后果。
- 克隆的含义:
- 一个虚拟机的克隆就是原始虚拟机全部状态的一个拷贝,或者说一个镜像。克隆的过程并不影响原始虚拟机,克隆的操作一但完成,克隆的虚拟机就可以脱离原始虚拟机独立存在,而且在克隆的虚拟机中和原始虚拟机中的操作是相对独立的,不相互影响。克隆过程中,VMware会生成和原始虚拟机不同的MAC地址和UUID,这就允许克隆的虚拟机和原始虚拟机在同一网络中出现,并且不会产生任何冲突。 VMware支持两种类型的克隆: 完整克隆、链接克隆。一个完整克隆是和原始虚拟机完全独立的一个拷贝,它不和原始虚拟机共享任何资源。 可以脱离原始虚拟机独立使用。 一个链接克隆需要和原始虚拟机共享同一虚拟磁盘文件,不能脱离原始虚拟机独立运行。但采用共享磁盘文件却大大缩短了创建克隆虚拟机的时间,同时还节省了宝贵的物理磁盘空间。通过链接克隆,可以轻松的为不同的任务创建一个独立的虚拟机。
如下图中左边红框中redis: lates和右边的红框中5f515359c7f8都唯一表示为同一个镜像。所以我们一般的镜像可以命名为类似`centos:latest`、centos:centos7.1.1503等等。镜像是分层的,有基础镜像,仅仅包含操作系统,比如centos镜像;有中间件镜像,比如redis等数据库镜像;最后是应用镜像,就是指具体的应用服务了,应用镜像可以非常丰富,随时可以发布,这三者之间依次叠加。所以当我们在使用 Docker构建镜像的时候,每一个命令都会在前一个命令的基础上形成一个新镜像层。
如下图,基础镜像就是centos镜像,中间件镜像就是两个红色圈,应用镜像就是紫色圈。其中redis+centos这样叠加组合的中间件镜像就可以供A服务或者B服务使用,这样叠加组合更加灵活。仍和一种镜像都可以从Docker hub公共仓库中拉取。
容器
容器Docker containers,你可以从镜像中创建容器,这如同从快照中创建虚拟机,不过更轻量,启动更快,秒启。应用是在容器中运行的,打个比方,你首先下载了一个Ubuntu的镜像,然后又安装mysql和Django应用及其依赖,来完成对它Ubutun镜像的修改,其它用户通过这个镜像就生成一个容器。容器启动之后就会运行Django服务了。
容器就是一个个独立的封闭的集装箱,但是也需要对外提供服务的,所以Docker允许公开容器的特定端口,在启动Docker的时候,我们就可以将容器的特定端口映射到宿主机上面的任意一个端口,所以,如果几个服务都需要80端口,那么容器的对外端口是80,但是映射到宿主机上面就是任意端口,就不会产生冲突,所以就不需要通过代理来解决冲突。容器对外端口与宿主机的端口映射可以通过下面的命令来完成。
启动docker容器 docker run -d -p 2222 : 22 --name 容器名 镜像名 -d 守护容器,就是后台运行,退出命令窗口容器也不会停止 -it 交互式容器 退出命令窗口容器就停止运行了 -p宿主机端口和容器端口映射 8081 : 80 宿主机端口:容器公开的端口 |
如下图所示:
仓库
仓库Docker registeries,docker仓库和存放集装箱的仓库是一样的,不过docker使用来存放镜像的。仓库存在公有和私有之分,公有仓库docker hub提供了非常多的镜像文件,这些镜像直接拉取下来就可以运行了,你也可以上传自己的镜像到docker hub上面。同时也可以自己搭建私有仓库用于团队项目管理。
结合前面介绍的基本概念,我们可以将docker的几个概念使用大致串起来,他们之间是如何运作的,也就是Docker的生命周期。看下图,主要是三步走。
- 开发构建镜像并将镜像push到Docker仓库
- 测试或者运维从Docker仓库拷贝一份镜像到本地
- 通过镜像文件开启Docker容器并提供服务
为什么用Docker
这要从目前软件行业的痛点来讲起
- 软件更新发布及部署低效,过程繁琐且需要人工介入。
- 环境一致性难以保证。
- 不同环境之间迁移成本太高。
与虚拟机的区别
- Hypervisor,又称虚拟机器监视器(virtual machine monitor, VMM),是用来建立与执行虚拟机器的软件、固件或硬件。
-
VM 的 Hypervisor 对资源进行抽象,着重体现在硬件层面的虚拟化上,要搭载自己的操作系统
-
其中虚拟机操作系统占用内存是比较大的,一个操作系统有好几个G,自然在启动速度和资源利用率以及性能上有非常大的开销
-
如果在本地,或者个人电脑,那么影响还不是那么大,但是在云端就是一个非常大的资源浪费。
所以Docker 应用容器相对于 VM 有以下几个优点:
- 属于OS级别的虚拟化,kernel通过创建多个镜像来隔离不同的app进程,由于kernel是是共享,而且本身linux image也不大,性能损耗几乎可以不计;VM 通常需要额外的 CPU 和内存来完成 OS 的功能,这一部分占据了额外的资源。
- 启动速度快,容器启动本质就是一个开启一个进程而已,因此都是秒启,而 VM 通常要更久。
- 资源利用率高,一台普通 PC 可以跑成百上千个容器。
- 很多移动互联网的应用或者云计算的后端节点都可以用docker来替换物理机器或者虚拟机。
怎么用Docker
架构
- namespaces充当隔离的第一级,是对Docker容器进行隔离,让容器拥有独立的hostname,ip,pid,同时确保一个容器中运行一个进程而且不能看到或影响容器外的其它进程。
- Cgroups是容器对使用的宿主机资源进行核算并限制的关键功能。比如CPU,内存,磁盘等。
- union FS主要是对镜像也就是image这一块作支持,采用copy-on-write技术,让大家可以共用某一层,对于某些差异层的话就可以在差异的内存存储。
- Libcontainer是一个库,是对上面这三项技术做一个封装。
- Docker engine 用来控制容器container的运行,以及镜像文件的拉取。