在Docker不加參數的情況下,要讓Container一直執行下去,就是執行一個無止盡的程式,如ping localhost
。我們就來看看執行結果:
ping localhost
:docker run --name test busybox ping localhost
這次我們加了一個新的參數--name test
,表示把這個執行的Container取名為test
,方便以後的處理。$ docker run --name test busybox ping localhost
PING localhost (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: seq=0 ttl=64 time=0.041 ms
64 bytes from 127.0.0.1: seq=1 ttl=64 time=0.071 ms
64 bytes from 127.0.0.1: seq=2 ttl=64 time=0.065 ms
64 bytes from 127.0.0.1: seq=3 ttl=64 time=0.039 ms
64 bytes from 127.0.0.1: seq=4 ttl=64 time=0.100 ms
64 bytes from 127.0.0.1: seq=5 ttl=64 time=0.100 ms
64 bytes from 127.0.0.1: seq=6 ttl=64 time=0.087 ms
64 bytes from 127.0.0.1: seq=7 ttl=64 time=0.094 ms
64 bytes from 127.0.0.1: seq=8 ttl=64 time=0.054 ms
.....(無止無盡的執行)
docker ps
,就可以看到正在執行中的Container,這就是一個標準的「活」的Container事實上,要讓Container能持續執行下去,除了Container本來去執行一個永遠不停止的命令之外,我們當然也可以使用docker run
本身附帶的參數來進行。
Container可被視為一台獨立的電腦,因此當然可以有鍵盤及螢幕。但這邊所謂的鍵盤螢幕,就是Linux的輸入裝置stdin
及輸出裝置stdout
。在Docker中的指令如下:
-t
:attach
時Container的螢幕會接到原來的螢幕上。-i
:attach
時鍵盤輸入會被Container接手如果你想讓Container擁有這兩樣,在執行docker run
時別忘加上參數-i
或-t
,如果兩個同時都加,這個Container就具備了標準的輸入(即你目前使用的鍵盤)和輸出(標準的Linux輸出,即目前操作的終端視窗)。
注意,Docker下的參數是可以合併的,因此docker run -t -i
可以直接寫成docker run -it
。
$ docker run -it --name test busybox
/ # ls
bin etc lib linuxrc mnt proc run sys usr
dev home lib64 media opt root sbin tmp var
/ # exit
$
讀者可以發現當你執行上述指令時,Linux的提示符號從$
變成了#
,表示你已經從原來的Linux主機,進入了這個Container的內部操作介面了。
此時執行的ls
指令顯示的是Container內的檔案系統列表,而非主系統的檔案系統列表。從另一個終端命令視窗進去執行docker ps
,也可以看到這個Container正在執行中。當然就像任何Linux一樣,當你在Container中輸入exit
之後,就會離開這個Container,此Container就會停止運行,回到外部的Linux系統。
大部分的Docker應用程式都是以服務方式執行,換句話說,我們不太需要進入這個Container的命令提示符號操作,此時可以在docker run
後輸入-d
參數,表示是Detached模式,或稱之為"Daemonized"的方式執行。此時不會進入Container,但Container照道理應該在背景執行了,可以用docker ps
查看。
$ docker run -d busybox
e8a30f345b260893cbda28cd9ef087def15080d756e974f21789ac2389306631
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
讀者應該會發現,背景並沒有這個Container的執行?不是已經下了-d
參數了嗎?我們就來看看原因。
我們在本機執行echo "hello world"
時,執行完畢即離開echo
這個指令,這個指令是不是在背景執行並不重要,通常執行完就離開。
Docker也是一樣。就算下了-d
參數,但由busybox
映像檔所產生的Container,在啟動時,並沒有一個長期駐留記憶體的服務,因此也是執行完就離開這個Container,因此不會常駐在主系統的記憶體中,當然就看不到了。
由此可知,要讓Container能活著提供服務的前題,就是該Container有一個駐留在記憶體中的服務,下列幾個就是符合這個前題的條件:
該Container在產生並啟動時,來源的映像檔就有一個開機自動執行常駐的服務,而且這個Container被我們使用-d
參數丟入背景。本書稍後章節會有完整實作。
$ docker run -d joshhu/webdemo
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
964951e51154 joshhu/webdemo:latest "/start.sh" 9 seconds ago Up 9 seconds 80/tcp elated_feynman
上面的例子,可以看到這個Container在啟動時,執行了一個start.sh
,這個檔案就是讓Container一直執行的服務,在建立映像檔時就建立好了。
手動對Container執行一個不停止的服務並把Container丟入背景執行,如docker run -d busybox ping localhost
。
$ docker run -d busybox ping localhost
d794699780ce1ae907782809887d56ee5d21e6d52d50caea13e6052d37afcb48
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d794699780ce busybox:latest "ping localhost" 2 seconds ago Up 2 seconds grave_hypatia
-d
參數將Container放入背景,並且讓他保持基本輸入或輸出的能力。換句話說,就是不但要加入參數-d
,同時也要有參數-t
或-i
,因此加上-dt
或-di
或-idt
均可。$ docker run -dt busybox
aa94ab648f25384c40e8c1e8fbbe3945472a7220f6fa20753765f6bb1499cc69
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aa94ab648f25 busybox:latest "/bin/sh" 2 seconds ago Up 2 seconds jovial_mccarthy