來源:21CTO
ID:www_21cto_com
Docker 作為新瓶裝舊酒的一門技術,用簡單便捷的操作極大改變了軟體開發的流程與生態環境,本文我們就來瞭解一下。註:Docker 目前已改名為 Moby。
更新曆史
-
2017.05.01: 完成初稿
快速入門
-
Docker 最初 dotCloud 公司內部的一個業餘專案
-
Docker 基於 Go 語言
-
Docker 專案的標的是實現輕量級的作業系統虛擬化解決方案
-
Docker 的基礎是 Linux 容器(LXC)等技術
-
Docker 容器的啟動可以在秒級實現,這相比傳統的虛擬機器方式要快得多
-
Docker 對系統資源的利用率很高,一臺主機上可以同時執行數千個 Docker 容器
下麵的圖片比較了 Docker 和傳統虛擬化方式的不同之處,可見容器是在作業系統層面上實現虛擬化,直接復用本地主機的作業系統,而傳統方式則是在硬體層面實現。
容器除了執行其中應用外,基本不消耗額外的系統資源,使得應用的效能很高,同時系統的開銷儘量小。傳統虛擬機器方式執行 10 個不同的應用就要起 10 個虛擬機器,而Docker 只需要啟動 10 個隔離的應用即可。
主要優勢為:
-
更快速的交付和部署 – 容器成為了最小單位
-
更高效的虛擬化 – 核心級虛擬化
-
更輕鬆的遷移和拓展
-
更簡單的管理
安裝
官方網站提供了 Mac, Linux 和 Windows 版本的安裝教程。我們只要跟著官方檔案即可,這裡不再贅述。
不過需要提一下 Kitematic 這個圖形化工具(官方給出的定義是 Visual Docker Container Management on Mac & Windows),對於熟悉和瞭解 Docker 是很好的幫助,大家可以體驗一下。
守護行程
執行 Docker 守護行程時,可以用 -H 來改變系結介面的方式,比如 sudo /usr/bin/docker -d -H tcp://0.0.0.0:2375,如果不想每次都輸入這麼長的命令,需要加入以下環境變數 export DOCKER_HOST=”tcp://0.0.0.0:2375″
圖形使用者介面
雖然我們可以用命令來控制 docker,但是如果能有一個 web 管理介面,操作什麼的會方便很多,比較常見的有
-
Shipyard
-
Potainer
基本概念
基本概念主要有三個:
-
映象(Image)
-
一個只讀的模板,映象可以用來建立 Docker 容器
-
使用者基於映象來執行自己的容器。映象是基於 Union 檔案系統的層式結構
-
可以簡單建立或更新現有映象,或者直接下載使用其他人的。可以理解為生成容器的『原始碼』
-
容器(Container)
-
容器是從映象建立的執行實體,在啟動的時候建立一層可寫層作為最上層(因為映象是隻讀的)
-
可以被啟動、開始、停止、刪除。每個容器都是相互隔離的、保證安全的平臺
-
可以把容器看做是一個簡易版的 Linux 環境(包括root使用者許可權、行程空間、使用者空間和網路空間等)和執行在其中的應用程式
-
倉庫(Registry)
-
集中存放映象檔案的場所,可以是公有的,也可以是私有的
-
最大的公開倉庫是 Docker Hub
-
國內的公開倉庫包括 Docker Pool 等
-
當使用者建立了自己的映象之後就可以使用 push 命令將它上傳到公有或者私有倉庫,這樣下次在另外一臺機器上使用這個映象時候,只需要從倉庫上 pull 下來就可以了
-
Docker 倉庫的概念跟 Git 類似,註冊伺服器可以理解為 GitHub 這樣的託管服務
另外 Docker 採用的是客戶端/伺服器架構,客戶端只需要向 Docker 伺服器或守護行程發出請求即可完成各類操作。那麼問題來了,我們能用 Docker 來做什麼呢?我們可以:
-
統一、最佳化和加速本地開發和構建流程
-
保證不同的環境中可以得到相同的執行結果
-
建立隔離環境用於測試
Docker 可以提供的隔離有:
-
檔案系統隔離:每個容器都有自己的 root 檔案系統
-
行程隔離:每個容器都執行在自己的行程環境中
-
網路隔離:容器間的虛擬網路介面和 IP 地址都是分開的
-
資源隔離和分組:使用 cgroups 將 CPU 和記憶體之類的資源獨立分配給每個 Docker 容器
常用命令
-
檢視 docker 狀態 sudo docker info
-
檢視系統中正在執行的容器的串列 docker ps
-
加上 -a 可以列出所有容器
-
加上 -l 可以列出最後一次執行的容器
一個簡單的例子
接下來我們用一個簡單的例子來體驗下 docker
容器小介紹
容器是獨立執行的一個或一組應用,以及它們的執行態環境。對應的,虛擬機器可以理解為模擬執行的一整套作業系統(提供了執行態環境和其他系統環境)和跑在上面的應用。
啟動容器有兩種方式,一種是基於映象新建一個容器並啟動,另外一個是將在終止狀態(stopped)的容器重新啟動。因為 Docker 的容器實在太輕量級了,很多時候使用者都是隨時刪除和新建立容器(對於初級應用來說後者更方便)。
當利用 docker run 來建立容器時,Docker 在後臺執行的標準操作包括:
-
檢查本地是否存在指定的映象,不存在就從公有倉庫下載
-
利用映象建立並啟動一個容器
-
分配一個檔案系統,併在只讀的映象層外面掛載一層可讀寫層
-
從宿主主機配置的網橋介面中橋接一個虛擬介面到容器中去
-
從地址池配置一個 ip 地址給容器
-
執行使用者指定的應用程式
-
執行完畢後容器被終止
可以利用 docker start 命令,直接將一個已經終止的容器啟動執行。
執行容器
現在,我們來建立一個 ubuntu:14.04 的容器 docker run ubuntu:14.04 /bin/echo ‘Hello wdx!’(結果如下圖所示)
可以看到正確輸出了我們的 “Hello wdx!”
接下來,我們用 docker run -t -i ubuntu:14.04 /bin/bash 可以啟動一個 bash 終端用來互動。引數的意思是:
-
-t 選項讓Docker分配一個偽終端(pseudo-tty)並系結到容器的標準輸入上
-
-i 則讓容器的標準輸入保持開啟
我們可以輸入一些命令來測試
容器的核心為所執行的應用程式,所需要的資源都是應用程式執行所必需的。除此之外,並沒有其它的資源。我們用 ps 或 top 在偽終端中檢視行程資訊,可以看到只有我們執行的行程,沒有其他花裡胡哨的(上圖最後一條命令)
試一試如下命令
-
cat /etc/hosts
-
ip a
-
ps -aux
-
cd ~ && echo “hello wdx” > hello.txt && cat hello.txt
(細心的同學可能會發現這裡的輸出暗藏玄機)
操作完成後,輸入 exit 便可以退出這個 ubuntu 容器。退出之後這個容器依然存在,我們可以用 docker ps -l來看看:
每個容器有一個 Container ID 和 Name,我們一般就是透過這倆來定位一個容器的。
映象
我們可以使用 docker pull 命令從倉庫中獲取所需要的映象。比如說 sudo docker pull ubuntu:12.04,相當於 sudo docker pull registry.hub.docker.com/ubuntu:12.04,即從註冊伺服器 registry.hub.docker.com中的 ubuntu 倉庫來下載標記為12.04 的映象。
如果想從其他倉庫註冊伺服器下載,需要輸入完成的地址,例如:sudo docker pull dl.dockerpool.com:5000/ubuntu:12.04
下載完成之後就可以使用該映象了,比如下麵的陳述句就會建立容器,其中執行 bash:sudo docker run -t -i ubuntu:12.04 /bin/bash
可以使用 dokcer images 來顯示本地已有的映象,如下
具體欄位的意思一目瞭然,這裡不再贅述。然後我們來執行官方例子 whalesay 映象。
執行映象
開啟瀏覽器,進入 Docker Hub
搜尋 whalesay 這個映象,就可以看到結果,點進去可以看到詳細內容(基於 Ubuntu)
然後我們來執行一下,使用命令 docker run docker/whalesay cowsay boo,其中 cowsay 是要執行的命令,後面的 boo 是引數。
Docker 會先在本地查詢有沒有映象,如果沒有就從倉庫中下載,具體的執行結果是:
也可以讓鯨魚說不同的話,比如:
製作映象
如果想要製作自己的映象,需要自己寫 Dockerfile。具體步驟如下
1、建立一個檔案夾 mkdir wdxtub; cd wdxtub,構造映象所需的所有東西都會放在這個檔案夾中
2、建立一個名為 Dockerfile 的檔案 gedit Dockerfile
3、新增第一句話 FROM docker/whalesay:latest,表示我們的映象以 whalesay 為基礎
4、新增需要執行的命令,如 RUN apt-get -y update && apt-get install -y fortunes(fortunes 這個程式會輸出名言警句)
5、透過 CMD 指定映象載入之後需要執行的命令,如 CMD /usr/games/fortune -a | cowsay
6、儲存並關閉 Dockerfile
7、使用 sudo docker build -t wdx-whale . 來構造映象,簡單來說就是用 Dockerfile 中的內容按步驟構造
8、使用 docker images 應該就可以看到我們新建立的映象
然後我們就可以執行一下看看 docker run wdx-whale
還有更賤的(感覺可以玩一天)
如果想要把自己的映象上傳到網上,就需要註冊一個 Docker Hub 帳號,然後點選 Create Repository,這裡我建立了一個名為 wdxtub/demo 的公用倉庫。
接下來我們需要打上 tag,目前 docker images 的情況是:
記住我們的 IMAGE ID 26ac9649d7da。用以下命令打 tag docker tag 26ac9649d7da wdxtub/wdx-whale:latest,然後再 docker images 一次:
然後用這個命令登入 docker login –username=yourhubusername –email=youremail@company.com,對於我來說就是 docker login –username=wdxtub –email=dacrocodilee@gmail.com
成功之後大概是這樣:
然後就可以 push 上去了 docker push wdxtub/wdx-whale,像下麵這樣
為了測試 pull 自己的映象,我們先把本地上的 whale 映象刪掉:docker rmi -f wdxtub/wdx-whale; docker rmi -f wdx-whale(如果有其他的用不著的也都刪掉),最後剩下(上課要用的映象):
接著來執行一下 docker run wdxtub/wdx-whale
管理映象
我們可以把映象匯出到本地檔案,使用 docker save 命令即可,比如針對我現在有的映象 wdxtub/wdx-whale(id:26ac9649d7da),可以這樣:docker save -o wdx-local-whale.tar wdxtub/wdx-whale。如果要載入的話,使用下麵的命令即可(會載入相關的元資料資訊)
docker load --input wdx-local-whale.tar
# 或者
docker load local-whale.tar
在刪除映象之前要先用 docker rm 刪掉依賴於這個映象的所有容器.
sudo docker rmi $(docker images -q -f "dangling=true")
映象的實現原理
Docker 映象是怎麼實現增量的修改和維護的? 每個映象都由很多層次構成,Docker 使用 Union FS 將這些不同的層結合到一個映象中去。
通常 Union FS 有兩個用途, 一方面可以實現不借助 LVM、RAID 將多個 disk 掛到同一個目錄下,另一個更常用的就是將一個只讀的分支和一個可寫的分支聯合在一起,Live CD 正是基於此方法可以允許在映象不變的基礎上允許使用者在其上進行一些寫操作。 Docker 在 AUFS 上構建的容器也是利用了類似的原理。
容器
啟動
舉個例子,
後臺執行
更多的時候,需要讓 Docker在後臺執行而不是直接把執行命令的結果輸出在當前宿主機下。此時,可以透過新增 -d 引數來實現。
下麵舉兩個例子來說明一下。
如果不使用 -d 引數執行容器 docker run ubuntu:14.04 /bin/sh -c “while true; do echo hello world; sleep 1; done” 容器會把輸出的結果(STDOUT)列印到宿主機上面
如果使用了 -d 引數執行容器 docker run -d ubuntu:14.04 /bin/sh -c “while true; do echo hello world; sleep 1; done”,則顯示是這樣:
使用 docker logs containerid 可以檢視輸出,如:
使用 -d 引數啟動後會傳回一個唯一的 id,也可以透過 docker ps 命令來檢視容器資訊。容器是否會長久執行,是和docker run指定的命令有關,和 -d 引數無關
在使用 -d 引數時,容器啟動後會進入後臺。 某些時候需要進入容器進行操作,有很多種方法,包括使用 docker attach 命令或 nsenter 工具等。具體參考這裡
終止與重新啟動
使用 docker stop containerid 來終止容器。終止狀態的容器可以用 docker ps -a 命令看到。
另外,docker restart containerid 命令會將一個執行態的容器終止,然後再重新啟動它。
匯入匯出與刪除
如果要匯出本地某個容器,可以使用 docker export containerid 命令。
可以使用 docker import 從容器快照檔案中再匯入為映象,例如
cat ubuntu.tar | sudo docker import - test/ubuntu:v1.0
# 也可以透過指定 URL 或者某個目錄來匯入,例如
docker import http://example.com/exampleimage.tgz example/imagerepo
使用者既可以使用 docker load 來匯入映象儲存檔案到本地映象庫,也可以使用docker import 來匯入一個容器快照到本地映象庫。這兩者的區別在於容器快照檔案將丟棄所有的歷史記錄和元資料資訊(即僅儲存容器當時的快照狀態),而映象儲存檔案將儲存完整記錄,體積也要大。此外,從容器快照檔案匯入時可以重新指定標簽等元資料資訊。
可以使用 docker rm 來刪除一個處於終止狀態的容器。如果要刪除一個執行中的容器,可以新增 -f 引數。Docker 會傳送 SIGKILL 訊號給容器。
用 docker ps -a 命令可以檢視所有已經建立的包括終止狀態的容器,如果數量太多要一個個刪除可能會很麻煩,用 docker rm $(docker ps -a -q) 可以全部清理掉。
註意:這個命令其實會試圖刪除所有的包括還在執行中的容器,不過就像上面提過的docker rm 預設並不會刪除執行中的容器。
倉庫
倉庫(Repository)是集中存放映象的地方。
一個容易混淆的概念是註冊伺服器(Registry)。實際上註冊伺服器是管理倉庫的具體伺服器,每個伺服器上可以有多個倉庫,而每個倉庫下麵有多個映象。從這方面來說,倉庫可以被認為是一個具體的專案或目錄。例如對於倉庫地址dl.dockerpool.com/ubuntu 來說,dl.dockerpool.com 是註冊伺服器地址,ubuntu是倉庫名。
大部分時候,並不需要嚴格區分這兩者的概念。相信資訊可以直接看教程,這裡不贅述了。
-
Docker Hub 指南
-
私有倉庫指南
-
配置檔案指南
參考連結
-
Docker —— 從入門到實踐
-
Install Docker Machine
來自:小土刀
連結:https://wdxtub.com/2017/05/01/docker-guide/
《Linux雲端計算及運維架構師高薪實戰班》2018年11月26日即將開課中,120天衝擊Linux運維年薪30萬,改變速約~~~~
*宣告:推送內容及圖片來源於網路,部分內容會有所改動,版權歸原作者所有,如來源資訊有誤或侵犯權益,請聯絡我們刪除或授權事宜。
– END –