Docker 是个啥?

1

  第一次听到 Docker 这个东西已经不记得是什么时候了。大概也就是两年前左右,那时对这些新兴技术也是觉得云里雾里。加上平时也没空去了解,所以也不知道是什么东西。直到去年第一次使用它时才慢慢明白是做什么用,相信有很多同学也和我一样,对 Docker 的概念十分模糊。这里就记录一下 Docker 的相关知识吧。

容器

  容器(container)到底是什么东西?我们再学习 Java Web 开发的时候肯定有听过 Servlet 容器,在生活中我们也有各种容器,锅碗瓢盆杯子都是容器。那他们有什么共同点?就是用来装东西的,只是各自装载的东西不同。Servlet 容器用来装载 Servlet 程序,而 Docker 容器,则是用来装载各种各样的程序。我们可以理解为容器是一个虚拟机,里面可以安装各种各样的程序。每个容器之间是互相隔离的,它们之间可以通过网络进行通信。

注意:Docker 并非是虚拟机,这里将它比作虚拟机只是为了方便理解。相对于虚拟机,Docker 省去了 Guest OS、虚拟化硬件等等步骤。启动速度在几十毫秒内。而虚拟机则需要数分钟。他们的应用场景并不相同,虚拟机往往应用在需要完全隔离环境的场景下。而 Docker 则是隔离应用。

镜像

  Docker 镜像类似我们以往认知中的系统镜像。系统镜像封装了整个系统的所有文件,安装程序等等。Docker 镜像则是一个固化的环境,一般而言这个环境大多数是一个经过简化的 Linux 系统。而容器则是基于镜像运行而来的。这就像上面虚拟机的例子,我们运行一个虚拟机也需要对应的系统。我们还可以在容器中进行一些操作后再固化成一个新的镜像。这样我们可以针对不同程序来制作镜像。然后通过镜像在所有基于 Docker 环境的机器上批量运行N个容器。这也减少了我们在部署程序时由环境因素而引起的客观问题。

安装

  了解了以上概念之后我们可以知道,操作 Docker 最基本的就是操作 Docker 容器、Docker 镜像 这两个东西。接下来我们就要开始使用它了,安装步骤可以通过官网了解到。

2

使用

  接下来就是怎么使用它了,我们知道 Docker 有容器镜像,这里初略列出它们各自的一些操作,所有的 Docker 命令都带有前缀 docker:

  1. 容器

    1. 运行容器

      run 镜像名称 命令 基于某个镜像运行后得到一个容器

    2. 停止容器

      stop 容器id 停止某个容器

    3. 删除容器

      rm 容器id 删除某个容器

    4. 在容器中执行命令

      exec 命令 容器id 在容器中执行命令

    5. 查看容器运行状态

      ps

  2. 镜像

    1. 获取镜像

      pull 镜像名称

    2. 提交镜像

      commit 容器id 镜像名称

    3. 删除镜像

      rmi 镜像名称

容器操作

运行容器

  这些都是最基本的操作,那么我们现在就开始来运行一个容器吧。这个容器基于 ubuntu 制作而成。运行docker run ubuntu /bin/echo "Hello World"

3

格式:docker run 参数 (容器id/容器名称/镜像名称) 命令

这里我们运行了一个基于 ubuntu 镜像的容器,并且运行后执行了 /bin/echo "Hello World" 命令。这里需要说明的是,如果我们以一个本地不存在的镜像来运行容器时,docker 会到官方仓库搜索并 pull 这个镜像。看起来好像就是运行了一个程序一样,其实它是个系统。只是我们让他运行了一个命令后就自动结束了。

运行交互式容器

  交互式容器是什么?上面是最普通的运行一个容器的命令,但是我们说了这个容器其实是个系统。那我们怎么去操作这个系统?这时就需要我们再运行时加上-it命令,以便我们能够对这个容器进行更多操作。运行 docker run -it ubuntu /bin/bash

4

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

5

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

查看容器

  ps 命令是用来查看容器状态的。运行docker ps 命令得到如下结果:

6

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

7

格式:docker ps 参数

有两条记录,CONTAINET ID 代表容器的唯一id,如果觉得 ID不好记,我们可以为容器设置别名。在运行容器时加上 --name 容器名称 参数,例如: docker run --name ubuntu

为什么容器执行完命令就会结束?

  因为系统中没后台驻留的程序,所以命令执行完容器就自动结束了。如果容器中运行 Tomcat、Nginx 等等会驻留在后台的程序,那么容器就会一直处于运行中的状态。直到你手动关闭它。

停止容器

  明白了上面运行容器的操作后,相信这个命令对你而言就是小事一桩。我们先运行一个交互式容器 docker run -it --name ubuntu ubuntu /bin/bash 。然后把它放在一边,打开一个新的终端,运行 docker ps 就能看到正在运行中的容器了。

8

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

9

这个时候 docker ps 看不到该容器,但是 docker ps -a 还是可以看到。如果删除了容器就再也看不到了。

删除容器

  运行 docker rm (容器id/容器名称)

10

镜像操作

​ 这里稍微讲解镜像的拉取,提交,删除操作。除这些外一些高级操作现在暂时不会涉及。

拉取镜像

​ 上面说到在运行容器时,如果对应的镜像没有下载,则会自动先把镜像下载下来然后运行容器。有时候你想自己预先下载镜像,这时候就需要用到 pull 命令。在 Docker Hub 可以搜索到现在官方仓库已有的镜像。例如我们搜索 java 的镜像:

12

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

13

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

14

删除镜像

  当需要删除镜像时只需要执行 docker rmi 镜像名称 即可。需要注意的是,如果该镜像被某个容器使用了,则需要删除容器后才能删除镜像。

提交容器

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