Docker 教程:玩轉容器(簡單例項)
【編者的話】Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然後釋出到任何流行的Linux機器上,也可以實現虛擬化,容器是完全使用沙箱機制,相互之間不會有任何介面。
如果你是Docker的新手,看一下你應該學習的一些基礎命令,以便開始管理容器。
Docker對軟體開發生命週期產生了巨大影響,使得大規模軟體部署變得簡單而且安全。這個教程將介紹執行,啟動,停止和刪除Docker容器的基礎知識。
Docker使得在不同的作業系統上使用不同的程式語言很容易,而所有這些都在同一主機上實現。
在Docker之後部署你的軟體變得更加容易,你不必擔心錯過系統配置或先決條件。
Docker與虛擬機器
如果你正使用虛擬執行你的軟體,為什麼還需要Docker來取代呢?
它們之間的主要區別在於Docker是一個在你的本機作業系統中執行的獨立程序,而虛擬機器是一個完整的隔離作業系統,它在主機作業系統之上執行,需要更多時間來載入。所以Docker比虛擬機器有更多優勢,例如:
- 載入速度 與虛擬機器不同,所需的硬體資源很少。
- 在同一作業系統上同時執行多個Docker容器。
- 你可以修改容器並對其進行部署,或將Docker檔案定義提供給朋友,以便在同一環境中工作。
實際上,Docker不是虛擬機器的替代品,而是解決特定問題。
假設你的應用程式需要3個或更多在不同作業系統上執行的服務,那麼你可以在同一主機上平穩執行3個容器,而不是在同一主機上執行3個虛擬機器。聽起來很棒!!
執行你的容器
在開始之前,請確保已正確安裝Docker並準備好接受命令。在新的終端視窗中鍵入以下命令:
$ docker -v
以上命令輸出PC上安裝的Docker版本:
Docker version 17.12.0-ce-rc2, build f9cde63
是時候開始執行容器了:
$ docker container run alpine echo "Hello World"
當您第一次執行上述命令時,你應該在終端視窗中看到與此類似的輸出:
Unable to find image 'alpine:latest' locally latest: Pulling from library/alpine 2fdfe1cd78c2: Pull complete Digest: sha256:ccba511b... Status: Downloaded newer image for alpine:latest Hello World
這很容易,不是嗎?嘗試再次執行相同的命令:
$ docker container run alpine echo "Hello World"
執行上述命令的第二,第三或第n次,你應該只在終端中看到此輸出:
Hello World
現在你已成功執行容器,現在是時候分析究竟發生了什麼。檢視以下命令:
$ docker container run alpine echo "Hello World"
該命令包含多個部分。首先,你有“docker”這個詞。這是Docker命令列介面(CLI)的名稱,用於與負責執行容器的Docker引擎進行互動。
接下來,您有單詞container,它表示你正在使用的上下文。
再下一步是 實際要執行的命令 run。
現在,還需要告訴Docker執行哪個容器。在這裡,執行的是 alpine 容器。
最後,需要定義在容器執行時,應在容器內執行的程序或任務型別。這是命令的最後一部分,echo "Hello World"
.
在容器內執行程序
既然已經瞭解了執行容器的命令的各個部分,請嘗試在另一個容器中執行不同的程序:
$ docker container run centos ping -c 5 127.0.0.1
輸出如下:
Unable to find image 'centos:latest' locally latest: Pulling from library/centos 85432449fd0f: Pull complete Digest: sha256:3b1a65e9a05... Status: Downloaded newer image for centos:latest PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.022 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.019 ms 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.029 ms 64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.030 ms 64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.029 ms --- 127.0.0.1 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4103ms
在前面的示例中,使用的容器映像是centos,並且在centos容器內執行的程序是ping -c 5 127.0.0.1,它將環回地址ping五次直到它停止。
-
第一行如下:
{{{Unable to find image 'centos:latest' locally}}}
這告訴你Docker沒有在系統的本地快取中找到名為 centos:latest 的映象。因此,Docker 知道它必須從儲存容器的某個映象源中提。
預設情況下,Docker 環境配置為從 hub.docker.com 的 Docker Hub 中提取映象。這由第二行表示如下:
latest: Pulling from library/centos
接下來的三行輸出如下:
85432449fd0f: Pull completeDigest: sha256:3b1a65e9a05...Status:
這告訴您 Docker 已成功從 Docker Hub 中提取了映象centos:latest。
後續的輸出都是由容器內執行的程序生成的,這裡執行的是 ping 工具。
你可能還注意到 latest 這個關鍵字出現了幾次。每個映像都有一個版本(也稱為標記),如果沒有明確指定版本,則 Docker 會自動其視為最新版本。
如果在系統上再次執行這個容器,將不會輸出之前的五行,因為 Docker 將在本地快取容器映像,因此不必先下載它。試試是不是這樣。
執行一個隨機引用容器
為了執行隨機語句容器,需要一個生成隨機語句的演算法。可以在此處找到生成這些隨機語句的 API。
現在的目標是要在容器內執行一個程序,每5秒生成一條隨機語句,並且輸出到 STDOUT:
while : do wget -qO- https://talaikis.com/api/quotes/random printf 'n' sleep 5 done
按 Ctrl + C 停止指令碼。這是輸出:
{"quote":"Martha Stewart is extremely talented. Her designs are picture perfect. Our philosophy is life is messy, and rather than being afraid of those messes we design products that work the way we live.","author":"Kathy Ireland","cat":"design"}{"quote":"We can reach our potential, but to do so, we must reach within ourselves. We must summon the strength, the will, and the faith to move forward - to be bold - to invest in our future.","author":"John Hoeven","cat":"faith"
}
每個響應都是一個JSON格式的字串,包含引號,作者及其類別。
現在,讓這個容器後臺執行。為此,需要將前面的指令碼縮成一行,並使用 /bin/sh -c “…” 來執行。Docker 的表示式如下:
$ docker container run -d --name quotes alpine \/bin/sh -c "while :; do wget -qO- https://talaikis.com/api/quotes/random; printf '\n'; sleep 5; done"
上面的表示式,你使用了兩個命令列引數,-d 和 --name。-d 告訴 Docker 以一個 Linux 守護程序的方式執行容器。-name 引數用於為容器指定顯式名稱。
如果您未指定顯式容器名稱,Docker將自動為容器分配一個隨機但唯一的名稱。這個名字將由一位著名科學家的名字和一個形容片語成。
諸如,“boring_borg”或“angry_goldberg”。相當幽默,不是嗎?
一個重要的方面是容器名稱必須是唯一的。確保引號容器已啟動並正在執行:
$ docker container ls -l
前面輸出的重要部分是STATUS列,此例中,它顯示 UP 16 seconds。這意味著容器已經啟動並運行了16秒。
隨著時間的推移繼續執行容器,你的系統也許會產生很多容器。要查詢主機上當前正在執行的容器,可以使用 container ls 命令,如下所示:
$ docker container ls
這將列出所有當前執行的容器。
預設情況下,Docker輸出七列,含義如下:
| 列| 描述|
| ------------ | ------------------------------------------------------------------------ |
| Container ID | 唯一的容器 ID 。它是 SHA-256.|
| Image| 所以用的映象|
| Status| 容器的狀態 (created, restarting, running, removing, paused, exited, or dead). |
| Ports| 對映到宿主機的埠|
| Names| 分配到容器的名字 (可以是多個名字的)|
如果要列出系統上定義的所有容器,可以使用命令列引數 -a 或 -all,如下所示:
$ docker container ls -a
這將列出任何狀態的容器,無論是建立,執行還是退出。
有時,可能只想列出所有容器的 ID。為此,你有 -q 引數:
$ docker container ls -q
你可能想知道這有什麼用。這裡有個例子:
$ docker container rm -f $(docker container ls -a -q)
上面的命令刪除當前在系統上定義的所有容器,包括已停止的容器。rm命令代表刪除,將在本教程中進一步解釋。
在上一節中,您在list命令中使用了-l引數。嘗試使用Docker幫助找出-l引數代表什麼。您可以為list命令呼叫help,如下所示:
$ docker container ls -h
停止和啟動容器
有時,你可能需要暫時停止正在執行的容器。試試以下這個容器
$ docker container run -d --name quotes alpine \/bin/sh -c "while :; do wget -qO- https://talaikis.com/api/quotes/random; printf '\n'; sleep 5; done"
現在,你可以使用以下命令停止此容器:
$ docker container stop quotes
當你嘗試暫停容器時,可能會注意到它需要一段時間(大約10秒)才能執行完成。為什麼會這樣? Docker將 Linux SIGTERM 訊號傳送到容器內執行的主程序。
在上面的命令中,容器的名稱用於指定要停止的容器。也可以使用容器ID。
你如何獲得容器ID?
有幾種方法可以做到這一點。手動方法是列出所有正在執行的容器,並在列表中找到您要查詢的容器。只需從那裡複製其ID。
更自動化的方法是使用shell指令碼和環境變數。例如,如果要獲取引號容器的ID,這是一個示例:
$ export CONTAINER_ID = $(docker container ls | grep quotes | awk '{print $1}')
這裡我們使用 AWK 獲取第一個欄位,即容器ID。現在,您可以在表示式中使用 $CONTAINER_ID 變數,而不是使用容器名稱:
$ docker container stop $CONTAINER_ID
一旦停止容器後,其狀態將更改為“已退出”。
你可以使用 docker container start 命令重新啟動已停止的容器。
移除容器
執行 docker container ls -a 命令時,您可以看到很多處於“已退出”狀態的容器。
如果您不再需要這些容器,最好將它們從記憶體中刪除;否則,他們會佔用寶貴的資源。刪除容器的命令如下:
$ docker container rm <container ID>
或者,也可以使用此命令:
$ docker container rm <container name>
有時,無法刪除正在執行的容器;如果要強制刪除,可以使用命令列引數 -f 或 -force。
容器化改變了行業執行方式,將維護成本降低了50%以上,並將產品上市時間縮短了約90%。此外,相對於容器外執行,容器使應用程式更安全。
如果你發現本教程有用並希望瞭解有關 Docker 容器的更多資訊,可以閱讀 Docker 的基礎知識 - Docker 18.x 的基礎知識,其中介紹了與容器化和編排相關的所有關鍵概念。
原文連結:ofollow,noindex" target="_blank">Docker Tutorial: Play With Containers (Simple Examples) (翻譯:Sam)