容器化:从 Docker 开始

如果您开始容器化之旅,首先会遇到的就是 Docker。通过学习本教程,您可以快速入门:它为您提供了可与 Docker、Dockerfile 以及 Red Hat® Quay 容器注册表一起使用的工具。

前提条件

预估时间

完成本教程大约需要您 45 分钟。

Docker

我们需要做的第一件事是安装 Docker。可以通过几种方法进行安装,但是第一个也是最好的方法是前往 Docker 文档站点。尝试使用和维护最新版本的 Docker,并为您的特定操作系统安装该 Docker。

在编写本教程时,有两个主要的 Docker 版本。我想花点时间讨论一下不同的版本。这两个版本分别是 Docker Community Edition (docker-ce) 和 Docker Enterprise Edition (docker-ee)。它们各有优点,并且针对不同的用例。我强烈建议您在学习完本教程后,重新考虑 docker-ce 还是 docker-ee 更适合您。

以下步骤和命令应该在任一版本上均适用,那么,让我们继续。

Docker CLI

安装了 docker 之后,打开命令提示符。在安装过程中,文档可能会要求您运行一个完整性检查。我们将再次运行以下命令,以确保一切正常。

docker run hello-world

您应该会看到类似以下输出的内容。(如果出现错误或不是类似如下的内容,那么说明您的安装未正确设置,您应该在进行其他操作之前先解决此问题。)

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 实例。让我们开始使用该实例。

下面是我希望您尝试的下一个命令。根据您的互联网访问情况,可能需要一些时间来运行,但幸运的是,它将缓存到您的计算机上,稍后我们将再次访问此处。

docker run -it centos:latest /bin/bash

在这个过程中,我们来谈谈发生了什么。当您运行 docker 命令时,您是在告诉 Docker,您需要从公共 Docker Hub 获取 latest 副本,并使用 /bin/bash 的 shell 运行它。 该命令运行到互联网,查看您拥有的版本,检查缓存镜像的 SHA,如果您没有 SHA,那么从 Docker hub 中提取。 为了清楚起见,-itinteractive 方式运行它,并为容器创建 tty。 您现在应该会看到以下内容。

Unable to find image 'centos:latest' locally
latest: Pulling from library/centos
a02a4930cb5d: Pull complete
Digest: sha256:184e5f35598e333bfa7de10d8fb1cebb5ee4df5bc0f970bf2b1e7c7345136426
Status: Downloaded newer image for centos:latest
[root@2de726a5fcb8 /]#

恭喜!现在,您有了第二个正在运行的 Docker 容器。继续并键入 exit,然后再次运行该 docker 命令。

[root@2de726a5fcb8 /]# exit
exit
$ docker run -it centos:latest /bin/bash
[root@583c6cec5d41 /]#

注意,根 @2de726a5fcb8@583c6cec5d41 有何不同?这是因为当您以这种方式创建容器时,它们是临时性的。临时性意味着它们只在运行的时间内存在,所以一旦退出,它们就会消失。稍后我将向您展示如何构建寿命较长的容器。

现在,让我们操作一下容器。利用 CentOS 机器,您具有 yum,那么让我们安装一些内容。

[root@583c6cec5d41 /]# yum install vim

[-- snip --]

Transaction Summary
=======================================================================================================
Install  1 Package (+32 Dependent packages)

Total download size: 19 M
Installed size: 63 M
Is this ok [y/d/N]: y

[-- snip --]

  perl-podlators.noarch 0:2.5.1-3.el7                  perl-threads.x86_64 0:1.87-4.el7
  perl-threads-shared.x86_64 0:1.43-6.el7              vim-common.x86_64 2:7.4.160-5.el7
  vim-filesystem.x86_64 2:7.4.160-5.el7                which.x86_64 0:2.20-7.el7

Complete!
[root@583c6cec5d41 /]#

现在可以在容器中运行 vim 了!试用一下吧。

[root@583c6cec5d41 /]# vim

如果您不知道如何退出 vim,请输入::q,您应该会再次看到命令提示符。

