全面易懂的Docker指令大全

執行中的Container

永遠執行的ontainer

在Docker不加參數的情況下,要讓Container一直執行下去,就是執行一個無止盡的程式,如ping localhost。我們就來看看執行結果:

  1. 執行一個不會結束的程式,如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
    .....(無止無盡的執行)
    
  2. 此時再開啟一個終端視窗,並且執行docker ps,就可以看到正在執行中的Container,這就是一個標準的「」的Container

事實上,要讓Container能持續執行下去,除了Container本來去執行一個永遠不停止的命令之外,我們當然也可以使用docker run本身附帶的參數來進行。

給Container標準輸出輸入裝置

Container可被視為一台獨立的電腦,因此當然可以有鍵盤及螢幕。但這邊所謂的鍵盤螢幕,就是Linux的輸入裝置stdin及輸出裝置stdout。在Docker中的指令如下:

  • -tattach時Container的螢幕會接到原來的螢幕上。
  • -iattach時鍵盤輸入會被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系統。

讓Container在背景執行

大部分的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有一個駐留在記憶體中的服務,下列幾個就是符合這個前題的條件:

  1. 該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一直執行的服務,在建立映像檔時就建立好了。

  2. 手動對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
    
  3. -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