什么是Docker
简单来说,Docker是一种容器化技术,它与传统的虚拟化技术相比更加轻量(启动更快速)。因为传统的虚拟化技术是在计算机上通过软件虚拟出另一套计算机出来,然后再在这个新的虚拟机上安装一套操作系统,所以要启动一台虚拟机,基本比启动一台真实的计算机花费的时间还要长一点。而Docker是直接运行在操作系统上的一个容器(其本质是一个Linux进程)。Docker所做的事情就是通过一些技术手段把这个“进程”(容器)与宿主机隔离(文件系统和网络上的隔离),使宿主机可以通过网络与这个“进程”通信(比如在容器中启动一个Apache服务器)。这样,对宿主机来说,感觉好像是在跟网络上的另一台计算机在通信。这些基本就是容器技术的本核心功能。所以一个容器可以秒级启动,因为本质上它只是操作系统启动一个程序进程,然后再给这个程序加一个套“壳”,使其与宿主机隔离。
Docker为什么会依赖虚拟机?
Linux的进程是只能运行在Linux操作系统上的,(这还用说?)所以如果在Linux系统上使用Docker时,可以直接在容器运行Linux程序。但是如果用户的操作系统是Windows或者Mac的话,就必须要在主机上安装一个虚拟机,然后在虚拟机上安装Linux系统,才能使用Docker来创建容器,运行Linux程序进程。以前安装Docker之前,还需要安装virtualBox之类的虚拟机软件,但是现在好像Docker的安装包里已经自带了一套虚拟机,并且安装好了Linux系统,使用起来就方便多了。
镜像
镜像就相当于一套配置好的系统运行环境的副本。比如说你想运行node程序,可以在Docker hub网站查找有没有现成node的镜像,然后通过一条简单的命令就可以将别人制作好的镜像拉取到本地镜像仓库(很方便有点像git的代码仓库)。
docker pull node
上面的命令会到docker hub镜像仓库上去下载node镜像,运行
docker images
可以查看本地镜像。不想要的镜像可以用下面的命令删除:
docker rmi IMAGE
启动容器
我们可以基于一个镜像来启动容器,比如我们启动之前下载的node镜像的一个容器:
docker run node /bin/echo 'Hello world'
这是屏幕上会打印出Hello world
,运行docker ps
命令发现没有任何container在运行,上面的命令实际上启动了一个node容器,然后执行了命了 /bin/echo 'Hello world'
,然后任务结束后马上又关闭了容器。那么当我们不想立即退出容器,并与容器的命令行进行交互的时候,我们可以运行如下命令:
docker run -t -i node /bin/bash
之后我们看到好像通过命令行登录到了另一台Linux主机上,界面如下:
root@240a12484cd2:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
上面的命令中, -t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上, -i
则让容器的标准输入保持打开。这个所谓的伪终端就是当前的命令行,而他绑定了已经绑定了容器的标准输入,并且命令指定使用bash shell与容器交互,这很像是ssh登录远程的一台linux服务器,但其实你并没有登录到一台linux服务器,而是让Docker(背后是一台linux虚拟机)执行了bash/shell
命令而已。
这时在宿主机上打开另一个命令行窗口,输入docker ps
,可以看到有一个ID为240a12484cd2
的容器正在运行(docker container ls
命令等同于docker ps
命令)。
CZ-20140709-003:~ b05709$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
240a12484cd2 node "/bin/bash" 3 minutes ago Up 3 minutes condescending_poincare
从上面的容器交互窗口输入exit,退出容器交互,此时运行docker ps
发现该容器还在运行。现在如果我想重新进入容器,可以使用命令
docker attach 240a12484cd2
但是使用 attach 命令有时候并不方便。当多个窗口同时 attach 到同一个容器的时候,所有
窗口都会同步显示。当某个窗口因命令阻塞时,其他窗口也无法执行操作了。一个更好的选择是使用exec
命令。
docker exec -it 240a12484cd2 /bin/bash
如果想手动关闭该容器,使用下面的命令:
docker container stop CONTAINER