现在再次输入 exit

[root@583c6cec5d41 /]# exit
exit
$ docker run -it centos:latest /bin/bash
[root@86f1f3872cbe /]# vim
bash: vim: command not found
[root@86f1f3872cbe /]# exit
exit
$

再次强调一下,当容器消失时,容器中的所有更改也都将消失。

Dockerfile

我们可以构建容器并对其进行更改,但如何保持更改呢?有几种方法,我鼓励您自己去发现这些方法。但我会向您介绍最常用的方法,那就是使用 Dockerfile

返回至命令提示符,创建一个新目录,并使用选择的 $EDITOR 更改目录,以打开一个名为 Dockerfile 的新文件。

$ mkdir docker-tutorial
$ cd docker-tutorial
$ $EDITOR Dockerfile

我将在此处介绍 Dockerfiles 的重点,但我强烈建议您查看编写 Dockerfile 的最佳实践,以了解它们的功能。

在您的 Dockerfile 中,编写以下内容:

FROM centos:latest
RUN yum install vim -y && mkdir /vim
WORKDIR /vim
ENTRYPOINT ["vim"]

保存文件并确保其名为 Dockerfile

让我们来讨论一下上面四行是什么意思。

  • FROM :通过 centos:latest Docker 镜像创建一个层
  • RUN :通过将 vim 安装到容器中并创建名为 /vim 的目录来构建容器
  • WORKDIR :通知容器工作目录的位置
  • ENTRYPOINT :是在容器启动时运行的命令,而非我们上面操作的 /bin/bash

现在让我们在本地构建。在 Dockerfile 所在目录中运行以下命令,让我们一起看看结果。

$ docker build .
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos:latest
 ---> 1e1148e4cc2c
Step 2/4 : RUN yum install vim -y && mkdir /vim
 ---> Running in ebd37633ab31
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
 * base: mirror.fileplanet.com
 * extras: mirror.ash.fastserv.com
 * updates: www.gtlib.gatech.edu
Resolving Dependencies

[-- snip --]

Step 4/4 : ENTRYPOINT ["vim"]
 ---> Running in 82618eb1e891
Removing intermediate container 82618eb1e891
 ---> eda2652aa25e
Successfully built eda2652aa25e
$

注意:您应该具有另一个散列 eda2652aa25e,请谨记这一点。

恭喜!您已经构建第一个 Dockerfile 和定制 Docker 容器。

现在让我们来试一试。继续运行以下命令:

$ docker run -it eda2652aa25e

您应该会看到 vim 启动!记住,:q 是退出方式,然后您应该会再次看到命令提示符。您可以根据需要多次运行它,并且每次都会有一个新的 vim 实例;但您实际上不能保存任何内容或读取任何内容,因为它是容器,对吧?让我们来解决这个问题。

我们将添加绑定安装和卷,以将本地目录安装到容器中。如果您想了解有关安装和卷的更多信息,我建议从有关如何使用卷的 Docker 文档开始。这是较难的概念之一,但值得您花时间去了解。

在命令行上,创建一个名为 hello 的文件,然后在其中保存单词 hello world

$ EDITOR hello

现在,让我们将本地目录安装到容器中。

$ docker run -it -v ${PWD}:/vim eda2652aa25e

vim 中输入 :e hello。您应该会看到 hello world 出现!如您所见,您打开了在主机上创建的文件,创建了一个带有 vim 的容器,安装了目录,并且能够打开该文件!

如果您愿意,可以输入 i 并输入一些内容。完成后输入 :wq。该容器应该已关闭,然后您可以在命令行上输入以下内容:

$ cat hello
hello world
I added this line from my container
$

注意:很显然,I added this line from my container 是我写的内容。您将会看到自己编写的内容。

太棒了!现在,让我们开始弄清楚如何将此容器分享给全世界。

容器注册表

我要向您介绍名为 Quay.io 的 Red Hat 产品。它是一个基于云的开源公共容器注册表,内置了一些简洁的功能。如果愿意,您可以托管自己的主机,但是本示例仅使用公共主机。

