将 Go 镜像作为容器运行

先决条件

完成构建 Go 映像中容器化 Go 应用程序的步骤 。

概述

在上一个模块中,您Dockerfile为示例应用程序创建了一个,然后使用命令创建了 Docker 映像docker build。现在您已经有了该映像,您可以运行该映像并查看您的应用程序是否正常运行。

容器是一个普通的操作系统进程,只不过这个进程是隔离的,有自己的文件系统、自己的网络以及与主机分离的自己的隔离进程树。

要在容器内运行映像,请使用该docker run命令。它需要一个参数,那就是图像名称。启动您的映像并确保其正常运行。在终端中运行以下命令。

$ docker run docker-gs-ping
   ____    __
  / __/___/ /  ___
 / _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.10.2
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
                                    O\
⇨ http server started on [::]:8080

当您运行此命令时,您会注意到您没有返回到命令提示符。这是因为您的应用程序是 REST 服务器,并且将在循环中运行,等待传入请求,而不将控制权返回给操作系统,直到您停止容器。

使用curl 命令向服务器发出GET 请求。

$ curl http://localhost:8080/
curl: (7) Failed to connect to localhost port 8080: Connection refused

您的curl 命令失败,因为与您的服务器的连接被拒绝。这意味着您无法连接到端口 8080 上的本地主机。这是预期的,因为您的容器正在隔离运行,其中包括网络。停止容器并使用本地网络上发布的端口 8080 重新启动。

要停止容器,请按 ctrl-c。这将使您返回到终端提示符。

要为容器发布端口,您将在命令中使用标志--publish-p简称)docker run。命令的格式--publish[host_port]:[container_port].因此,如果您想将8080容器内部的端口公开到3000容器外部的端口,您可以传递3000:8080--publish标志。

启动容器并将端口公开到主机上的8080端口。8080

$ docker run --publish 8080:8080 docker-gs-ping

现在,重新运行curl 命令。

$ curl http://localhost:8080/
Hello, Docker! <3

成功!您能够连接到在端口 8080 上的容器内运行的应用程序。切换回容器正在运行的终端,您应该会看到GET记录到控制台的请求。

ctrl-c停止容器。

以分离模式运行

到目前为止这很棒,但是您的示例应用程序是一个 Web 服务器,您不必将终端连接到容器。 Docker 可以在后台以分离模式运行容器。为此,您可以 简称为--detach-d。 Docker 将像以前一样启动您的容器,但这次将与容器分离并将您返回到终端提示符。

$ docker run -d -p 8080:8080 docker-gs-ping
d75e61fcad1e0c0eca69a3f767be6ba28a66625ce4dc42201a8a323e8313c14e

Docker 在后台启动容器并在终端上打印容器 ID。

再次确保您的容器正在运行。运行相同的curl命令:

$ curl http://localhost:8080/
Hello, Docker! <3

列出容器

由于您在后台运行容器,因此如何知道您的容器是否正在运行或者您的计算机上正在运行哪些其他容器?那么,要查看计算机上运行的容器列表,请运行docker ps。这类似于如何使用 ps 命令查看 Linux 计算机上的进程列表。

$ docker ps

CONTAINER ID   IMAGE            COMMAND             CREATED          STATUS          PORTS                    NAMES
d75e61fcad1e   docker-gs-ping   "/docker-gs-ping"   41 seconds ago   Up 40 seconds   0.0.0.0:8080->8080/tcp   inspiring_ishizaka

ps命令告诉您许多有关正在运行的容器的信息。您可以查看容器 ID、容器内运行的映像、用于启动容器的命令、创建容器的时间、状态、公开的端口以及容器的名称。

您可能想知道容器的名称来自哪里。由于启动时没有为容器提供名称,因此 Docker 生成了一个随机名称。您很快就会解决这个问题,但首先您需要停止容器。要停止容器,请运行docker stop命令,并传递容器的名称或 ID。

$ docker stop inspiring_ishizaka
inspiring_ishizaka

现在重新运行该docker ps命令以查看正在运行的容器的列表。

$ docker ps

CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

停止、启动和命名容器

