理解Docker(譯文)

原文出自https://docs.docker.com/introduction/understanding-docker/, 本文由[email protected]翻譯。

什麼是Docker?

Docker是一個用於開發、裝載和運行程度的開放平臺,可使你的程序遷移更加便捷。在Docker中可以將你的應用程序和基礎設施層隔離,並且還可以將你的基礎設施當作程序一樣進行管理。Docker可以幫助你更加快速地打包你代碼、更加快速地測試、更加快速地部署,並且可以減少寫代碼到部署運行代碼的週期。

Docker通過將一個輕量級的容器虛擬化平臺和一組標準工作流程、工具進行集成,來幫助你方便地管理和部署應用。

核心的是,Docker提供了一種在一個安全隔離的環境中運行幾乎所有程序方式,這種隔離性和安全性允許你在同一主機上同時運行多個容器,而容器的這種輕量級特性,意味着你可以節省更多的硬件資源,因爲你不必消耗運行hypervisor所需要的額外負載的。

圍繞容器虛擬化Docker提供了一些工具和一個平臺,可爲你提供以下幫助:

  • 將應用程序(包括支撐的組件)放入docker容器中;
  • 將這些容器打包並分發給你的團隊,以便於後續的開發和測試;
  • 將這些容器部署到生產環境中,即可以是本地的數據中心也可以在雲端。

我可以用Docker做些什麼?

快速分發你的應用

Docker是開發過程中較爲理想的助手,它允許你在包含了你的應用和服務的本地容器中進行開發,然後幫你完成集成和部署。

例如,你的開發人員可以在本地寫代碼然後通過Docker與其他同事共享,當他們完成了各自的開發任務後,可以將他們的代碼推送到一個測試的環境中進行測試,完成測試後便可以將相應的Docker鏡像部署到生產環境中。

更方便地進行部署和調整規模

Docker這種基於容器的平臺具有高度的便攜性,它可以無縫地運行於開發者的本地主機、數據中心其他的物理機或虛擬機、或者雲端。

Docker的便攜性和其天然的輕量特性易於實現動態地負載管理,你可以利用Docker快速地增減應用和服務的部署規模,Docker的速度保證了這種規模的調整近乎實時。

更高密度的部署應用和運行更多的應用

由於Docker輕量並且快速,因此相對於基於Hypervisor的虛擬機的部署方式,Docker提供了一種更可行和划算的替代方案,這對於高密度部署環境尤其有用,例如在構建私有云或平臺即服務環境時,當然,當你想在有限的資源裏部署更多的應用時,Docker對於小中型的部署也非常有用。

Docker主要包括哪些組件?

Docker主要包括兩個組件:

  • Docker: 開源的容器虛擬化平臺;
  • Docker Hub :用於分享和管理Docker容器的軟件即服務平臺。

: Docker在Apache 2.0開源協議下進行授權。

Docker的架構?

Docker是一種Client/Server的架構,Docker客戶端與Docker daemon進行交互,daemon負責構建、運行和發佈Docker容器。客戶端即可以和服務端運行在同一個系統中,也可以連接遠程的daemon。Docker的客戶端的daemon通過RESTful API進行sockets 通信。

docker-architecture.svg

Docker守護進程

就像上圖所示,Docker守護進程(daemon)在主機上運行,用戶不能直接和守護進程打交道,但是可以通過docker客戶端與其進行交互。

Docker客戶端

Docker客戶端——docker二進制文件的功能之一——是Docker的初始用戶界面,它接收用戶的命令並反饋,並且與Docker的守護進行交互。

Docker內部機制

理解Docker的內部機制,你需要明白如下三個組件:

  • Docker鏡像
  • Docker註冊中心
  • Docker容器

Docker鏡像

Docker鏡像是一個只讀的模塊。例如,一個鏡像可以包含一個安裝了apache WEB服務應用的Ubuntu操作系統。鏡像用來創建Docker容器。Docker提供了構建新鏡像或升級原有鏡像的較爲便利的方式,或者你也可以下載別人已經創建好的鏡像。Docker鏡像是Docker的構建組件。

Docker註冊中心

Docker註冊中心用於上傳和下載鏡像,有公共註冊中心和私有註冊中心兩種。公共註冊中心爲Docker Hub,它提供了大量的現成鏡像,你可以構建自己的鏡像上傳到上面,也可以在上面下載別人構建的鏡像。Docker註冊中心是Docker的發佈組件。

Docker容器

Docker容器與一個目錄很類似,它包含了一個應用程序運行所需要的一切內容。每個容器都是基於一個Docker鏡像製作的。Docker容器可被運行、開始、停止、遷移或者是刪除。每個容器均是一個隔離的、安全的應用平臺。Docker容器是Docker的運行組件。

Docker怎樣工作的

至此,我們已經知道了:

  1. 你可以構建用於存儲你的應用程序的鏡像;
  2. 你可以從Docker鏡像中創建容器用來運行你的應用;
  3. 你可以通過Docker Hub或者你自己的註冊中心來共享Docker鏡像

那我們看看Docker是怎麼將這些元素組合在一起工作的。

Docker鏡像是如何工作的

我們已經知道Docker鏡像實質上是一些用於加載Docker容器的只讀模板,每個鏡像包括很多層。Docker利用union file systems將這些層組合爲一個鏡像。Union file systems允許相互隔離的文件或目錄透明的疊加在一起,而呈現爲一個統一的文件系統。

Docker如此輕量化的原因也是由於這些層的存在。當你對一個Docker鏡像進行修改時——例如將一個應用升級爲一個新的版本——會構建一個新的層,因此,與虛擬機的替換整個鏡像或完全構建的方式不同,Docker僅對相關的層進行添加或升級。所以你僅需要發佈鏡像的更新部分而不必發佈整個鏡像,這種方式使得鏡像的發佈更加快速和簡單。

