0%

【Docker】偵錯技巧

/images/20190221/02/1.jpg

學習 Docker 最先碰到的困擾應該都是究竟該如何偵錯 ,畢竟 Docker Run Container 如果沒有下一些指令,通常都是執行完就砍掉,什麼都沒留下,不像在本機可以透過開發的 IDE、Log … 等手段來 Debug,所以這邊就寫下一些我較常使用的偵錯方式


Run

如果 Build Docker Image 時就有指定 CMD 或是 ENTRYPOINT,那 Container Run 起來後跑完就關掉了,這時候可以透過 Run 的最後一個參數來覆蓋過原本的 CMD 指令。

1
$ docker run -it mcr.microsoft.com/windows/nanoserver:1809 cmd.exe

這邊的 cmd.exe 就是要覆蓋 Build Image 所指定的指令,讓你可以進入 Container 的 terminal 中執行你想做的指令


Volume

因為 Container 每次執行都是全新的,所以導致 Log 不易保留,但我們可以 Volume 的方式將 Host Folder 與 Container 內的 Log Folder Mount ,這樣就可以將 Container 內的 Log File 寫出來,達到持久化的效果。

/images/20190221/02/2.png

(圖片來源 : Docker Docs )

接著用簡單的範例來展示一下

1
$ docker run -it mcr.microsoft.com/windows/nanoserver:1809 cmd.exe

進到 Container 後,隨便寫個檔案

1
2
3
4
$ mkdir log
$ cd log
$ echo "hi" >> test.txt
$ dir

/images/20190221/02/3.png

可以看到在 Container 內的確長出了 C:\log 資料夾,並且裡面有個 test.txt 的檔案,檔案裡面寫著 “hi”。但這時候你在 host 機器應該找不到對應的檔案,因為 Container 是彼此獨立且隔離的。

這時候離開 Container 再重啟一次,會發現剛剛 log 的 Folder 已經消失,因為這個 Container 是全新的

1
2
3
$ exit
$ docker run -it mcr.microsoft.com/windows/nanoserver:1809 cmd.exe
$ dir

/images/20190221/02/4.png


Volume 使用方式

1
docker run -v HostFolderPath:ContainerFolderPath 

加上 Volume 參數再重新執行一次剛剛的步驟

1
$ docker run -it -v c:\files:c:\log mcr.microsoft.com/windows/nanoserver:1809 cmd.exe

將 Host 機器的 c:\files Folder Mount 到 Container 內的 c:\log 資料夾,所以在 Container 內新增檔案寫 Log 也會同時寫出來

/images/20190221/02/5.png

這邊應該會注意到,因為 Volume 了 Container 內原本不存在的 log 資料夾,所以一進去的時候它就長出來了,並不需要特別另外建立。


EXEC

有時候 Container 內執行的是常駐程式,它可能會持續執行直到任務完成,如果又沒有將 Log 寫出來的必要,其實很難知道它目前的狀況為何,這時候 EXEC 就派上用場了,它可以讓你進入一個正在執行中的 Container 中。

一樣用個簡單的範例來演練一下

先 Run 一個 Container 起來,並且一樣寫一個 log 下來

1
2
3
4
5
$ docker run -it mcr.microsoft.com/windows/nanoserver:1809 cmd.exe
$ mkdir log
$ cd log
$ echo "hi" >> test.txt
$ dir

/images/20190221/02/6.png

這時候開另一個 terminal,先查詢剛剛的 Container ID

1
$ docker ps

/images/20190221/02/7.png

透過 EXEC 指定要執行哪個 Container

1
$ docker exec -it d24e6db4de85 cmd.exe

/images/20190221/02/8.png

可以看到一進去就已經有剛剛我們寫下的 test.txt,表示這是同一個 Container,或是可以透過 hostname 來做驗證,可以得到相同的 ID

/images/20190221/02/9.png