Docker 镜像和容器

608 阅读4分钟

这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战

上一篇:认识 Docker

一个简单的示例

在上一篇的结尾,建议你按照官方的安装文档,自己动手安装 Docker,在步骤的最后,可以通过运行以下命令来验证安装是否成功:

➜  ~ docker run hello-world

如果没有问题的话,控制台会打印类似如下的内容:

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:37a0b92b08d4919615c3ee023f7ddb068d12b8387475d64c622ac30f45c29c51
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

从这里面可以看到,Docker 没有在本地找到 hello-world:latest 镜像,因此,远程拉取了这个镜像,其中 latest 可以理解为版本号,如果在执行命令时没有指定版本号,便会使用最新的版本,也就是 latest

接下来,Hello from Docker! 以及之后的内容,就是运行成功后输出的内容,你可以重点了解一下 To generate this message, Docker took the following steps: 这部分,介绍了为了让这段信息被展示出来,Docker 做了哪些事情:

  1. Docker 客户端连接到了 Docker 守护进程
  2. Docker 守护进程从 Docker Hub 拉取了 hello-world 镜像
  3. Docker 守护进程从这个镜像创建了一个容器,这个容器运行可执行文件并产生了你现在正在读的内容。
  4. Docker 守护进程将输出流传输到 Docker 客户端,后者将其发送到你的终端。

这就是 Docker 通过 hello-world 镜像创建容器并运行的整个过程。下面介绍其中的几个重要概念。

Docker 架构.png

Docker 客户端和守护进程

Docker 是一个 C/S 架构的软件,我们在命令行之行 docker 命令的时候,Docker 的命令行工具会向 Docker 守护进程发送请求,然后再把接收到的结果显示在终端。

我们按照之前的步骤安装 Docker 的时候,是把它的服务端(Docker 守护进程)和客户端(Docker 命令行工具)安装在了同一台机器上,你也可以从一台机器的 Docker 客户端,远程连接到另一台机器的 Docker 守护进程上。

镜像 Image

容器本质上是一个二进制文件,它包含了一个程序以及它运行所需要的环境和配置。镜像是通过一系列的指令构建出来的,比如:添加一个文件、执行一个命令、开放一个端口等等,当完成构建之后,镜像的内容是不可变的。

在实际的开发中,一个镜像往往继承自另一个,然后在其基础上添加更多的指令,构建出新的镜像。例如,你可以基于一个包含 Java 运行环境的镜像,加上自己开发的 Java 程序,形成一个自己的新的镜像。

Registry 和 Docker Hub

Docker 用 Registry 来保存用户构建的镜像,Docker 公司自己运营着一个公共的 Registry 叫 Docker Hub,你可以把它理解为一个保存和分享镜像的 GitHub。

CleanShot 2021-11-02 at 15.42.17@2x.png

许多企业也会部署私有的 Docker Registry 供内部使用。

容器 Container

容器是镜像运行的实例,容器中可以运行一个或者多个进程,我们可以基于一个镜像实例化多个容器,他们的关系类似于面向对象编程中类和对象的关系。

一个容器可以被创建、启动、终止、删除,当一个容器被终止时,它并不会被删除,还可以再次启动。

有些容器运行之后,会自己终止,比如文章开头的 hello-world 镜像生成的容器,有些则会一直运行,除非手动种植,必须提供网络服务的容器。