iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 19
0
Cloud Native

30 天準備 LPI DevOps Tools Engineer 證照系列 第 19

[Day 19] Docker (5)

Docker image CLI

介紹完 Dockerfile 後,來看看 Docker CLI 中和映像檔相關的操作。一般介紹 Docker 的書應該會將常用的指令整理在同一章節中,不過在 Docker 文件中我沒找到專門介紹常用指令的段落,因此找了 CLI 文件中關於 docker image 的部分來作說明,可參考 https://docs.docker.com/engine/reference/commandline/image/

docker image build

等同 docker build,用來從 Dockerfile 建立一個映像檔,格式如下:

docker image build [OPTIONS] PATH | URL | -

注意最後一個參數,前面有說過是指 build context,不是 Dockerfile,如果要指定 Dockerfile 路徑要使用 -f 旗標。

docker image load

等於 docker load,將一個 tar 壓縮檔載入成為映像檔,預設讀取 STDIN,可用 --input-i 來指定輸入檔案,例如:

docker image load [OPTIONS]

docker image save

等於 docker save,是前一個指令的反向,將映像檔存成一個 tar 壓縮檔,預設寫至 STDOUT,可用 --output-o 來指定輸出檔案,範例如下:

docker image save [OPTIONS] IMAGE [IMAGE...]

在無法透過 docker registry 上傳或下載映像檔時,可以利用 docker image load / save。試驗了一下,用 docker load 所載入的映像檔不會有名稱(用 docker image ls 查看,REPOSITORYTAG 欄位會是 <none>),可以用 docker tag 加上資訊。

docker image push

等於 docker push,用來將映像檔推到 registry,格式如下:

docker image push [OPTIONS] NAME[:TAG]

docker image pull

等於 docker pull,是前一個指令的反向,用來將映像檔由 registry 拉下,格式如下:

docker image pull [OPTIONS] NAME[:TAG|@DIGEST]

其他動作如 lsinspectrm 都蠻直覺的,就不多介紹,請查閱文件。

容器

官方文件的指引中似乎沒有專門針對容器說明的部分,但也可以說因為指引是以應用程式開發的角度來編寫,而應用程式運行的生命週期幾乎離不開容器,所以整份指引也幾乎都是在說明和容器相關的概念及操作。

