簡單的列一下目前這個階段我們很容易發現的幾點:
docker image的體積非常的小,注意看下之前我們用到的幾個image的size,一個完整功能的ubuntu才100多mb。docker image如此小的體積,讓我們可以友善的在網絡上傳輸和分享,對于公司來說就提供了對大量image的管理和分發的可能。
docker的系統啟動的耗時為0。昨天如果自己也嘗試啟動hello-world的同學可能會知道,<code>docker run hello-world</code>的指令是瞬間完成的,你并沒有感覺到加載image,啟動系統的耗時,指令完成就直接輸出了結果。程式執行完後container也跟着關閉,也并沒有儲存鏡像的時間,但下次再運作還是會保留你處理過的狀态。
docker系統占用資源極少,我們知道如果我們開啟了一個vm的系統,不論是linux的或者windows,就算什麼都不運作都會占用一部分記憶體,但是docker container啟動後如果不運作程式,你是看不到系統資源被占用的。
這些特點是不是完全和vm不同呢?并且有了這些特點,是不是很多之前沒有的應用場景就會産生?比如我們可以把一個項目build成一個image,然後友善分發出去,别人拿到後也不用關心你的項目需要什麼環境或者依賴,隻要docker run一下就能運作。。而且速度很快,甚至在一台開發機都可以管理成百上千的container,沒有業務處理的時候也不會占用你的系統資源。。。

到這裡可能你已經感受到docker的一些厲害之處了吧。。。那麼是不是也很好奇docker到底是怎麼做到的?那麼我們繼續往下。
我們先思考一下,一台伺服器給我們開發的項目到底提供了哪些能力讓他運作起來呢?cpu、記憶體、硬碟、網絡、作業系統、工具軟體還有項目的運作環境(jre等)。當具備了這些能力的機器,我們會說這台機器給項目提供了可以運作的環境。
我們知道vm技術可以将一台實體機器部署為多台虛拟機器,解決了很多物力資源的浪費以及友善的管理能力。那麼vm是怎麼做到的呢?關鍵詞:hypervisor,vm在實體機器的作業系統上建立了一個中間軟體層hypervisor,hypervisor利用實體機器的資源,虛拟出多個新虛拟的硬體環境,這些硬體環境可以共享主控端的資源。這些新的虛拟的硬體環境,安裝作業系統和相應的軟體後便形成了一台台的虛拟機器。
那麼docker有什麼不同呢?docker很聰明的利用linux的一些技術走了一條捷徑:docker選擇了和虛拟化完全不同的思路,并不去虛拟化任何硬體,而是對硬體資源在不同的docker container之間做了 “隔離” 。隔離使每個docker container之間擁有了不同的環境(硬碟空間、網絡、系統的工具包),并且又可以共享需要的硬體資源(cpu、記憶體、系統核心),達到了和虛拟機能提供的同樣的功能。
aufs(chroot) – 用來建立不同的作業系統和隔離運作時的硬碟空間
namespace – 用來隔離container的執行空間
cgroup – 配置設定不同的硬體資源
selinux – 用來保護linux的網絡安全
netlink – 用來讓不同的container之間的程序保持通信
netfilter – 建立container埠為基礎的網路防火牆封包過濾
apparmor – 保護container的網路及執行安全
linux bridge – 讓不同container或不同主機上的container能溝通
。。。
這裡面的每一項技術當然都值得我們去了解,這裡我隻拿其中最具代表性的aufs來展開一下,讓大家了解一下docker隔離的思路。 (除了aufs的技術請大家自己研究吧,後面我也會整理一些資源發出來)
aufs -> another union file system,aufs的技術可以讓多個檔案目錄union成一個新的目錄,并且可以對這個新的目錄進行讀寫操作。
那這有什麼用呢?如果你有一張隻讀的cd資料盤,但是你卻想編輯裡面的内容,你通常的做法是不是把内容拷貝到本地硬碟,然後再編輯。但如果你可以利用aufs技術,你就可以将硬碟中的一個空目錄和你的cd資料盤進行union形成一個新的目錄,接着你對這個目錄讀取,會得到的cd盤内的資料,當你對這個目錄的内容進行編輯,編輯的内容aufs會自動講修改内容儲存在你union的那個空目錄内,當你再次讀區的時候,aufs也會将你硬碟中記錄的改動内容優先于cd資料盤中的内容讀取出來,這樣對你來說這就完全是一個可編輯的目錄内容了。
aufs雖然看起來思路很簡單,但是docker卻利用這個技術做出了大文章。我們可以想象一下docker的image,其實也就是一個事先制作好的隻讀的檔案目錄,當我們要使用這個系統功能的時候,docker為我們開辟了一個新的檔案夾和這個image做了union,提供給docker container做為系統運作的存儲,這個image裡面已經包含了系統程式、工具軟體、以及程式,當系統啟動後産生的運作時檔案(如logs、臨時目錄等)或新安裝的軟體都在這個新的檔案夾内。這樣我們在啟動一個container的時候,其實并沒有加載鏡像的過程,也不會像vm一樣需要安裝一個系統這麼負責,隻是做了一次unoin,一切就和安裝過系統的虛拟機同樣使用了。另外docker還提供了一個<code>docker commit</code>指令,這個指令可以随時将你現在的運作中的cantainer建構成一個新的image。
檢視目前的container清單
指令:<code>docker ps -a</code>
通過一個ubuntu的container生成一個新的image,這個image内包含了在這次container中的改動
指令:<code>docker commit container-id</code>
檢視現在是不是有了一個新的container了
指令:<code>docker images</code>
看到這裡是不是大緻的了解了docker container和docker images之間的聯系了。
dcoker通過很多的所謂 隔離 的方式,讓多個docker container之間共享了同一台機器上的資源,但又是互相隔離的(比如container1 和 container2 用的是完全不同的硬碟空間、網絡位址等),這樣就讓docker container成為了我們項目理想的開發、測試、釋出的環境。非常的輕量,簡單,易于分發和管理。這也就是docker的目标:build, ship and run any app, anywhere!
下面我會簡單的再分享一下現在docker的實際使用場景,和mircoservice 的概念。。。讓大家了解docker對于現有技術和模式的影響~