1. 程式人生 > >Docker教程(3)理解Docker架構

Docker教程(3)理解Docker架構

Docker的主要元件

Docker有兩個主要元件:

  • Docker引擎:開源的容器化平臺;
  • Docker Hub:我們的用於分享和管理Docker容器的SAAS平臺。

Docker的架構

Docker使用一個C/S架構。Docker客戶端和Docker守護程序交流,Docker守護程序做非常重要的工作,構建,執行和分發你的Docker容器。Docker客戶端和守護程序可以執行在同樣的系統上,或者是你可以連線一個Docker客戶端到一個遠端Docker守護程序中。Docker客戶端和守護程序通過sockets或通過RESTful API進行溝通交流。

這裡寫圖片描述

Docker守護程序

正如上面的圖片顯示,Docker守護程序執行在一個主機機器中。使用者不直接和守護程序互動,而是通過Docker客戶端。

Docker客戶端

Docker客戶端,以docker二進位制的形式出現,是Docker最基本的使用者介面。他接收來自使用者的命令,然後和Docker守護程序來回溝通。

Docker內部

為了能夠理解Docker的內部,你需要去理解下面三個資源:

  • Docker映象
  • Docker註冊處
  • Docker容器
  • Docker映象
Docker映象

一個Docker映象是一個只讀的模板。例如,一個映象可以包含一個帶有Apache和你的web應用的Ubuntu作業系統。映象被用來建立Docker容器。Docker提供了一個簡單的方式來構建一個新的映象或更新一個存在的映象,或者是你可以下載其他人已經建立的Docker映象。Docker映象是Docker的build

元件。

Docker註冊處

Docker註冊處保留映象。這些是來自於上傳或下載映象的公共或私密儲存的地方。公共的Docker註冊處又Docker Hub提供。他提供了一個你可以使用的已存映象的集合。這些可以是你自己建立的或其他人建立的你可以使用的映象。Docker註冊處是Docker的distribution元件。

Docker容器

Docker容器和目錄是相似的。一個Docker容器可以儲存任何東西,這些東西是執行一個應用程式所必須的。每一個容器都是從一個Docker映象中建立的。Docker容器可以被執行,開啟,停止,移動和刪除。每一個容器都是一個分離的和安全的應用平臺。Docker容器是Docker的執行元件。

Docker映象如何工作

我們已經知道Docker映象是一個只讀的模板,在映象中Docker容器被建立。每一個容器包含一系列層。Docker使用union檔案系統來組合這些層到一個單一的映象中。Union檔案系統允許分離檔案系統的檔案和目錄作為分支,被透明化的覆蓋,構成一個單一的一致的檔案系統。

Docker非常輕量化的一個原因就是因為這些層。當你改變了一個Docker映象的時候–例如,更新一個應用程式到一個新版本–一個新的層被構建。因此,不是替換整個映象或整體重新構建。就像你可能在一個虛擬機器上工作,僅僅那一層被新增或更新。現在你不必釋出一個整體的新的映象,僅僅更新便可。這使得釋出Docker映象更快更簡單。

每一個映象都從一個基礎映象開始,例如,ubuntu,一個基本的Ubuntu映象,或者是fedora,一個基本的Fedora映象。你也可以使用你自己的映象作為新映象的基礎映象,例如,如果你有一個基本的Apache映象,你可以使用這個作為你的Web應用映象的基本映象。

Docker映象從這些基本映象中使用一個簡單的,可描述的步驟,我們稱作指令,被構件。每一個指令在我們的映象中建立一個新層。指令包含的行為類似於:

  • 執行一個命令
  • 新增一個檔案或目錄
  • 建立一個環境變數
  • 當從這個映象中建立了一個容器的時候哪一個程序執行

這些指令被儲存在被稱為Dockerfile的檔案中。一個Dockerfile是一個基於包含構件映象的指令和命令指令碼的文字檔案。當你需要構件一個映象,執行指令返回一個最終映象的時候,Docker讀取這個Dockerfile。

Docker註冊處如何工作

Docker註冊處是你的Docker映象的儲存處。一旦你構建了一個Docker映象,你可以將他推送到一個公共的註冊處例如Docker Hub或者是到你自己的註冊處。

使用Docker客戶端,你可以搜尋已經發布的映象和下載到你的Docker主機中來從他們中構建容器。

Docker Hub既提供公共的也提供私人的映象儲存。公共儲存可以被任何人搜尋和下載。私人儲存僅僅你和你的使用者可以下載使用。

容器如何工作

一個容器包含一個作業系統,使用者檔案和元資料。正如我們看到的,每一個容器都是從映象中被構建的。那個映象告訴Docker容器儲存什麼資料,當容器釋出的時候執行什麼程序,還有其他一些配置資料。Docker映象是隻讀的。當Docker從一個映象中執行一個容器的時候,他在映象的最頂層新增一個讀寫層(使用union檔案系統),在該層中你的應用程式可以執行。

當你執行一個容器的時候發生了啥

無論是使用docker二進位制還是API,Docker客戶端告訴Docker守護程式來執行一個容器。

$ docker run -i -t ubuntu /bin/bash

Docker引擎客戶端使用帶有run選項的docker二進位制執行一個新的容器。Docker客戶端需要告訴Docker守護程序執行容器的最低限度是:

  • 容器從哪一個Docker映象中構建的,例如,ubuntu
  • 當他被髮布的時候,內部容器想要執行的命令,例如,/bin/bash

所以,當我們執行這個命令的時候鉤子下面發生了什麼?

按照次序,Docker引擎做:

  • 推出ubuntu映象:Docker引擎檢查當前的ubuntu映象。如果映象已經存在,Docker引擎使用他作為新的容器。如果在當前主機上不存在,然後Docker引擎從Docker Hub中拉取下來;
  • 建立一個新的容器:一旦Docker引擎有映象,他便使用它來建立一個容器;
  • 分配檔案系統,掛載一個讀寫層:容器在檔案系統中被建立,並且一個讀寫層被新增到映象中;
  • 分配一個網路/橋介面。建立一個網路介面來允許Docker容器與本地主機交流;
  • 設定一個IP地址。從一個池中尋找和繫結一個可用的IP地址;
  • 執行一個你指定的程序。執行應用;
  • 捕獲和獲取應用輸出:連線和記錄標準輸入,輸出和錯誤,來告訴你你的應用是如何工作的;
  • 現在你就擁有一個執行的容器了。現在你可以管理你的容器,與你的應用互動,當結束的時候,可以停止和移除你的容器。

底層的技術

Docker是使用Go編寫的,使用多個核心特徵來分發其功能。

名稱空間

Docker充分使用稱為namespace的技術來提供分離的工作空間,我們稱為容器。當你執行一個容器,Docker為這個容器創造一些列名稱空間。

這個提供了一層分離:容器的每一個方面執行在他自己的明明空間中,並且不能訪問其名稱空間之外的資料。

Docker引擎在Linux中使用的名稱空間有:

  • pid名稱空間:程序分離;
  • net名稱空間:管理網路介面;
  • ipc名稱空間:管理IPC資源訪問;
  • mnt名稱空間:管理掛載點;
  • uts名稱空間:分離核心和版本識別。

控制組

在Linux上的Docker引擎也會使用其他的技術稱為cgroups或控制組。在分離體中執行程式的關鍵就是隻讓他們使用你想要的資源。這能保證容器在主機中是一個優秀的多租戶居民。控制組允許Docker引擎共享可用硬體資源,如果必要,設定限制和約束。例如,為特定容器限制可用記憶體。

Union檔案系統

Union檔案系統或者是UnionFS,是一個檔案系統,其通過建立層來操作,使得他們更加輕量化和快速。Docker引擎使用union檔案系統來為容器提供構件塊。Docker引擎可以使用多個union檔案系統變數,包括AUFS,btrfs,vfs和DeviceMapper。

容器格式

Docker引擎組合這些元件到一個包中,我們稱為一個容器格式。預設的容器格式被稱為libcontainer。在將來,Docker可能支援其他容器格式,例如,通過整合BSD Jails或Solaris Zones。