一般介紹 Docker 的書談到容器,應該都會先介紹 CLI 操作容器的指令,這裡也先從指令介紹起,關於 CLI 中 docker container 的說明可參考 [https://docs.docker.com/engine/reference/commandline/container_run/]
(https://docs.docker.com/engine/reference/commandline/container_run/),除了文件的說明,也參考了 Packt 出版的 Mastering Docker, 2/e 中關於容器一節,以決定要介紹那些指令。

docker container run

用來在一個新的容器中執行命令,等於 docker run。它應該是 docker container 中最重要的指令,文件中有一頁(應該算是)完整的介紹,請參考 https://docs.docker.com/engine/reference/run/。執行時有一些重要的選項,例如要以分離模式或前景模式運行、CPU 和記憶體資源限制等等。指令格式如下:

docker container run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]

分離 (detached) 或前景 (foreground) 模式

這個在 Get Started 第一部分已經看過,分離模式有點類似以背景執行,以 -d 旗標指定。若是前景模式,則 docker 可以將容器中運行行程的 STDINSTDOUTSTDERR 附著 (attach) 在終端機上,主要有三個旗標可以使用,-a 可用來指示要 attach STDINSTDOUTSTDERR-t 代表要分配一個虛擬的 tty (終端機),-i 表示要持續開啟 STDIN。在互動模式的行程例如 shell,通常會一起使用 -i-t 旗標,或寫成 -it,用來分派 tty 給容器程序。看不懂沒有關係,反正記得如果希望容器運作時能提供一個 shell 以連進去進行操作,就在 docker run 時加上 -it 的指令就對了,例如:

$ docker container run -it --rm --name alpine-env alpine

這個容器使用 alpine 映像檔,執行 /bin/sh 並給予一個 tty 進行操作。--rm 表示在主程序 /bin/sh 結束後,例如輸入 exit 退出 shell,容器會被移除,--name 則為給予容器的名稱。

資源限制

容器運行時的資源限制大概可以分成三類,記憶體、處理器以及 I/O。可以設定的選項有很多,比較常見的應該是 --memory (-m) 限制記憶體用量,以及 --cpu-shares (-c) 限制 CPU 用量,但不是很瞭解它是怎麼計算的,有看到兩種不同的參數給法,一種是給 512、1024,另一種是給 0、1、2。範例如下:

$ docker container run --cpu-shares 512 --memory 128M nginx

與容器互動

除了剛才介紹的 docker container run 搭配 -it 選項外,還有幾個指令可以用來跟容器互動。跟容器互動這個說法有點模糊,總之先看一下這兩個指令。

docker container attach

文件中說它的用途是 Attach local standard input, output, and error streams to a running container,但感覺起來好像是將運行中容器的行程附著到本機終端機。不知道是英文理解上的問題,還是我對 attach 的「方向」認知有誤。來試驗一下,我們先用 detached 模式來執行一個運行 nginx 服務的容器,指令是

$ docker container run -d -p 8888:80 --name nginx-test --rm nginx

接下來執行 docker container attach nginx-test,並用瀏覽器訪問 http://localhost:8888,此時會在剛才 attach 的終端機看到訪問 nginx 的記錄檔 (access log)。

docker container exec

它會在容器中產生另一個行程來執行要求的指令。來試驗一下,一樣用 detached 模式執行剛才的 nginx 容器,然後執行下列指令:

$ docker container exec -it nginx-test /bin/sh

它會在 nginx-test 容器中執行 /bin/sh-it 旗標會給予一個可供互動的終端機。

容器運作狀況

docker container logs

用來印出容器的 STDOUT,範例如下:

$ docker container logs --tail 5 nginx-test
$ docker container logs -f nginx-test

docker container top

列出容器內執行的行程訊息,範例如下:

$ docker container top nginx-test
PID                 USER                TIME                COMMAND
14583               root                0:00                nginx: master process nginx -g daemon off;
14623               101                 0:00                nginx: worker process

docker container stats

列出運行中容器的即時資訊,例如 ID、名稱、CPU、記憶體等等。若加上容器名稱,只顯示該容器資訊,否則會顯示所有容器的資訊。

$ docker container stats nginx-test
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
2d28fd25bce0        nginx-test          0.00%               1.914MiB / 1.952GiB   0.10%               858B / 0B           0B / 0B             2

docker container prune

刪除所有在停止狀態的容器,範例如下:

$ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
dea1c7d02374a1ec427fcd16084166146e06201f8fe52284d81b56dbae9066a0
6502de71db8883d45b077fe494c0b1e47cddd5a9c9a78805af71dea438da2b3f
ea3d9f38020c1520af716146ba39293ab15cff393f89568c96615b496c24aded

Total reclaimed space: 0B

docker container commit

由容器改變後的狀態來建立新的映像檔,例如可能使用 shell 在容器中作了一些設定或檔案的變化,此時就可以使用這個指令,根據容器目前的狀態來建立新的映像檔,不過這不是推薦的方式,最好還是利用 Dockerfile 從基礎映像檔加上其他的指令來創建新的映像檔。可以使用 --change-c 來傳入 Dockerfile 中的指令。範例如下:

$ docker commit --change='CMD ["apachectl", "-DFOREGROUND"]' -c "EXPOSE 80" c3f279d17e0a  svendowideit/testimage:version4

c3f279d17e0a 為容器的 ID,svendowideit/testimage:version4 為映像檔的名稱及標籤。

其他關於容器狀態管理的指令,例如 startstoprmkill 等等,也都蠻直覺的,就不再介紹,請查閱文件。

這兩天介紹了映像檔和容器,以及編寫 Dockerfile 時常用的指令,明天會介紹 Docker 網路 (network) 及卷宗 (volume)。


上一篇
[Day 18] Docker (4)
下一篇
[Day 20] Docker (6)
系列文
30 天準備 LPI DevOps Tools Engineer 證照30

尚未有邦友留言

立即登入留言