Docker 容器可以启动、停止和重新启动。当您停止容器时,它不会被删除,但状态会更改为已停止,并且容器内的进程也会停止。运行该docker ps命令时,默认输出仅显示正在运行的容器。如果您通过简称--all-a,您将看到系统上的所有容器,包括已停止的容器和正在运行的容器。

$ docker ps --all

CONTAINER ID   IMAGE            COMMAND                  CREATED              STATUS                      PORTS     NAMES
d75e61fcad1e   docker-gs-ping   "/docker-gs-ping"        About a minute ago   Exited (2) 23 seconds ago             inspiring_ishizaka
f65dbbb9a548   docker-gs-ping   "/docker-gs-ping"        3 minutes ago        Exited (2) 2 minutes ago              wizardly_joliot
aade1bf3d330   docker-gs-ping   "/docker-gs-ping"        3 minutes ago        Exited (2) 3 minutes ago              magical_carson
52d5ce3c15f0   docker-gs-ping   "/docker-gs-ping"        9 minutes ago        Exited (2) 3 minutes ago              gifted_mestorf

如果您一直在关注,您应该会看到列出的几个容器。这些是您启动和停止但尚未删除的容器。

重新启动刚刚停止的容器。找到容器的名称并在以下命令中替换容器的名称restart

$ docker restart inspiring_ishizaka

现在,使用以下命令再次列出所有容器ps

$ docker ps -a

CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS                     PORTS                    NAMES
d75e61fcad1e   docker-gs-ping   "/docker-gs-ping"        2 minutes ago    Up 5 seconds               0.0.0.0:8080->8080/tcp   inspiring_ishizaka
f65dbbb9a548   docker-gs-ping   "/docker-gs-ping"        4 minutes ago    Exited (2) 2 minutes ago                            wizardly_joliot
aade1bf3d330   docker-gs-ping   "/docker-gs-ping"        4 minutes ago    Exited (2) 4 minutes ago                            magical_carson
52d5ce3c15f0   docker-gs-ping   "/docker-gs-ping"        10 minutes ago   Exited (2) 4 minutes ago                            gifted_mestorf

请注意,您刚刚重新启动的容器已以分离模式启动,并且端口已8080公开。另请注意,容器的状态为Up X seconds。当您重新启动容器时,它将使用与最初启动时相同的标志或命令来启动。

停止并删除所有容器,然后查看修复随机命名问题。

停止刚刚启动的容器。找到正在运行的容器的名称,并将以下命令中的名称替换为系统上容器的名称:

$ docker stop inspiring_ishizaka
inspiring_ishizaka

现在所有容器都已停止,请将其删除。当容器被删除时,它不再运行,也不处于停止状态。相反,容器内的进程将被终止,容器的元数据将被删除。

要删除容器,请运行docker rm传递容器名称的命令。您可以在一个命令中将多个容器名称传递给该命令。

再次确保将以下命令中的容器名称替换为系统中的容器名称:

$ docker rm inspiring_ishizaka wizardly_joliot magical_carson gifted_mestorf

inspiring_ishizaka
wizardly_joliot
magical_carson
gifted_mestorf

再次运行该docker ps --all命令以验证所有容器是否都已消失。

现在,解决讨厌的随机名称问题。标准做法是为容器命名,原因很简单,因为可以更轻松地识别容器中运行的内容以及与它关联的应用程序或服务。就像代码中变量的良好命名约定可以使其更易于阅读一样。命名容器也是如此。

要命名容器,您必须将--name标志传递给run命令:

$ docker run -d -p 8080:8080 --name rest-server docker-gs-ping
3bbc6a3102ea368c8b966e1878a5ea9b1fc61187afaac1276c41db22e4b7f48f
$ docker ps

CONTAINER ID   IMAGE            COMMAND             CREATED          STATUS          PORTS                    NAMES
3bbc6a3102ea   docker-gs-ping   "/docker-gs-ping"   25 seconds ago   Up 24 seconds   0.0.0.0:8080->8080/tcp   rest-server

现在,您可以根据名称轻松识别您的容器。

下一步

在本模块中,您学习了如何运行容器和发布端口。您还学习了管理容器的生命周期。然后您了解了为容器命名的重要性,以便更容易识别它们。在下一个模块中,您将学习如何在容器中运行数据库并将其连接到您的应用程序。