每個鏡像始於一個基礎鏡像,例如:ubuntu便是一個基礎的Ubuntu鏡像,fedora是一個基礎的Fedora鏡像。你也可以將你自己製作的鏡像作爲基礎鏡像,例如你可以將一個Apache鏡像作爲一個Web應用的基礎鏡像。

注意:Docker一般從Docker Hub上獲取基礎鏡像。

Docker鏡像從這些基礎鏡像中按照一系列的步驟進行製作,我們稱這些步驟爲指令,每個指令在你的鏡像中創建一個新的層,指令包括以下行爲:

  • 運行一條命令;
  • 添加一個文件或目錄;
  • 創建一個環境變量;
  • 從此鏡像中加載一個容器時需要運行的進程。

這些指令存儲在Dockerfile中,Docker在構建鏡像過程中讀取這個Dockerfile,運行裏面的指令並返回最終的鏡像。

Docker註冊中心如何工作的

Docker註冊中心是Docker鏡像的存儲中心,當你構建完一個鏡像後便可以將其推送到Docker Hub或你自己的註冊中心。

利用Docker客戶端,你可以搜索已經發布的鏡像,然後將其拉取到你的Docker主機上,以便於從這些鏡像中構建容器。

Docker Hub爲鏡像提供了公共的和私有的存儲空間。公共的存儲空間任何人均可以在上面搜索和下載,私有存儲空間僅對你本人或你的團隊開放搜索以及拉取下載,你可以通過這裏註冊一個私有的存儲空間。

容器是如何工作的

一個容器包括操作系統、用戶添加的文件以及相關的元數據。我們知道,每個容器都是從鏡像中構建出來的,這個鏡像告訴Docker容器用到什麼資源、當容器加載時啓動哪個進程以及容器啓動時的其他配置。Docker鏡像是隻讀的,當Docker從一個鏡像運行一個容器時,它會在鏡像的上層添加一個用於運行應用的可讀寫的層(利用的就是上文提到的union file system)。

運行一個容器時到底發生了什麼

Docker客戶端通過直接運行docker或者通過API調用的方式,可以通知Docker的守護進程運行一個容器。

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

我們來看一下這個命令,Docker客戶端利用docker命令跟一個run的選項啓動一個容器,一個最小配置的Docker客戶端運行一個容器需要告訴Docker守護進程以下事項:

  • 此容器基於什麼鏡像來構建,此處是ubuntu——一個基礎的Ubuntu鏡像;
  • 需要在容器中運行的命令,此處是/bin/bash——在容器中啓動一個Bash Shell。

那麼我們看看運行上述命令時到底發生了什麼?

按照順序,Docker依次幹了如下事情:

  • 拉取ubuntu鏡像 : Docker首先檢查一下ubuntu鏡像在本地服務器上存不存在,如果不存在,則自動從Docker Hub中下載,如果已經存在則直接利用這個鏡像來啓動一個新的容器。
  • 創建一個新的容器: 如果Docker本地服務器中存在這個鏡像,那麼就據此來啓動一個容器。
  • 分配一個文件每戶並且將其掛載到一個可讀寫的層: 容器在此文件系統中被創建,並且將其作爲一個可讀寫的層添加到鏡像中。
  • 分配一個網絡或橋接的接口: 創建一個網絡的接口以便於Docker容器能夠訪問本機。
  • 設置一個IP地址: 爲此容器從地址池中找到並綁定一個IP地址。
  • 執行指定的進程: 運行你的應用程序,然後;
  • 獲取並提供應用程序的輸出: 連接標準輸入、標準輸出和標準錯誤接口,這樣你便可以觀察到程序運行的一切。

現在你已經運行了一個容器,這樣你便可以管理你的容器、與應用程序進行交互,當運行結束是停止或者刪除你的容器。

底層技術問題

Docker是用Go語言實現的,用到了一些Linux內核的特性實現上述功能。

命名空間(namespaces)

Docker在爲容器提供一個隔離的工作空間時,用到了命名空間的技術,當你運行一個容器時,Docker會爲此容器創建一組命名空間。

這樣便可以提供一個隔離的層:每個容器運行在自己的命名空間中,而外部不能訪問這個層。

Docker用到的一些命名空間有:

  • pid命名空間: 用於隔離進程(PID:Process ID);
  • net命名空間: 用於管理網絡;
  • ipc命名空間: 用於訪問IPC資源(IPC:InterProcess Communication);
  • mnt命名空間: 用於管理掛載點(MNT:Mount);
  • uts命名空間: 用於隔離內核和版本標識(UTS:Unix Timesharing System)。

控制組(Control Groups)

Docker還用到了另外一項技術叫cgroups或者叫控制組(control groups)。實現程序運行環境的隔離的關鍵在於使這些程序只用到他們需要的資源,這就能夠保證這些容器是主機服務環境小社會中的好市民。控制組允許Docker在不同的容器之間共享硬件資源,需要時添加一些限制和約束,例如限制一個容器最大訪問內存量。

統一文件系統(Union file systems)

統一文件系統或者說是UnionFS,是創建層的時候用到的文件系統,使文件系統非常輕量和快速。Docker使用統一文件系統爲容器構建blocks,Docker可以使用幾種不同的文件系統:AUFS、btrfs、vfs以及DeviceMapper。

容器格式

Docker容器將這些組件合併在一起,我們稱之爲容器格式,容器的缺省格式稱爲libcontainer。Docker還支持利用LXC技術的傳統Linux容器格式,未來還將會支持其他的容器格式,例如:與BSD Jails或者Solaris Zones實現整合。

下一步

安裝Docker,請參照installation section

Docker用戶指南,請參照深入學習Docker

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章