首先,访问 https://quay.io 并创建一个账号。

现在,让我们登录并确定自己的位置。

$ docker login quay.io
Username: jjasghar
Password:
Login Succeeded

我的用户名是“jjasghar”。将用户名更改为您自己的。非常好,现在您已登录。

如果我们要创建一个容器并将其推送到 Quay,实际上会非常简单。我将向您展示命令,然后对其进行解释。

$ docker build -t quay.io/jjasghar/vim .  
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos:latest
latest: Pulling from library/centos
Digest: sha256:76d24f3ba3317fa945743bb3746fbaf3a0b752f10b10376960de01da70685fbd
Status: Downloaded newer image for centos:latest
 ---> 0d120b6ccaa8
 Step 2/4 : RUN yum install vim -y && mkdir /vim
  ---> Running in 4818f1e81f74
    CentOS-8 - AppStream                            3.2 MB/s | 5.8 MB     00:01
    CentOS-8 - Base                                 1.2 MB/s | 2.2 MB     00:01
    CentOS-8 - Extras                               3.6 kB/s | 8.6 kB     00:02
    Dependencies resolved.
    ================================================================================
     Package             Arch        Version                   Repository      Size

[-- snip --]

Complete!
Removing intermediate container 4818f1e81f74
 ---> d566a180f683
Step 3/4 : WORKDIR /vim
 ---> Running in 8b9b16611a82
Removing intermediate container 8b9b16611a82
 ---> 06166d346df4
Step 4/4 : ENTRYPOINT ["vim"]
 ---> Running in 63856bad104f
Removing intermediate container 63856bad104f
 ---> dc5de217e843
Successfully built dc5de217e843
Successfully tagged quay.io/jjasghar/vim:latest
$ docker push quay.io/jjasghar/vim:latest
The push refers to repository [quay.io/jjasghar/vim]
10c0147b9d97: Pushed
291f6e44771a: Pushed
latest: digest: sha256:cf98f2fb8f268020a59363d4ccf2e5963783ce8628478899274485fc7d874bf0 size: 741

如您所见,我像之前一样构建了容器,但是我添加了 -t quay.io/jjasghar/vim:latest 作为“标签”。我告诉 docker 将其发送到另一个注册表,然后发送到默认的 Docker Hub 和我的命名空间。

构建完成后,我只需要使用 docker push quay.io/jjasghar/vim:latest 就可以了!(默认情况下,当您将第一个容器推送到 Quay.io 时,必须将其公开)

前往 https://quay.io/repository/jjasghar/vim?tab=settings 站点(用您的命名空间替换 jjasghar)然后点击公开。现在你可以将其拉到任何联网的机器了 !

接下来,让我们通过运行以下命令来获取容器:

$ docker run -v ${PWD}:/vim -it quay.io/jjasghar/vim:latest
Unable to find image 'quay.io/jjasghar/vim:latest' locally
1: Pulling from jjasghar/vim
a02a4930cb5d: Already exists
209873925a88: Pull complete
Digest: sha256:831fcbac319dda1aab3d022c408ecc5cc1c1b825bcd90fc7694c3d4f0ef4eb9a
Status: Downloaded newer image for quay.io/jjasghar/vim:latest
# and you should see vim now

大功告成!您现在知道如何创建容器并将其发布到 Quay.io 了。

结束语

感谢您学习本教程。希望您对一些通用的 docker 命令、Dockerfiles 的工作方式以及如何使用容器注册表有了更多的了解。如果您有任何疑问或想法,请随时通过 Twitter @jjasghar 与我联系。

现在,您已经完成了本教程的学习,已经知道了如何使用 Docker 和容器注册表,接下来要做些什么?您可以通过我们的 Kubernetes 学习路径,进一步学习容器和编排。

如果您有兴趣进一步试验 Docker,请尝试以下教程:获取对 Docker Hub 公共和私有存储库的访问权限在 Docker 容器中创建数据库以进行本地开发

本文翻译自:Containerization: Starting with Docker(2020-12-03)