首页 > 代码库 > [Docker]保持屋子整洁,开始使用docker

[Docker]保持屋子整洁,开始使用docker

关于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 images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu              latest              9cbaf023786c        7 days ago          192.8 MB

然后,你可以在这个镜像为基础,执行某些操作。如下:

root@docker:~# docker run -it ubuntu /bin/bash
root@ead6f34e1f8e:/#

这样,你就进入了一个容器。新容器并不需要单独创建,只需要以某个镜像为基础,执行某些命令就可以。
注意,新容器就像一个全新安装的精简系统,里面很多指令和程序都默认没有安装,如python, wget, vim等。
下面,在容器里下载nginx:

root@ead6f34e1f8e:/# apt-get update
root@ead6f34e1f8e:/# apt-get install nginx
root@ead6f34e1f8e:/# which nginx
/usr/sbin/nginx
root@ead6f34e1f8e:/# nginx -v
nginx version: nginx/1.4.6 (Ubuntu)
root@ead6f34e1f8e:/# exit

在退出容器之后,使用docker ps -a可以看到停止了的容器:

root@docker:~# docker ps -a
CONTAINER 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/nginx
6d61d587b283fd163a30eff8ec1928b503e1d05de24cb815bc3acc5bc4b4d1ed
root@docker:~# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu/nginx        latest              6d61d587b283        3 seconds ago       231.3 MB
ubuntu              latest              9cbaf023786c        7 days ago          192.8 MB

这样我们就创建了一个新的镜像,里面默认包含了Nginx,以后所有需要nginx运行环境的容器都可以以这个镜像为基础,而不需要重新下载。当然,这里的镜像名字比较随意,此处仅为实验。

root@docker:~# docker run -it ubuntu/nginx /bin/bash
root@3364e69c4654:/# which nginx
/usr/sbin/nginx
root@3364e69c4654:/# nginx -v
nginx version: nginx/1.4.6 (Ubuntu)

进入后可以看到,默认就是上面那个环境。现在退出后,再查看容器:

root@docker:~# docker ps -a
CONTAINER ID        IMAGE                 COMMAND             CREATED             STATUS                      PORTS               NAMES
3364e69c4654        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使用的最基本流程,里面有很多概念包括涉及到的概念(如镜像标签)并没有展开来讲,所以总体是比较粗略的。深入了解可以期待本人后续文章或者直接参看下面的开源图书,这本书很适合想入门的朋友。

资料参考:Docker 从入门到实践

[Docker]保持屋子整洁,开始使用docker