啓動容器
啓動容器有兩種方式,一種是基於鏡像新建一個容器並啓動,另外一個是將在終止狀態(stopped ) 的容器重新啓動。
因爲 Docker 的容器實在太輕量級了,很多時候用戶都是隨時刪除和新創建容器。
新建並啓動
例如,下面的命令輸出一個 “Hello World”,之後終止容器。
$ docker run ubuntu:14.04 /bin/echo 'Hello world'
Hello world
這跟在本地直接執行 /bin/echo 'hello world' 幾乎感覺不出任何區別。
下面的命令則啓動一個 bash 終端,允許用戶進行交互。
$ docker run -t -i ubuntu:14.04 /bin/bash
root@af8bae53bdd3:/#
其中, -t 選項讓Docker分配一個僞終端(pseudo-tty) 並綁定到容器的標準輸入上, -i則讓容器的標準輸入保持打開
當利用 docker run 來創建容器時,Docker 在後臺運行的標準操作包括:
- 檢查本地是否存在指定的鏡像,不存在就從公有倉庫下載
- 利用鏡像創建並啓動一個容器
- 分配一個文件系統,並在只讀的鏡像層外面掛載一層可讀寫層
- 從宿主主機配置的網橋接口中橋接一個虛擬接口到容器中去
- 從地址池配置一個 ip 地址給容器
- 執行用戶指定的應用程序
- 執行完畢後容器被終止
啓動已終止容器
可以利用 docker container start 命令,直接將一個已經終止的容器啓動運行。
守護狀態運行
更多的時候,需要讓 Docker 在後臺運行而不是直接把執行命令的結果輸出在當前宿主機下。此時,可以通過添加 -d 參數來實現。
$ docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
cb30b87566d0550ec5f1232d148c5ffed6546c347889e58a6405579f2af73f2a
使用 -d 參數啓動後會返回一個唯一的 id。此時輸出結果可以用docker logs [container ID or NAMES] 查看。如果不使用 -d 參數。輸出的結果 (STDOUT) 會打印到宿主機上面
通過 docker container ls 命令來查看容器信息。
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cb30b87566d0 ubuntu "/bin/sh -c 'while t…" 2 minutes ago Up 2 minutes goofy_mcclintock
要獲取容器的輸出信息,可以通過 docker container logs 命令。
$ docker container logs goofy_mcclintock
hello world
hello world
hello world
......
注: 容器是否會長久運行,是和 docker run 指定的命令有關,和 -d 參數無關。
終止容器
可以使用 docker container stop 來終止一個運行中的容器。其格式爲:docker container stop [選項] CONTAINER [CONTAINER...]
此外,當 Docker 容器中指定的應用終結時,容器也自動終止。
例如只啓動了一個終端的容器,用戶通過 exit 命令或 Ctrl+d 來退出終端
時,所創建的容器立刻終止。
終止狀態的容器可以用 docker container ls -a 命令看到。例如
$ docker container stop goofy_mcclintock
goofy_mcclintock
$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cb30b87566d0 ubuntu "/bin/sh -c 'while t…" 20 minutes ago Exited (137) 23 seconds ago goofy_mcclintock
通過 docker container start 命令來啓動處於終止狀態的容器;
通過 docker container restart 命令會將一個運行態的容器先終止再重新啓動。
進入容器
在使用 -d 參數時,容器啓動後會進入後臺。
使用 docker exec 命令 或 docker attach 命令進入容器進行操作,推薦使用 docker exec 命令,原因會在下面說明。
exec 命令
-i -t 參數
docker exec 後邊可以跟多個參數,這裏主要說明 -i -t 參數。
只用 -i 參數時,由於沒有分配僞終端,界面沒有我們熟悉的 Linux 命令提示符,但命令執
行結果仍然可以返回。
當 -i -t 參數一起使用時,則可以看到我們熟悉的 Linux 命令提示符。
$ docker run --name webserver -d -p 80:80 nginx
1eec473ab0a32ad938e06644d4b15046a708bbf5a8e22f0f9e4ebf4918b8df15
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1eec473ab0a3 nginx "nginx -g 'daemon of…" 22 seconds ago Up 22 seconds 0.0.0.0:80->80/tcp webserver
$ docker exec -it webserver bash
root@1eec473ab0a3:/# echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
root@1eec473ab0a3:/# exit
#修改了容器的文件,我們可以通過 docker diff 命令看到具體的改動。
如果從這個 stdin 中 exit,不會導致容器的停止。
更多參數說明請使用 docker exec --help 查看。
attach 命令
docker attach 是 Docker 自帶的命令。下面示例如何使用該命令。
$ docker attach webserver
注意: 如果從這個 stdin 中 exit,會導致容器的停止。
查看容器日誌
通過docker logs命令可以查看容器的日誌。
命令格式:
$ docker logs [OPTIONS] CONTAINER
Options:
--details 顯示更多的信息
-f, --follow 跟蹤實時日誌
--since string 顯示自某個timestamp之後的日誌,或相對時間,如42m(即42分鐘)
--tail string 從日誌末尾顯示多少行日誌, 默認是all
-t, --timestamps 顯示時間戳
--until string 顯示自某個timestamp之前的日誌,或相對時間,如42m(即42分鐘)
例子:
#查看指定時間後的日誌,只顯示最後100行:
$ docker logs -f -t --since="2018-02-08" --tail=100 CONTAINER_ID
#查看最近30分鐘的日誌:
$ docker logs --since 30m CONTAINER_ID
#查看某時間之後的日誌:
$ docker logs -t --since="2018-02-08T13:23:37" CONTAINER_ID
#查看某時間段日誌:
$ docker logs -t --since="2018-02-08T13:23:37" --until "2018-02-09T12:23:37" CONTAINER_ID
將容器保存爲鏡像
當我們運行一個容器的時候(如果不使用卷的話) ,我們做的任何文件修改都會被
記錄於容器存儲層裏。而 Docker 提供了一個 docker commit 命令,可以將容器的存儲層保
存下來成爲鏡像。換句話說,就是在原有鏡像的基礎上,再疊加上容器的存儲層,並構成新
的鏡像。以後我們運行這個新鏡像的時候,就會擁有原有容器最後的文件變化。
docker commit 的語法格式爲:
docker commit [選項] <容器ID或容器名> [<倉庫名>[:<標籤>]]
我們可以用下面的命令將容器保存爲鏡像:
$ docker commit --author "QiangSH" --message "修改了默認網頁" webserver nginx:v2
sha256:749af9532d166d2cd5f88025a79e0e39658375761eef0200925cb82093b4514f
$ docker image ls -a
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v2 749af9532d16 48 seconds ago 109MB
nginx latest c82521676580 4 weeks ago 109MB
其中 --author 是指定修改的作者,而 --message 則是記錄本次修改的內容。這點和 git
版本控制相似,不過這裏這些信息可以省略留空。
慎用 docker commit
- 會有大量的無關內容被添加進來,如果不小心清理,將會導致鏡像極爲臃腫。
- 除了製作鏡像的人知道執行過什麼命令、怎麼生成的鏡像,別人根本無從得知
- 任何修改的結果僅僅是在當前層進行標記、添加、修改,而不會改動上一層,每一次修改都會讓鏡像更加臃腫一次,所刪除的上一層的東西並不會丟失
刪除容器
刪除一個處於終止狀態的容器,其格式爲:docker container rm [選項] CONTAINER [CONTAINER...]
$ docker container rm awesome_payne
awesome_payne
如果要刪除一個運行中的容器,可以添加 -f 參數。Docker 會發送SIGKILL 信號給容器。
清理所有處於終止狀態的容器用 docker container ls -a 命令可以查看所有已經創建的包括終止狀態的容器,如果數量太多要一個個刪除可能會很麻煩,用下面的命令可以清理掉所有處於終止狀態的容器。
$ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
545f8f6d19286efae28307d06ed1acc034d07f109e907c01892471a6f89e772d
cb30b87566d0550ec5f1232d148c5ffed6546c347889e58a6405579f2af73f2a
......
導出和導入容器
導出容器
如果要導出本地某個容器,可以使用 docker export 命令。
$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
16168d4b66b1 ubuntu "/bin/bash" 18 minutes ago Up 18 minutes happy_bardeen
$ docker export 16168d4b66b1 > ubuntu.tar
這樣將導出容器快照到本地文件。
導入容器快照
可以使用 docker import 從容器快照文件中再導入爲鏡像,例如
$ cat ubuntu.tar | docker import - test/ubuntu:v1.0
sha256:91b174fec9ed55d7ebc3d2556499713705f40713458e8594efa114f261d7369a
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
test/ubuntu v1.0 91b174fec9ed 10 seconds ago 69.8MB
ubuntu latest 735f80812f90 3 weeks ago 83.5MB
此外,也可以通過指定 URL 或者某個目錄來導入,例如$ docker import http://example.com/exampleimage.tgz example/imagerepo
注:用戶既可以使用 docker load 來導入鏡像存儲文件到本地鏡像庫,也可以使用 docker import 來導入一個容器快照到本地鏡像庫。這兩者的區別在於容器快照文件將丟棄所有的歷史記錄和元數據信息(即僅保存容器當時的快照狀態) ,而鏡像存儲文件將保存完整記錄,體積也要大。此外,從容器快照文件導入時可以重新指定標籤等元數據信息。