Docker容器中应用程序的log输出管理

3,898 阅读5分钟

在之前的文章中我们介绍过Docker相关的基础知识,同时在文章(使用Log4Net根据log level的不同将log输出到不同的文件中)中介绍了log4net的使用,本篇文章我们将结合两者来介绍如何将docker容器中应用程序的log输出到docker主机中。说到docker中应用程序log的输出,我们需要先来了解一下Docker的数据管理机制。

Docker数据管理

默认情况下,容器内创建的所有文件都存储在可写容器层上,这意味着:

当该容器不再存在时,数据不会持久,并且如果另一个进程需要数据,则很难将数据从容器中取出。容器的可写层与运行容器的主机紧密耦合,我们不能轻易地将数据移动到其他地方。

幸运的是Docker为容器提供了两个选择来在主机中存储文件,这样即使在容器停止或者删除之后,这些文件也会被持久化。这两种方式就是:Volume和Bind Mounts, 当然如果你是在linux上运行Docker,还可以使用tmpfs mount。

volume(数据卷): volume存储在由Docker管理的主机文件系统的一部分中。非docker

进程不应该修改文件系统的这一部分。Volume是在Docker中持久化数据的最佳方案。

bind mounts(挂载主机目录): bind mounts可以存储在主机系统的任何位置。它们甚至可能是非常重要的系统文件或目录。Docker主机或Docker容器上的非Docker进程可以随时修改它们。

tmpfs mount: 只存储在主机系统的内存中,并且从不写入主机系统的文件系统中。

下图展示了三种数据持久化中container与Docker主机的关系:


对于volume的简单理解就是,在docker主机中创建一个volume,该volume存储在Docker管理的主机文件系统中,如上图中所示的Docker area,通过将该volume与container中的某个文件或目录进行挂载(我个人更喜欢将挂载叫为映射)来实现对相应的目录或文件的数据进行持久化。

本篇文章我们主要介绍基于volume来实现容器内应用程序log的输出。Volume是一个可供一个或多个容器使用的特殊目录,它绕过UFS(Union File System), 提供类似如下特性:

  • volume可以在容器之间共享和重用
  • 对volume的修改会立马生效
  • 对volume的更新,不会影响镜像
  • volume默认会一直存在,即使容器被删除


Volume的创建

我们可以通过指令docker volume create volume-name在docker主机中创建一个volume,如docker volume create demo-log,通过这个指令我们在docker主机中创建一个名为demo-log的volume,如下图所示:


可以通过指令docker volume ls来查看当前docker主机中创建的volume,如下图所示:


通过指令docker volume inspect demo-log来查看创建的demo-log volume的信息,如图所示:


通过上图我们可以看到该volume所在的主机路为"C:\ProgramData\Docker\volumes\common-log\_data"

接下来我们通过docker run指令在创建容器的时候将demo-log volume挂载到容器中的某个路径上,我们将(使用Log4Net根据log level的不同将log输出到不同的文件中)中讲解的例子进行容器化,为其添加一个dockerfile文件,文件内容如下所示:


通过docker build -t logdemo:v1 . 指令创建一个名为logdemo:v1的image,然后通过指令

docker run -d -p 5001:80 --name logdemocontainer --mount source=demo-log,target=c:/app/logs logdemo:v1 

来创建一个名为logdemocontainer的容器,并将demo-log volume挂载到容器中的logs文件夹,这样logs文件夹中的log就会同时映射到docker主机的demo-log中,大家可能会有疑问:我是怎么知道container中有c:/app/logs目录的,这个在dockerfile中已经设置了workdir为app,所以app目录是一定在container中存在的,至于是存在于哪个盘中我们可以通过指令docker inspect logdemo:v1 来进行查看,如下图所示:


需要注意logs folder是我们的应用程序在写入log的时候创建的,即log在container中的输出路径。

当有log输出的时候我们就可以在docker主机的volume目录中看到输出的log了,如图所示:


通过指令docker inspect containername我们可以查看当前container的信息,其中包含了Mounts信息,如图所示:



除了上述方式之外,我们还有另外一种方式进行volume的挂载,即在dockerfile中定义好挂载信息,我们可以在dockerfile中添加VOLUME demo-log:c:/app/logs 指令来定义挂载信息,这样在创建image的时候,挂载信息就会被添加到image中,同时在创建container的时候会对volume进行创建,这样我们就不需要预先创建volume了,修改之后的dockerfile如图所示:


以上就是该篇文章的全部内容,希望通过该篇文章的介绍能加强大家对Volume的理解。


相关资料:

docs.docker.com/storage/

yeasy.gitbooks.io/docker_prac…


上一篇(Docker实践过程中遇到的问题总结)

下一篇(灵活设置Docker容器内.net core app的配置文件信息)