通过ASP.NET Core 应用镜像创建容器

admin
admin
2021-06-03
分享:

[YoYoMooc]Docker镜像创建容器的几种方法

推荐内容:

孔乙己:茴香豆的茴字有几种写法?

封面

每个容器都是由镜像创建的应用程序的一个实例,并且一个主机系统可以运行多个容器,每个容器都是隔离的。接下来,我将介绍如何创建、使用和管理容器。

创建容器

我们可以从任何镜像创建容器,包括您创建的自定义镜像。

输入以下命令

docker create -p 3000:80 --name exampleApp3000 yoyomooc/exampleapp

说明:

  • docker create命令用于创建一个新的镜像。
  • -p 参数告诉 Docker 如何在容器中映射端口 80到主机操作系统。我指定容器内的端口80映射到主机操作系统中的端口3000。这与Docker中的EXPOSE命令相对应。
  • --name 参数为容器指定了一个名字,这样一来,一旦容器的已经创建了。本例中的名称是 exampleApp3000,表示这个容器将响应于请求发送至主机操作系统中的端口3000。
  • 最后一个参数告诉Docker要使用哪个镜像作为新容器的模板。这个命令指定了yoyomooc/exampleapp镜像,这是docker build中使用的名称。

从镜像中创建附加容器

您可以从一个镜像中创建多个容器,但您必须确保以下内容不冲突配置选项,如名称和端口映射等。现在创建第二个容器,使用不同名称和端口映射的自定义镜像。

docker create -p 4000:80 --name exampleApp4000 yoyomooc/exampleapp

该命令使用yoyomooc/exampleapp 镜像创建了一个名为exampleApp4000的容器。 将端口80映射到主机中的端口4000,这样该容器将能够与实例exampleapp3000容器共存。 因为它们使用不同的网络端口和名称,即使它们包含相同的应用但是也相互不影响。

容器列表

docker ps命令用于排列出系统中存在的容器。默认情况下,docker ps 命令省略了未运行的容器,所以如果要查看所有的可用的容器,请输入以下命令。

docker ps -a

这个命令会产生以下输出。

容器列表

  • CONTAINER ID列,每个容器都被分配了一个唯一的ID,该 ID用于引用Docker命令中的容器。
  • NAMES 列,更自然的方式是使用容器的名称来引用容器。
  • IMAGE列显示用于创建容器的镜像。
  • STATUS(状态)列显示这两个容器的创建状态,表示容器已被创建成功创建并准备好了。
  • PORTS 列是空的, 这是因为当前容器没有被激活启动,所以看到的端口值为空,而当它被激活的时候,将会改变。

启动容器

上一节使用docker create命令从同一个镜像中创建两个容器。这两个容器的内部是完全相同的,并且包含相同的文件。只有在这两个容器外面的配置是不一样的,它们所生成的容器是不同的,Docker允许容器通过使用不同的名称和映射不同的网络端口到容器内的80端口。

然而,目前,容器并没有做任何事情。它们所包含的应用程序也没有运行,因为它们所配置的网络端口没有激活。

docker start 命令用于启动一个或多个容器,这些容器由它们的唯一的 ID 或名称。

运行以下命令:

docker start exampleApp3000

Docker会使用Dockerfile中的ENTRYPOINT命令来启动容器中的应用程序。 在这种情况下,这意味着会启动.NET Core运行时,然后再启动ASP.NET Core Kestrel服务器,这时将监听传入容器内部80端口上的HTTP请求。

当容器启动时,Docker也会设置端口映射,以便于在主机操作系统上的3000端口将被引导到容器内的80端口,使Kestrel服务器能够接收来自容器外部的HTTP请求。

要测试该容器,请打开一个新的浏览器窗口,并请求URL http://localhost:3000,其中 将发送一个HTTP请求到主机操作系统上的3000端口。Docker会将请求引导到端口80在容器内,这样就可以被Kestrel接收,Kestrel将启动ASP.NET Core 和运行MVC示例应用程序。

几秒钟后,你会看到示例MVC应用程序的响应,如图所示。

示例项目

启动所有容器

docker start $(docker ps -aq)

运行上方命令来启动系统上的所有容器。该命令结合了docker startdocker ps命令的输出。

  • 参数 -a 包括未运行的容器,而 -q 参数只返回容器 ID。
  • 该命令的作用是启动该容器的 ID。由于其中一个容器已经在运行,新容器被映射到4000端口,您可以通过浏览器中的URL http://localhost:4000 进行测试。它显示的内容和上图的内容一致,因为他们两个容器都在运行相同的应用程序。

你可以通过运行docker ps -a命令查看容器的状态变化,该命令将产生这样的产出。

