1. 程式人生 > 其它 >dataguard歸檔路徑的問題(r7筆記第99天)

dataguard歸檔路徑的問題(r7筆記第99天)

exec 模式

使用 exec 模式時,容器中的任務程序就是容器內的 1 號程序,看下面的例子:

FROM ubuntu
CMD [ "top" ]

把上面的程式碼儲存到 test1 目錄的 Dockerfile 中,然後進入 test1 目錄構建映象並啟動一個容器:

$ docker build -t test1 .
$ docker run -idt --name testcon test1

然後檢視容器中的程序 ID:

$ docker exec testcon ps aux

從圖中我們看到執行 top 命令的程序 ID 為 1。
exec 模式是建議的使用模式,因為當執行任務的程序作為容器中的 1 號程序時,我們可以通過 docker 的 stop 命令優雅的結束容器(詳情請參考《

在 docker 容器中捕獲訊號》)。

exec 模式的特點是不會通過 shell 執行相關的命令,所以像 $HOME 這樣的環境變數是取不到的

FROM ubuntu
CMD [ "echo", "$HOME" ]

把上面的程式碼儲存到 test1 目錄的 Dockerfile 中,然後進入 test1 目錄構建映象並啟動一個容器:

$ docker build --no-cache -t test1 .
$ docker run --rm test1

通過 exec 模式執行 shell 可以獲得環境變數:

FROM ubuntu
CMD [ "sh", "-c", "echo $HOME" ]

把上面的程式碼儲存到 test1 目錄的 Dockerfile 中,然後進入 test1 目錄構建映象並啟動一個容器:

$ docker build --no-cache -t test1 .
$ docker run --rm test1

這次正確取到了 $HOME 環境變數的值。

 

shell 模式

使用 shell 模式時,docker 會以 /bin/sh -c "task command" 的方式執行任務命令。也就是說容器中的 1 號程序不是任務程序而是 bash 程序,看下面的例子:

FROM ubuntu
CMD top

把上面的程式碼儲存到 test2 目錄的 Dockerfile 中,然後進入 test2 目錄構建映象並啟動一個容器:

$ docker build -t test2 .
$ docker run -itd --name testcon2 test2

然後檢視容器中的程序 ID:

$ docker exec testcon2 ps aux

1 號程序執行的命令居然是 /bin/sh -c top。而我們指定的 top 命令的程序 ID 為 7。這是由 docker 內部決定的,目的是讓我們執行的命令或者指令碼可以取到環境變數。

同時使用 CMD 和 ENTRYPOINT 的情況

對於 CMD 和 ENTRYPOINT 的設計而言,多數情況下它們應該是單獨使用的。當然,有一個例外是 CMD 為 ENTRYPOINT 提供預設的可選引數。
我們大概可以總結出下面幾條規律:
    • 如果 ENTRYPOINT 使用了 shell 模式,CMD 指令會被忽略。
    • 如果 ENTRYPOINT 使用了 exec 模式,CMD 指定的內容被追加為 ENTRYPOINT 指定命令的引數。
    • 如果 ENTRYPOINT 使用了 exec 模式,CMD 也應該使用 exec 模式。
真實的情況要遠比這三條規律複雜,好在 docker 給出了官方的解釋,如下圖所示: