关于Docker
Docker是一个使用Go语言编写的虚拟化解决方案,非常轻量、易于使用。
为什么要使用Docker
至于为什么要使用Docker,相信你可以很轻松地在网上找到许多使用Docker的优点。一次配置、到处运行,更高效的虚拟化,更简单地管理等等。 但是,对于我个人来说,使用Docker,可以让我的工作环境变得整洁、干净。说到这里,就要说一下工作方式了。
1. 石器时代
在最开始时候,个人电脑就是工作电脑,工作娱乐都是在同一台电脑上进行的。一般情况下,会稍微对它们做下整理,比如放到不同文件夹,或者放到不同的磁盘。但是不管怎样,随着软件安装、删除、升级,文件的增删,慢慢的电脑中的文件碎片就越来越多。常见的比如windows电脑C盘越来越大,里面都是一些奇怪文件名的文件,都不知道哪些可以删,哪些不可以删,最后索性重装系统。
2. 青铜时代
在了解过一些虚拟机以及双系统的知识后,可以会选择安装双系统、装虚拟机,来保证工作环境的隔离。比如我以前就用Virtualbox装不同的系统做不同的事情。但是这类虚拟机启动缓慢,抽象看来它就是另外一台电脑,所以只是你的一台电脑变成两台或者多台电脑而已。
3. 工业时代
除了虚拟机启动缓慢、效率性能比较低之外,一台电脑还是同一套环境,如果你想切换环境,还是比较麻烦。比如你要做一个项目使用的是PHP5.3,但是你想试用PHP5.5的新特性时候就会比较麻烦。Docker的出现,可以比较好地解决其中某些问题。
Docker的使用
Docker是一个轻量级的虚拟化解决方案,你可以实现秒级的虚拟机启动、非常轻量级的虚拟化。个人使用理解看来,它可以实现一个类似于版本管理Git一样的轻量化的状态保存。
Docker有两个非常重要的概念: 镜像和容器。
镜像是呈载容器的实体,所有容器都是运行在镜像之上。用版本管理的角度来看,镜像就像是某一个节点,它可以派生出不同的分支,你可以在不同分支上做不同的事情。可以想象成一棵树,最基本的镜像是主树干,主树干可以分出旁支树干,而旁支树干可以分出更细的旁支,而树干上可以生长树枝。
比如,你使用Docker,从官方仓库下载一个ubuntu镜像,把它作为最基础的镜像。然后在上面运行一个容器,这个容器里下载Nginx,再以这个容器为基础生成一个新的镜像,以后这个镜像生成的容器就都是ubuntu+nginx为基础。但是你工作环境可能需要你使用Apache来工作,你也想有一个ubuntu+apache为基础的镜像,于是你可以使用最基础的ubuntu镜像运行一个容器,在里面下载安装Apache,然后以这个容器为基础,保存一个ubuntu+apache的镜像,以后在这个镜像基础上运行的所有容器都拥有了一个apache环境。
操作流程 在安装完Docker之后(这里以本机ubuntu操作系统为例):# docker pull ubuntu
这样通过pull会从官方仓库下载一个最新构建的ubuntu镜像下来:root@docker:~# docker imagesREPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZEubuntu latest 9cbaf023786c 7 days ago 192.8 MB
然后,你可以在这个镜像为基础,执行某些操作。如下:root@docker:~# docker run -it ubuntu /bin/bashroot@ead6f34e1f8e:/#
这样,你就进入了一个容器。新容器并不需要单独创建,只需要以某个镜像为基础,执行某些命令就可以。 注意,新容器就像一个全新安装的精简系统,里面很多指令和程序都默认没有安装,如python, wget, vim等。 下面,在容器里下载nginx:root@ead6f34e1f8e:/# apt-get updateroot@ead6f34e1f8e:/# apt-get install nginxroot@ead6f34e1f8e:/# which nginx/usr/sbin/nginx
root@ead6f34e1f8e:/# nginx -vnginx version: nginx/1.4.6 (Ubuntu)root@ead6f34e1f8e:/# exit
在退出容器之后,使用docker ps -a可以看到停止了的容器:root@docker:~# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ead6f34e1f8e ubuntu:latest "/bin/bash" 9 minutes ago Exited (0) 44 seconds ago suspicious_rosalind
这里显示的一些东西:CONTAINER ID: 容器的ID
IMAGE: 容器所使用的镜像
COMMAND: 建立容器时候使用的命令
CREATED: 创建时间
STATUS: 当前状态
PORTS: 端口映射(默认为无)
NAMES: 容器的名字
通过上面已经下载Nginx的容器,我们可以创建一个新的镜像:root@docker:~# docker commit -m 'add nginx' ead6f34e1f8e ubuntu/nginx6d61d587b283fd163a30eff8ec1928b503e1d05de24cb815bc3acc5bc4b4d1ed
root@docker:~# docker imagesREPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZEubuntu/nginx latest 6d61d587b283 3 seconds ago 231.3 MBubuntu latest 9cbaf023786c 7 days ago 192.8 MB
这样我们就创建了一个新的镜像,里面默认包含了Nginx,以后所有需要nginx运行环境的容器都可以以这个镜像为基础,而不需要重新下载。当然,这里的镜像名字比较随意,此处仅为实验。root@docker:~# docker run -it ubuntu/nginx /bin/bashroot@3364e69c4654:/# which nginx/usr/sbin/nginx
root@3364e69c4654:/# nginx -vnginx version: nginx/1.4.6 (Ubuntu)
进入后可以看到,默认就是上面那个环境。现在退出后,再查看容器:root@docker:~# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES3364e69c4654 ubuntu/nginx:latest "/bin/bash" 3 minutes ago Exited (0) 3 seconds ago happy_curie
ead6f34e1f8e ubuntu:latest "/bin/bash" 23 minutes ago Exited (0) 14 minutes ago suspicious_rosalind
这里就可以看到,有了两个停止的容器。另外,容器ID就是容器的主机名。
你可以创建很多容器,仅消耗很少一部份资源,就可以拥了很多隔离的环境。而且,你可以把这样的环境保存起来,推送到某一个docker仓库中去,然后在生产环境再次下载运行。这样就达到了生产和开发环境的一致性,也就是一次开发到处运行。
使用docker遇到的问题
由于个人电脑为OS X,所以运行docker需要同时安装boot2docker这个程序,而且需要virtualbox的配合,具体可以参见Mac OS X系统安装说明。如果使用了Homebrew,可以直接使用brew install docker boot2docker来安装。但是如果以前安装过,或者更新,可能会有一些问题,很常见的如:Error response from daemon: client and server don't have same version (client : 1.15, server: 1.13)
这个问题说明服务端和客户端版本不一致(在linux系统上应该不会出现这样的问题),主要是boot2docker引起的。如果遇到这样的问题,更新下boot2docker就可以了。注意,这里不是重新下载安装boot2docker:boot2docker download
boot2docker restart
或boot2docker upgrade
后记
这篇文章只是大概地讲述了一下Docker使用的最基本流程,里面有很多概念包括涉及到的概念(如镜像标签)并没有展开来讲,所以总体是比较粗略的。深入了解可以期待本人后续文章或者直接参看下面的开源图书,这本书很适合想入门的朋友。