容器列表

  • STATUS(状态)列展示两个容器都在运行中,并报告它们已经运行了多长时间。容器运行了多久。

  • PORTS 列显示了每个容器从主机操作系统映射的端口。在这种情况下,你可以看到一个容器将端口 3000 映射到端口 80,另一个容器将端口 4000 也映射到端口 80。

  • 这些容器可以共存,因为容器内的应用程序是相互隔离的。其他容器对映射的系统端口则一无所知。

  • 容器内正在处理HTTP请求的Kestrel服务器开始侦听端口80,它不会发现自己在容器中运行,也不会发现请求是通过主机操作系统上的端口映射来的。通过同一个镜像创建多个端口的相同容器,并通过改变容器的配置来并排运行,这是Docker的一个重要特点。

容器列表

我们会在后面的章节中展示如果将应用程序部署到服务器集群中.

停止容器

可以通过使用docker stop 指定名称停止一个或多个容器。

docker stop exampleApp3000

该命令以停止正在处理主机端口为3000的容器名称。

运行以下命令,返回列表中的容器Id,停止所有正在运行的容器。

docker stop $(docker ps -q)

docker ps命令唯一需要的参数是 -q。没有使用 -a 参数,因为停止命令只需要运行中的容器的ID,docker ps 命令默认情况下进返回运行的容器。

小贴士: 还有一个docker kill命令,会向容器发送杀死信号。我倾向于不使用使用此命令,因为如果容器还没有停止,可以使用参数-t 来设置容器,10秒后发送docker stop命令。

Docker Kill主要流程 1.Docker引擎通过containerd使用SIGKILL发向容器主进程,等待一段时间后,如果从containerd收到容器退出消息,那么容器Kill成功 2.在上一步中如果等待超时,Docker引擎将跳过Containerd自己亲自动手通过kill系统调用向容器主进程发送SIGKILL信号。如果此时kill系统调用返回主进程不存在,那么Docker kill成功。否则引擎将一直死等到containerd通过引擎,容器退出。

https://www.jianshu.com/p/813d8362d497

获取容器输出日志

默认情况下,当您使用docker start命令。容器会保留了一个记录,可以用docker logs命令来检查。

docker logs exampleApp3000

ASP.NET Core运行时每次收到HTTP请求时,都会打印一条消息,而docker logs 命令显示这些消息,看起来像这样。

warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
      Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
      No XML encryptor configured. Key {e52d346f-ec4d-499a-a406-473d1d656e12} may be persisted to storage in unencrypted form.
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://[::]:80
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /app

docker logs命令可以显示容器的最新输出,即使是容器已被停止。对于运行中的容器,你可以使用-f参数来监控输出,所以你会看到所有的新消息。运行以下命令来启动一个容器并监测其输出。

docker start exampleApp3000
docker logs -f exampleApp3000

在浏览器中请求http://localhost:3000,生成一些输出信息。完成后,键入Control+C来停止显示输出信息。而容器不受推出 docker logs命令的影响。

使用一个命令创建和启动容器

docker run命令用于从镜像创建容器,并通过合并docker createdocker start命令的效果在一个步骤中启动它。 运行以下的命令,从自定义镜像中创建和启动容器,并转发端口映射,从主机操作系统中的5000到容器内部80端口的网络流量。

docker run -p 5000:80 --name exampleApp5000 yoyomooc/exampleapp

Docker从yoyomooc/exampleapp镜像中创建容器,设置好端口映射,并分配给 容器的名称为 exampleApp5000。

不同的是,一旦创建了容器,就会启动它。docker run命令会保持容器输出所附带的命令提示符,以便Kestrel服务器生成的消息都会在命令提示符中显示。

要测试新容器,请打开浏览器标签页并请求URL http://localhost:5000。

HTTP发送到5000端口的请求将被Docker接收并转发到容器内的80端口。

呈现的内容与你在前面的例子中看到的MVC应用程序相同。

如果你使用的是Linux或macOS,你可以通过键入Control+C来停止容器。如果你使用的是Windows 系统,Control+C将命令提示符从容器中分离出来,但却让其在后台,您必须运行停止容器命令。

docker stop exampleApp5000

自动删除容器

docker run命令可以使用 --rm 参数,它告诉Docker停止时删除容器。运行此命令,在主机中创建一个映射端口6500映射到新容器中的端口80。

docker run -p 6500:80 --rm --name exampleApp6500 yoyomooc/exampleapp

你可以通过在浏览器中请求http://localhost:6500,然后运行 docker ps 查看容器列表. 检查了容器的工作状态后,使用Control+C停止容器,(仅在Linux或macOS有效)或windows使用此命令。

docker stop exampleApp6500

Docker会在容器停止后立即删除,你可以通过运行docker ps -a 来查看系统中存在的所有容器确认。