全面易懂的Docker指令大全

Container內部及外部的執行

進入執行中Container內部

如果Container在背景常駐,我們當然就可以進入Container進行操作,以下是最常見的使用:

denter

denter不是Docker的指令,而是我們在前面章節匯入的一個script,只要輸入denter <CONTAINER NAME>即可。

$ docker run --name web joshhu/webdemo
chown: cannot access '/app': No such file or directory
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.12. Set the 'ServerName' directive globally to suppress this message
^C$ docker rm -f web
web

在上面的範例中,首先我們執行一個Web服務,其預設的常駐程式是apache2。但第一次執行沒有用-d參數放入背景,因此所有的訊息會輸出到前景的stdout中,我們使用Ctrl-C強迫中斷。

$ docker run -d --name web joshhu/webdemo
0941e3055a30352688290746f0a175df1f6bcbf447038cd4cf3e3a43cba1f658
$ denter web
root@0941e3055a30:~# exit
logout
$ docker ps
CONTAINER ID        IMAGE                   COMMAND             CREATED             STATUS              PORTS               NAMES
0941e3055a30        joshhu/webdemo:latest   "/start.sh"         2 minutes ago       Up 2 minutes        80/tcp              web
$

第二次執行有使用-d參數,因此這個Container的Web服務被放入背景,輸入denter web就以進入這個Container中操作,exit離開後,在docker ps中也可以看到這個Container在繼續執行。

docker attach

docker attach是用來「監管」Container用的。換句話說,在使用docker attach一個Container之後,就會進入這個Container的操作終端命令列,但視你之前執行docker run的參數,離開這個Container時,會不會中止Container的執行。

  • 使用-d-id參數:離開Container時該Container停止。
  • 使用-td參數:離開Container時該Container繼續在背景。
    root@ubuntu:/# docker run -id --name test busybox ping localhost
    45abb8bc99cdd91c1c6a46b6a3d1477dc0d7f0c5612b63dcbe50b2a0c5badbc7
    root@ubuntu:/# docker attach test
    64 bytes from 127.0.0.1: seq=6 ttl=64 time=0.095 ms
    64 bytes from 127.0.0.1: seq=7 ttl=64 time=0.095 ms
    64 bytes from 127.0.0.1: seq=8 ttl=64 time=0.102 ms
    ^C
    --- localhost ping statistics ---
    9 packets transmitted, 9 packets received, 0% packet loss
    round-trip min/avg/max = 0.051/0.092/0.111 ms
    root@ubuntu:/# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    
    $ docker run -td --name test busybox ping localhost
    d8c3687f46a2c26e809c556a7c810a36a73959bfcb8636fb874c9da969b2ee43
    $ docker attach test
    64 bytes from 127.0.0.1: seq=7 ttl=64 time=0.063 ms
    64 bytes from 127.0.0.1: seq=8 ttl=64 time=0.096 ms
    64 bytes from 127.0.0.1: seq=9 ttl=64 time=0.097 ms
    64 bytes from 127.0.0.1: seq=10 ttl=64 time=0.093 ms
    ^C$ docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    d8c3687f46a2        busybox:latest      "ping localhost"    14 seconds ago      Up 13 seconds                           test
    

在外部執行Container內的程式

我們可以從外部執行Container內部的程式,或直接觀看Container內的輸出。有兩個指令:

docker logs

這個指令直接讀出Container內的輸出到主機的螢幕上。舉例來說,我們執行一個不斷列出系統時間的無窮迴圈: 先在前景執行:

$ docker run --name printtime busybox /bin/sh -c "while true;do date;sleep 1;done"
Fri Mar 27 12:24:15 UTC 2015
Fri Mar 27 12:24:16 UTC 2015
Fri Mar 27 12:24:17 UTC 2015
Fri Mar 27 12:24:18 UTC 2015
^C$
$

丟到背景執行,再用docker logs在前景列出執行結果:

$ docker run -d --name printtime busybox /bin/sh -c "while true;do date;sleep 1;done"
5a80b74ff2fb1c0596880c2b6d3f12a1db9a27777721326fa8d296fcfab9da53
$ docker logs printtime
Fri Mar 27 12:22:25 UTC 2015
Fri Mar 27 12:22:26 UTC 2015
Fri Mar 27 12:22:27 UTC 2015
Fri Mar 27 12:22:28 UTC 2015
Fri Mar 27 12:22:29 UTC 2015
Fri Mar 27 12:22:30 UTC 2015
Fri Mar 27 12:22:31 UTC 2015
Fri Mar 27 12:22:32 UTC 2015
$

docker exec

這個指令很簡單,就是在外部向執行中的Container內部下指令,此時會呼叫Container內部的shell程式來執行你下的指令,而不管你之前啟動Docker時給這個Container的指令,兩個沒有關係。

$ docker run -d --name printtime busybox /bin/sh -c "while true;do date;sleep 1;done"
f01ceebc8330893b741a5c3323bae506b7e62d242dc8c76e4d127010281b2c9b
$ docker logs printtime
Fri Mar 27 12:34:59 UTC 2015
Fri Mar 27 12:35:00 UTC 2015
Fri Mar 27 12:35:01 UTC 2015
Fri Mar 27 12:35:02 UTC 2015
Fri Mar 27 12:35:03 UTC 2015
Fri Mar 27 12:35:04 UTC 2015
$ docker exec printtime ps
PID   USER     COMMAND
    1 root     /bin/sh -c while true;do date;sleep 1;done
   52 root     sleep 1
   53 root     ps

就像上例一樣,我們雖然在執行docker run時讓這個Container執行一個無限印出系統時間的指令,但使用docker exec時,也是在Container內另外啟動一個/bin/sh的shell來執行ps