Docker容器中應用程式的log輸出管理

拾月_發表於2019-05-14

在之前的文章中我們介紹過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主機的關係:

Docker容器中應用程式的log輸出管理

對於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容器中應用程式的log輸出管理

可以通過指令docker volume ls來檢視當前docker主機中建立的volume,如下圖所示:

Docker容器中應用程式的log輸出管理

通過指令docker volume inspect demo-log來檢視建立的demo-log volume的資訊,如圖所示:

Docker容器中應用程式的log輸出管理

通過上圖我們可以看到該volume所在的主機路為"C:\ProgramData\Docker\volumes\common-log\_data"

接下來我們通過docker run指令在建立容器的時候將demo-log volume掛載到容器中的某個路徑上,我們將(使用Log4Net根據log level的不同將log輸出到不同的檔案中)中講解的例子進行容器化,為其新增一個dockerfile檔案,檔案內容如下所示:

Docker容器中應用程式的log輸出管理

通過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 來進行檢視,如下圖所示:

Docker容器中應用程式的log輸出管理

需要注意logs folder是我們的應用程式在寫入log的時候建立的,即log在container中的輸出路徑。

當有log輸出的時候我們就可以在docker主機的volume目錄中看到輸出的log了,如圖所示:

Docker容器中應用程式的log輸出管理

通過指令docker inspect containername我們可以檢視當前container的資訊,其中包含了Mounts資訊,如圖所示:

Docker容器中應用程式的log輸出管理


除了上述方式之外,我們還有另外一種方式進行volume的掛載,即在dockerfile中定義好掛載資訊,我們可以在dockerfile中新增VOLUME demo-log:c:/app/logs 指令來定義掛載資訊,這樣在建立image的時候,掛載資訊就會被新增到image中,同時在建立container的時候會對volume進行建立,這樣我們就不需要預先建立volume了,修改之後的dockerfile如圖所示:

Docker容器中應用程式的log輸出管理

以上就是該篇文章的全部內容,希望通過該篇文章的介紹能加強大家對Volume的理解。


相關資料:

docs.docker.com/storage/

yeasy.gitbooks.io/docker_prac…


上一篇(Docker實踐過程中遇到的問題總結)



相關文章