文/李国柱 git
一直有人说docker是划时代的技术,但看资料介绍,要不是操做方法,要不就是Web 2.0,DevOps,去中心化,云里雾里,不知所云。而不使用的人会以为“就是个轻量化的虚拟机”,这个技术的重要性就被轻飘飘地带过去了。web
本文试图在必定程度上消除这个gap,介绍一下docker的功能,说明为何docker是“划时代的”。笔者对docker的理解还至关初级,但愿更多有经验的维护者不苟指正。docker
Linux服务器由一组用户态应用程序和一个操做系统内核组成,像下面这样:数据库
业务软件面对一个复杂的应用环境。好比一个Web服务器,客户端连上来了,运行一个服务,这个服务以什么权限进行?这个就涉及这个文件系统环境中的一系列配置了,好比鉴权系统的配置,为不一样的服务器选择对应的鉴权系统,这就涉及一组配置文件。而后这个服务用哪几个IP地址?路由怎么配置?这又是一组的配置文件。用哪一个数据库?这又是一组配置。好吧,好比如今我装好了一台Ubuntu Linux系统,我配好了一个Web服务器,交给同事维护,这个同事维护一段时间后,被人DDOS攻击了,他在tcpd里面配置了一个IP过滤,我怎么知道?一个Linux的文件系统里面有几十万个文件啊,他在这里面藏了这么一个配置,你说我怎么找?ubuntu
靠文档化吗?文档和实现的一致性——你告诉我何时被解决过?文档和实现一致是要钱和时间的啊,乖乖。谁能等你?bash
因此,在大规模的云数据机房,是不能这样维护系统的。基本上,你在一台机器上配置好了,你得把这个文件系统整个备份下来,何时把一个环境弄坏了,把它整个废弃掉,从那里从新配一个上线。因此你会看见,在数据机房中,即便一台机器上只跑一个虚拟机,别人也要用虚拟机来跑,由于虚拟机能够把整个文件系统备份,而后全部东西都用这个虚拟机完整地从新跑起来。服务器
docker怎么解决这个问题的呢?docker是一个管理程序,它在你的文件系统中放了不少个完整的子文件系统,让你的业务软件运行在你本身的“名称空间”中,像这样:
好比我先配置好了一个ubuntu,我能够把这个文件系统备份下来,称为ubuntu.tar,而后交给你,你只要运行:
1 |
docker load < ubuntu. tar |
2 |
docker run -P -d --name myubuntu_server ubuntu:latest |
(这里先补充几个docker的基本语义:
保存在docker中能够被单独运行的文件称为一个“image”,好比这里的ubuntu:lastest,其中ubuntu称为“repository”,表示“一类”image,你能够类比为git里的一个branch;lastest称为tag,表示repository的一个版本。
而这里的ubuntu.tar是image的一个备份
把image运行起来,就生成一个container,container是image的运行形态,但和“进程是程序的运行态”不一样的是,container在运行结束后仍然存在(由于你可能修改了image的文件系统中的内容),你能够从新运行它,或者经过commit命令,把它保存为另外一个image)
就能够把个人在这个ubuntu配置的业务软件运行起来了,这个业务软件彻底使用本身的文件系统,和别人都没有关系,它对外使用固定的网络,这些网络的端口都映射到我本地指定的端口上,这样我一台机器上能够随意启动两个Web Server并映射到两个不一样的端口上,好比这样:
1 |
docker run -p 80:8000 -d --name webserver1 ubuntu:latest |
2 |
docker run -p 80:8001 -d --name webserver2 ubuntu:latest |
这两个命令运行了两个ubuntu(版本是latest,假设我在里面配置了Web Server),一个映射到本地的8000端口上,另外一个映射到本地的8001端口上。
你看,这样就把一个复杂的“系统配置”工做,变成一个“应用程序运行”的工做了。
若是你想调整一下ubuntu:latest的配置,很简单,你能够这样:
1 |
docker run -ti --name=myconfig_container ubuntu:latest /bin/ bash |
这样你就能够“进入”这个系统进行配置了,配置完成后,把这个container保存为一个image,就能够被其余人用了:
1 |
docker commit myconfig_container ubuntu:myconfig_version |
这个地方的强悍之处在于,docker用了一个称为aufs的技术,你在ubuntu:lastest中作配置,ubuntu的文件系统假设称为f1,而后你在myconfig_container中对f1进行修改,修改的内容并不会修改到f1中,而是修改在f1a文件中。aufs的做用是,它能够把这些f1, f1a, f
2a, f3a……所有叠加起来,做为一个文件系统来用。因此你的myconfig_container并不会覆盖ubuntu:latest,而是针对ubuntu:latest的一个patch。
若是读者熟悉git,很容易就明白这意味着什么了,这表示你是像开发软件和进行版本管理同样维护整批整批的服务器文件系统,而且能够任意把它们部署到网络中的任何一台支持docker的服务器上。
这个设计完全改变了咱们对一个“网络服务”的见解,让它从“一台机器”退化回“一个程序”。它的影响是深远的,首先是guest文件系统的设计变得简化,只要能支持启动一组服务器程序就能够了。不须要复杂的init.d服务,不须要复杂的本地鉴权设计(固然,应用自己的鉴权仍是须要),不须要考虑硬件兼容性(由于对OS的抽象都是同样的),这些变化是要踩到不少服务器OSV,IBV的尾巴的。
另外一方面是Host OS的设计也会变得简化,如今的CoreOS和RancherOS的出现就是例子,这二者都提供了一个最简化(只能运行docker)的基础操做系统。这个操做系统没有复杂的包管理,没有不少的软件,它就干一件事,让你用docker运行其余操做系统。
你说,是否有这么一天?:咱们买一台服务器,它提供的再也不是UEFI接口,让你安装操做系统,而是直接给你一个RancherOS,而后要配置硬件,均可以直接用OS级别的功能完成,而后,你须要运行Redhat就运行Redhat,须要运行Suse就运行Suse?
这一切,说到底,就是服务器已经太强大了,到了能够作减法的时候了。