每天5分鐘玩轉Docker容器技術(二)

阿里云云棲社群發表於2019-02-27

容器核心知識

本篇通過 Docker 討論容器的核心知識。

概述

容器核心知識主要回答有關容器 What、Why 和 How 三個問題。其中 How 是重點,將從架構、映象、容器、網路和儲存幾個方面進行講解。

What - 什麼是容器?

容器是一種輕量級、可移植、自包含的軟體打包技術,使應用程式可以在幾乎任何地方以相同的方式執行。開發人員在自己筆記本上建立並測試好的容器,無需任何修改就能夠在生產系統的虛擬機器、物理伺服器或公有云主機上執行。

容器與虛擬機器

談到容器,就不得不將它與虛擬機器進行對比,因為兩者都是為應用提供封裝和隔離。

容器由兩部分組成:

  1. 應用程式本身
  2. 依賴:比如應用程式需要的庫或其他軟體

容器在 Host 作業系統的使用者空間中執行,與作業系統的其他程式隔離。這一點顯著區別於的虛擬機器。

傳統的虛擬化技術,比如 VMWare, KVM, Xen,目標是建立完整的虛擬機器。為了執行應用,除了部署應用本身及其依賴(通常幾十 MB),還得安裝整個作業系統(幾十 GB)。

下圖展示了二者的區別。

每天5分鐘玩轉Docker容器技術(二)

如圖所示,由於所有的容器共享同一個 Host OS,這使得容器在體積上要比虛擬機器小很多。另外,啟動容器不需要啟動整個作業系統,所以容器部署和啟動速度更快,開銷更小,也更容易遷移。

Why - 為什麼需要容器?

為什麼需要容器?容器到底解決的是什麼問題?
簡要的答案是:容器使軟體具備了超強的可移植能力

容器解決的問題

我們來看看今天的軟體開發面臨著怎樣的挑戰?

如今的系統在架構上較十年前已經變得非常複雜了。以前幾乎所有的應用都採用三層架構(Presentation/Application/Data),系統部署到有限的幾臺物理伺服器上(Web Server/Application Server/Database Server)。

而今天,開發人員通常使用多種服務(比如 MQ,Cache,DB)構建和組裝應用,而且應用很可能會部署到不同的環境,比如虛擬伺服器,私有云和公有云。

每天5分鐘玩轉Docker容器技術(二)

一方面應用包含多種服務,這些服務有自己所依賴的庫和軟體包;另一方面存在多種部署環境,服務在執行時可能需要動態遷移到不同的環境中。這就產生了一個問題:

如何讓每種服務能夠在所有的部署環境中順利執行?

於是我們得到了下面這個矩陣:

每天5分鐘玩轉Docker容器技術(二)

各種服務和環境通過排列組合產生了一個大矩陣。開發人員在編寫程式碼時需要考慮不同的執行環境,運維人員則需要為不同的服務和平臺配置環境。對他們雙方來說,這都是一項困難而艱鉅的任務。

如何解決這個問題呢?

聰明的技術人員從傳統的運輸行業找到了答案。

幾十年前,運輸業面臨著類似的問題。

每天5分鐘玩轉Docker容器技術(二)

每一次運輸,貨主與承運方都會擔心因貨物型別的不同而導致損失,比如幾個鐵桶錯誤地壓在了一堆香蕉上。另一方面,運輸過程中需要使用不同的交通工具也讓整個過程痛苦不堪:貨物先裝上車運到碼頭,卸貨,然後裝上船,到岸後又卸下船,再裝上火車,到達目的地,最後卸貨。一半以上的時間花費在裝、卸貨上,而且搬上搬下還容易損壞貨物。

這同樣也是一個 NxM 的矩陣。

每天5分鐘玩轉Docker容器技術(二)

幸運的是,集裝箱的發明解決這個難題。

每天5分鐘玩轉Docker容器技術(二)

任何貨物,無論鋼琴還是保時捷,都被放到各自的集裝箱中。集裝箱在整個運輸過程中都是密封的,只有到達最終目的地才被開啟。標準集裝箱可以被高效地裝卸、重疊和長途運輸。現代化的起重機可以自動在卡車、輪船和火車之間移動集裝箱。集裝箱被譽為運輸業與世界貿易最重要的發明。

每天5分鐘玩轉Docker容器技術(二)

Docker 將集裝箱思想運用到軟體打包上,為程式碼提供了一個基於容器的標準化運輸系統。Docker 可以將任何應用及其依賴打包成一個輕量級、可移植、自包含的容器。容器可以執行在幾乎所有的作業系統上。

每天5分鐘玩轉Docker容器技術(二)

其實,“集裝箱” 和 “容器” 對應的英文單詞都是 “Container”。
“容器” 是國內約定俗成的叫法,可能是因為容器比集裝箱更抽象,更適合軟體領域的原故吧。

我個人認為:在老外的思維中,“Container” 只用到了集裝箱這一個意思,Docker 的 Logo 不就是一堆集裝箱嗎?

每天5分鐘玩轉Docker容器技術(二)


Docker 的特性

我們可以看看集裝箱思想是如何與 Docker 各種特性相對應的。

每天5分鐘玩轉Docker容器技術(二)

容器的優勢

對於開發人員 - Build Once, Run Anywhere

容器意味著環境隔離和可重複性。開發人員只需為應用建立一次執行環境,然後打包成容器便可在其他機器上執行。另外,容器環境與所在的 Host 環境是隔離的,就像虛擬機器一樣,但更快更簡單。

對於運維人員 - Configure Once, Run Anything

只需要配置好標準的 runtime 環境,伺服器就可以執行任何容器。這使得運維人員的工作變得更高效,一致和可重複。容器消除了開發、測試、生產環境的不一致性。

How - 容器是如何工作的?

接下來學習容器核心知識的最主要部分。

我們首先會介紹 Docker 的架構,然後分章節詳細討論 Docker 的映象、容器、網路和儲存。

Docker 架構詳解

Docker 的核心元件包括:

  1. Docker 客戶端 - Client
  2. Docker 伺服器 - Docker daemon
  3. Docker 映象 - Image
  4. Registry
  5. Docker 容器 - Container

Docker 架構如下圖所示:

每天5分鐘玩轉Docker容器技術(二)

Docker 採用的是 Client/Server 架構。客戶端向伺服器傳送請求,伺服器負責構建、執行和分發容器。客戶端和伺服器可以執行在同一個 Host 上,客戶端也可以通過 socket 或 REST API 與遠端的伺服器通訊。

Docker 客戶端

最常用的 Docker 客戶端是 docker 命令。通過 docker 我們可以方便地在 Host 上構建和執行容器。

docker 支援很多操作(子命令),後面會逐步用到。

每天5分鐘玩轉Docker容器技術(二)

除了 docker 命令列工具,使用者也可以通過 REST API 與伺服器通訊。

Docker 伺服器

Docker daemon 是伺服器元件,以 Linux 後臺服務的方式執行。

每天5分鐘玩轉Docker容器技術(二)

Docker daemon 執行在 Docker host 上,負責建立、執行、監控容器,構建、儲存映象。

預設配置下,Docker daemon 只能響應來自本地 Host 的客戶端請求。如果要允許遠端客戶端請求,需要在配置檔案中開啟 TCP 監聽,步驟如下:

1.編輯配置檔案 /etc/systemd/system/multi-user.target.wants/docker.service,在環境變數 ExecStart 後面新增 -H tcp://0.0.0.0,允許來自任意 IP 的客戶端連線。

每天5分鐘玩轉Docker容器技術(二)

如果使用的是其他作業系統,配置檔案的位置可能會不一樣。

2.重啟 Docker daemon。

每天5分鐘玩轉Docker容器技術(二)

3.伺服器 IP 為 192.168.56.102,客戶端在命令列里加上 -H 引數,即可與遠端伺服器通訊。

每天5分鐘玩轉Docker容器技術(二)

info 子命令用於檢視 Docker 伺服器的資訊。

Docker 映象

可將 Docker 映象看成只讀模板,通過它可以建立 Docker 容器。

例如某個映象可能包含一個 Ubuntu 作業系統、一個 Apache HTTP Server 以及使用者開發的 Web 應用。

映象有多種生成方法:

  1. 可以從無到有開始建立映象
  2. 也可以下載並使用別人建立好的現成的映象
  3. 還可以在現有映象上建立新的映象

我們可以將映象的內容和建立步驟描述在一個文字檔案中,這個檔案被稱作 Dockerfile,通過執行 docker build <docker-file> 命令可以構建出 Docker 映象,後面我們會討論。

Docker 容器

Docker 容器就是 Docker 映象的執行例項。

使用者可以通過 CLI(docker)或是 API 啟動、停止、移動或刪除容器。可以這麼認為,對於應用軟體,映象是軟體生命週期的構建和打包階段,而容器則是啟動和執行階段。

Registry

Registry 是存放 Docker 映象的倉庫,Registry 分私有和公有兩種。

Docker Hub(https://hub.docker.com/) 是預設的 Registry,由 Docker 公司維護,上面有數以萬計的映象,使用者可以自由下載和使用。

出於對速度或安全的考慮,使用者也可以建立自己的私有 Registry。後面我們會學習如何搭建私有 Registry。

docker pull 命令可以從 Registry 下載映象。 docker run 命令則是先下載映象(如果本地沒有),然後再啟動容器。

Docker 元件如何協作?

一個完整的例子

還記得我們執行的第一個容器嗎?現在通過它來體會一下 Docker 各個元件是如何協作的。

容器啟動過程如下:

每天5分鐘玩轉Docker容器技術(二)
  1. Docker 客戶端執行 docker run 命令。
  2. Docker daemon 發現本地沒有 httpd 映象。
  3. daemon 從 Docker Hub 下載映象。
  4. 下載完成,映象 httpd 被儲存到本地。
  5. Docker daemon 啟動容器。

docker images 可以檢視到 httpd 已經下載到本地。

每天5分鐘玩轉Docker容器技術(二)

docker ps 或者 docker container ls 顯示容器正在執行。

每天5分鐘玩轉Docker容器技術(二)

小結

Docker 借鑑了集裝箱的概念。標準集裝箱將貨物運往世界各地,Docker 將這個模型運用到自己的設計哲學中,唯一不同的是:集裝箱運輸貨物,而 Docker 運輸軟體。

每個容器都有一個軟體映象,相當於集裝箱中的貨物。容器可以被建立、啟動、關閉和銷燬。和集裝箱一樣,Docker 在執行這些操作時,並不關心容器裡到底裝的什麼,它不管裡面是 Web Server,還是 Database。

使用者不需要關心容器最終會在哪裡執行,因為哪裡都可以執行。

開發人員可以在筆記本上構建映象並上傳到 Registry,然後 QA 人員將映象下載到物理或虛擬機器做測試,最終容器會部署到生產環境。

使用 Docker 以及容器技術,我們可以快速構建一個應用伺服器、一個訊息中介軟體、一個資料庫、一個持續整合環境。因為 Docker Hub 上有我們能想到的幾乎所有的映象。

不知大家是否意識到,潘多拉盒子已經被開啟。容器不但降低了我們學習新技術的門檻,更提高了效率。

如果你是一個運維人員,想研究負載均衡軟體 HAProxy,只需要執行 docker run haproxy,無需繁瑣的手工安裝和配置既可以直接進入實戰。

如果你是一個開發人員,想學習怎麼用 django 開發 Python Web 應用,執行 docker run django,在容器裡隨便折騰吧,不用擔心會搞亂 Host 的環境。

不誇張的說:容器大大提升了 IT 人員的幸福指數。

最小的映象

映象是 Docker 容器的基石,容器是映象的執行例項,有了映象才能啟動容器。

本章內容安排如下:

  1. 首先通過研究幾個典型的映象,分析映象的內部結構。
  2. 然後學習如何構建自己的映象。
  3. 最後介紹怎樣管理和分發映象。

映象的內部結構

為什麼我們要討論映象的內部結構?

如果只是使用映象,當然不需要了解,直接通過 docker 命令下載和執行就可以了。

但如果我們想建立自己的映象,或者想理解 Docker 為什麼是輕量級的,就非常有必要學習這部分知識了。

我們從一個最小的映象開始吧。

hello-world - 最小的映象

hello-world 是 Docker 官方提供的一個映象,通常用來驗證 Docker 是否安裝成功。

我們先通過 docker pull 從 Docker Hub 下載它。

每天5分鐘玩轉Docker容器技術(二)

docker images 命令檢視映象的資訊。

每天5分鐘玩轉Docker容器技術(二)

hello-world 映象竟然還不到 2KB!

通過 docker run 執行。

每天5分鐘玩轉Docker容器技術(二)

其實我們更關心 hello-world 映象包含哪些內容。

Dockerfile 是映象的描述檔案,定義瞭如何構建 Docker 映象。Dockerfile 的語法簡潔且可讀性強,後面我們會專門討論如何編寫 Dockerfile。

hello-world 的 Dockerfile 內容如下:

每天5分鐘玩轉Docker容器技術(二)

只有短短三條指令。

  1. FROM scratch
    此映象是從白手起家,從 0 開始構建。
  2. COPY hello /
    將檔案“hello”複製到映象的根目錄。
  3. CMD ["/hello"]
    容器啟動時,執行 /hello

映象 hello-world 中就只有一個可執行檔案 “hello”,其功能就是列印出 “Hello from Docker ......” 等資訊。

/hello 就是檔案系統的全部內容,連最基本的 /bin,/usr, /lib, /dev 都沒有。

hello-world 雖然是一個完整的映象,但它並沒有什麼實際用途。通常來說,我們希望映象能提供一個基本的作業系統環境,使用者可以根據需要安裝和配置軟體。

這樣的映象我們稱作 base 映象。

作者:cloudman6

原文


相關文章