Docker基礎原理

kobejayandy發表於2018-06-30

前言


Docker和容器不是一個意思,Docker包含實現虛擬化技術的一系列技術,而容器(container)只是其中的一個元件。

Docker可以給你帶來什麼?


  1. 更快交付你的應用(Faster delivery of your applications)
  2. 讓部署和測試更簡單(Deploying and scaling more easily)
  3. 實現更高密度和更多的負載(Achieving higher density and running more workloads)

目標


Docker專案的目標是實現輕量級的作業系統虛擬化解決方案,建立軟體程式可移植的輕量容器。

底層實現


  1. Docker 的基礎是Linux容器(LXC)等技術,最新的版本開始使用Libcontainer替代LXC。
  2. 在LXC的基礎上Docker進行了進一步的封裝,讓使用者不需要去關心容器的管理,使得操作更為簡便。
  3. Docker使用CGroups來提供容器隔離,而Union檔案系統用於儲存映象並使容器變得短暫。

Cgroups:Cgroups是Linux核心功能,它讓兩件事情變成可能:限制Linux程式組的資源佔用(記憶體、CPU);為程式組製作 PID、UTS、IPC、網路、使用者及裝載名稱空間。
Union檔案系統:在union檔案系統裡,檔案系統可以被裝載在其他檔案系統之上,其結果就是一個分層的積累變化。如下圖:


union檔案系統

與虛擬機器的關係


使用者操作Docker的容器就像操作一個快速輕量級的虛擬機器一樣簡單。
但是它們還是有很大的區別的,看下面兩幅圖:


virtualization應用

docker應用

官網的說法是:虛擬機器上的應用不僅包含了應用本身、必要的依賴(二進位制和庫包等),還包括整個作業系統;而docker應用不同,共享系統核心,僅僅包含應用本身和依賴。

docker的優勢:

特性容器虛擬機器
啟動秒級分鐘級
硬碟使用一般為 MB一般為 GB
效能接近原生弱於原生
系統支援量單機支援上千個容器一般幾十個

docker的特性:

  • 互動式Shell:Docker可以分配一個虛擬終端並關聯到任何容器的標準輸入上,例如執行一個一次性互動shell
  • 檔案系統隔離:每個程式容器執行在完全獨立的根檔案系統裡
  • 寫時複製:採用寫時複製方式建立根檔案系統,這讓部署變得極其快捷,並且節省記憶體和硬碟空間
  • 資源隔離:可以使用cgroup為每個程式容器分配不同的系統資源
  • 網路隔離:每個程式容器執行在自己的網路名稱空間裡,擁有自己的虛擬介面和IP地址
  • 日誌記錄:Docker將會收集和記錄每個程式容器的標準流(stdout/stderr/stdin),用於實時檢索或批量檢索
  • 變更管理:容器檔案系統的變更可以提交到新的映像中,並可重複使用以建立更多的容器。無需使用模板或手動配置

一般情況下

Linux(如ubuntu)執行一個應用,如tomcat,它需要依賴Java環境吧,其實就(可能)是把Java放在/usr/lib下,然後配置使用者環境,使你可以在shell(如bash)上使用java指令,(可選)然後關聯tomcat的bin目錄下的startup.sh到使用者環境上,完成上面兩個步驟,就可以把tomcat執行起來。

docker方面

相對上面的tomcat例子,Docker就是通過

  1. 使用Cgroups隔離計算機資源,使計算機可以執行很多的服務;
  2. 使用Namespace分離打包服務執行時需要的所有依賴——java、tomcat,方便移植到新的計算機上,可以看下圖(MacOS系統上執行docker),你會發現此容器已經有java和tomcat;


    MacOS上docker執行tomcat
  3. 使用Union檔案系統,把所有的操作記錄在Dockerfile(構建映象的藍圖);
  4. 還有兩個特別重要的功能,對映埠和外掛資料卷,對映埠負責接受把docker容器裡的某個埠與主機某個埠繫結(請看下面的注意),外掛資料卷就是把war包放置的路徑對映到主機上的某個路徑,達到業務邏輯和資料持久化分割開,是不是頗有MVC的熟悉感。

注意:這裡的埠對映有一個坑,在非Linux上安裝docker(比如Windows和MacOS),都是在本機上安裝Linux的虛擬機器,所有當你在docker執行tomcat時,訪問“localhost:8080”是不會有響應的,你應該把localhost換成執行此docker的Linux虛擬機器的IP地址。但是在Linux上,就可以通過"localhost:8080"訪問到tomcat。這坑很深,我剛接觸docker就因為此坑差點放棄了。

Docker結構引擎


引擎元件圖

注意上圖,顯示的是docker主要元件。

  1. Server,就是一個守護程式,它會一直執行在後臺;
  2. REST API,說明如何與server互動和指示它執行命令;
  3. Client,是客戶書寫指令的地方,也俗稱shell,看下圖:


    iTerm執行docker
  4. Image,俗稱映象;
  5. Container,俗稱容器,裝載和執行映象;
  6. Network,俗稱網路,容器通過暴露埠與主機埠繫結,達到接受來自主機的訊號;
  7. Volume,俗稱外掛,為了能夠持久化資料以及共享容器間的資料,Docker提出了Volume的概念。

正如上面提到的內容,docker的基礎就是這幾塊內容。往深一點,就是swarm之類的雲端計算概念了。


Docker執行流程


docker執行流程

正如上圖所示,當我們想執行一個容器的時候,docker會:

  1. 拉取映象,若本地已經存在該映象,則不用到網上去拉取
  2. 建立新的容器
  3. 分配union檔案系統並且掛著一個可讀寫的層,任何修改容器的操作都會被記錄在這個讀寫層上,你可以儲存這些修改成新的映象,也可以選擇不儲存,那麼下次執行改映象的時候所有修改操作都會被消除
  4. 分配網路\橋接介面,建立一個允許容器與本地主機通訊的網路介面
  5. 設定ip地址,從池中尋找一個可用的ip地址附加到容器上,換句話說,localhost並不能訪問到容器
  6. 執行你指定的程式
  7. 捕獲並且提供應用輸出,包括輸入、輸出、報錯資訊

相關文章