
第一次听到 Docker 这个东西已经不记得是什么时候了。大概也就是两年前左右,那时对这些新兴技术也是觉得云里雾里。加上平时也没空去了解,所以也不知道是什么东西。直到去年第一次使用它时才慢慢明白是做什么用,相信有很多同学也和我一样,对 Docker 的概念十分模糊。这里就记录一下 Docker 的相关知识吧。
容器
容器(container)到底是什么东西?我们再学习 Java Web 开发的时候肯定有听过 Servlet 容器,在生活中我们也有各种容器,锅碗瓢盆杯子都是容器。那他们有什么共同点?就是用来装东西的,只是各自装载的东西不同。Servlet 容器用来装载 Servlet 程序,而 Docker 容器,则是用来装载各种各样的程序。我们可以理解为容器是一个虚拟机,里面可以安装各种各样的程序。每个容器之间是互相隔离的,它们之间可以通过网络进行通信。
注意:Docker 并非是虚拟机,这里将它比作虚拟机只是为了方便理解。相对于虚拟机,Docker 省去了 Guest OS、虚拟化硬件等等步骤。启动速度在几十毫秒内。而虚拟机则需要数分钟。他们的应用场景并不相同,虚拟机往往应用在需要完全隔离环境的场景下。而 Docker 则是隔离应用。
镜像
Docker 镜像类似我们以往认知中的系统镜像。系统镜像封装了整个系统的所有文件,安装程序等等。Docker 镜像则是一个固化的环境,一般而言这个环境大多数是一个经过简化的 Linux 系统。而容器则是基于镜像运行而来的。这就像上面虚拟机的例子,我们运行一个虚拟机也需要对应的系统。我们还可以在容器中进行一些操作后再固化成一个新的镜像。这样我们可以针对不同程序来制作镜像。然后通过镜像在所有基于 Docker 环境的机器上批量运行N个容器。这也减少了我们在部署程序时由环境因素而引起的客观问题。
安装
了解了以上概念之后我们可以知道,操作 Docker 最基本的就是操作 Docker 容器、Docker 镜像 这两个东西。接下来我们就要开始使用它了,安装步骤可以通过官网了解到。

使用
接下来就是怎么使用它了,我们知道 Docker 有容器和镜像,这里初略列出它们各自的一些操作,所有的 Docker 命令都带有前缀 docker:
容器
运行容器
run 镜像名称 命令基于某个镜像运行后得到一个容器停止容器
stop 容器id停止某个容器删除容器
rm 容器id删除某个容器在容器中执行命令
exec 命令 容器id在容器中执行命令查看容器运行状态
ps
镜像
获取镜像
pull 镜像名称提交镜像
commit 容器id 镜像名称删除镜像
rmi 镜像名称
容器操作
运行容器
这些都是最基本的操作,那么我们现在就开始来运行一个容器吧。这个容器基于 ubuntu 制作而成。运行docker run ubuntu /bin/echo "Hello World" :

格式:docker run 参数 (容器id/容器名称/镜像名称) 命令
这里我们运行了一个基于 ubuntu 镜像的容器,并且运行后执行了 /bin/echo "Hello World" 命令。这里需要说明的是,如果我们以一个本地不存在的镜像来运行容器时,docker 会到官方仓库搜索并 pull 这个镜像。看起来好像就是运行了一个程序一样,其实它是个系统。只是我们让他运行了一个命令后就自动结束了。
运行交互式容器
交互式容器是什么?上面是最普通的运行一个容器的命令,但是我们说了这个容器其实是个系统。那我们怎么去操作这个系统?这时就需要我们再运行时加上-it命令,以便我们能够对这个容器进行更多操作。运行 docker run -it ubuntu /bin/bash :

看,是不是跟普通的 linux 系统一样?

基本的 shell 命令都没问题,最后我们退出这个容器。现在是不是能理解为什么要把它比喻为虚拟机了吧?这个时候同学们又要问了,要是我运行的时候忘记加 -it 了怎么办?这个时候只需要重新运行这个容器就可以了 docker run -it 容器id /bin/bash
查看容器
ps 命令是用来查看容器状态的。运行docker ps 命令得到如下结果:

没有任何正在运行的容器,因为我们上面运行的容器都在执行完命令后自动结束了,所以这里看不到。我们需要加上 -a 参数查看所有容器,运行 docker ps -a :

格式:docker ps 参数
有两条记录,CONTAINET ID 代表容器的唯一id,如果觉得 ID不好记,我们可以为容器设置别名。在运行容器时加上 --name 容器名称 参数,例如: docker run --name ubuntu
为什么容器执行完命令就会结束?
因为系统中没后台驻留的程序,所以命令执行完容器就自动结束了。如果容器中运行 Tomcat、Nginx 等等会驻留在后台的程序,那么容器就会一直处于运行中的状态。直到你手动关闭它。
停止容器
明白了上面运行容器的操作后,相信这个命令对你而言就是小事一桩。我们先运行一个交互式容器 docker run -it --name ubuntu ubuntu /bin/bash 。然后把它放在一边,打开一个新的终端,运行 docker ps 就能看到正在运行中的容器了。

现在我们看到容器id和容器名称了,运行 docker stop (容器id/容器名称) 就可以停止它了。

这个时候 docker ps 看不到该容器,但是 docker ps -a 还是可以看到。如果删除了容器就再也看不到了。
删除容器
运行 docker rm (容器id/容器名称) :

镜像操作
这里稍微讲解镜像的拉取,提交,删除操作。除这些外一些高级操作现在暂时不会涉及。
拉取镜像
上面说到在运行容器时,如果对应的镜像没有下载,则会自动先把镜像下载下来然后运行容器。有时候你想自己预先下载镜像,这时候就需要用到 pull 命令。在 Docker Hub 可以搜索到现在官方仓库已有的镜像。例如我们搜索 java 的镜像:

点击第一个进去,查看tag 能看到很多不同的镜像。

这时我们可以选择一个然后 pull 到本地:

删除镜像
当需要删除镜像时只需要执行 docker rmi 镜像名称 即可。需要注意的是,如果该镜像被某个容器使用了,则需要删除容器后才能删除镜像。
提交容器
从 Docker Hub 可以看到,有各种镜像。它们都是怎么做的?结合上面的知识,我们可以在 Ubuntu 容器中安装 Java,安装 Tomcat。最后把它 commit 成一个新镜像,最后我们就得到一个可以运行 Java Web 应用的镜像啦。运行一个交互式容器,在其中安装需要的软件,最后执行 docker commit (容器id/容器名称) 镜像名称 就可以把容器固化为一个镜像啦。然后我们只要以新镜像为基础运行容器就可以了。