在開始談docker容器以前,先須要清楚什麼是虛擬化,什麼是容器docker
若是要⽤簡單的語句來闡述虛擬化技術的話,那麼能夠這麼解釋: 虛擬化技術是⼀種將計算機物理資源進⾏抽象、轉換爲虛擬的計算機資源提供給程序使⽤的技術。 這⾥所指的計算機資源,就包括了 CPU 提供的運算控制資源,硬盤提供的數據存儲資源,⽹卡提供的⽹絡傳輸資源等。 編程
計算機發展早期,各種計算機平臺,計算資源所提供的接口都不同,調用十分混亂,沒有像今天同樣有相對統一的標準。因爲爲兼容不一樣的平臺寫各類各樣的兼容代碼,因而虛擬技術運應而生。虛擬化技術經過自己適配不一樣平臺的硬件,抽象成統一的接口,從而實現程序的跨平臺。安全
在虛擬化技術發展的過程當中,人們又發現了虛擬化技術的另一個用途:資源管理。 由於虛擬化技術原本就是對計算機物理資源的抽象轉換成虛擬的計算機資源,這樣就很容易在這裏對計算機資源進行修改,好比能夠告訴程序這臺計算機只有4G內存,而不管計算機是有16G仍是32G,程序都會按照虛擬機告訴它的4G內存來進行使用。 經過虛擬化技術管理計算機資源的方式,不當能讓咱們對計算機資源的控制更加靈活,並且還能極大的提交計算機資源的使用率。 看到這可能會有些迷惑,虛擬化技術自己就要耗費部分的計算機資源,怎麼還能產生1+1>2的效果? 其實這裏指的是計算機的使用率,而非計算機的佔用率,這二者看似很相近,其實並不是一個概念。虛擬化技術可以提升計算機資源的使用率,是指利用虛擬化技術,將本來程序使用不到的資源分配給其餘程序使用,從而提高計算機資源的總體利用率。 例如,這⾥咱們有⼀臺運⾏ Nginx 的機器,因爲 Nginx 運⾏對系統資源的消耗並不⾼,這就讓系統⼏乎 95% 以上的資源處於閒置狀態。這時候咱們經過虛擬化技術,把其餘的⼀些程序放到這臺機器上來 運⾏,它們就可以充分利⽤閒置的資源。這帶來的好處就是咱們不須要再爲這些程序單獨部署機器,從⽽節約很多的成本。 服務器
所謂硬件虛擬化,指的是物理硬件本⾝就提供虛擬化的⽀持。舉個例⼦來講,某個平臺的 CPU,可以將另外⼀個平臺的指令集轉換爲⾃⾝的指令集執⾏,並給程序徹底運⾏在那個平臺上的感受。又或者 說,CPU 可以⾃⾝模擬裂變,讓程序或者操做系統認爲存在多個 CPU,進⽽可以同時運⾏多個程序或者操做系統。這些都是硬件虛擬化的體現。 ⽽軟件虛擬化則指的是經過軟件的⽅式來實現虛擬化中關鍵的指令轉換部分。依然⽤ CPU 的例⼦來講話,在軟件虛擬化實現中,經過⼀層夾雜在應⽤程序和硬件平臺上的虛擬化實現軟件來進⾏指令的轉換。也就是說,雖然應⽤程序向操做系統或者物理硬件發出的指令不是當前硬件平臺所⽀持的指令,這個實現虛擬化的軟件也會將之轉換爲當前硬件平臺所能識別的架構
在實際場景中,虛擬化還能進⾏更加細化的分類,例如:運維
虛擬機 ( Virtual Machine )。所謂虛擬機,一般來講就是經過⼀個虛擬機監視器 ( Virtual Machine Monitor ) 的設施來隔離操做系統與硬件或者應⽤程序與操做系統,以此達到虛擬化的⽬的。這個夾在其中的虛擬機監視器,經常被稱爲 Hypervisor。 分佈式
容器技術是⼀種全新意義上的虛擬化技術,按分類或者實現⽅式來講,其應該屬於操做系統虛擬化的範疇,也就是在由操做系統提供虛擬化的⽀持。 所謂容器技術,指的是操做系統⾃⾝⽀持⼀些接⼜,可以讓應⽤程序間能夠互不⼲擾的獨⽴運⾏,而且可以對其在運⾏中所使⽤的資源進⾏⼲預。 因爲應⽤程序的運⾏被隔離在了⼀個獨⽴的運⾏環境之中,這個獨⽴的運⾏環境就好似⼀個容器,包裹住了應⽤程序,這就是容器技術名字的由來。 虛擬機VS容器 模塊化
Docker是由 dotCloud 在2013年開源的一個由Go實現的容器引擎。微服務
利⽤它的全⾯性和易⽤性帶來的提高咱們的⼯做效率,能夠將開發人員或者運維人員從重複且容易出錯的服務搭建中解放出來,特別是在微服務的浪潮下,項目多模塊化和服務化,一個完整的項目由不少小服務組成,這對於搭建來講也是一個不小的挑戰。 docker技術實現 Docker 的實現,主要歸結於三⼤技術:命名空間 ( Namespaces ) 、控制組 ( Control Groups ) 和聯合⽂件系統 ( Union File System ) 。 性能
命名空間是 Linux 核⼼在 2.4 版本後逐漸引⼊的⼀項⽤於運⾏隔離的模塊。Linux 內核的命名空間,就是可以將計算機資源進⾏切割劃分,造成各⾃獨⽴的空間。 就實現⽽⾔,Linux Namespaces 能夠分爲不少具體的⼦系統,如 User Namespace、Net Namespace、PID Namespace、Mount Namespace 等等。 這⾥咱們以進程爲例,經過 PID Namespace,咱們能夠造就⼀個獨⽴的進程運⾏空間,在其中進程的編號又會從 1 開始。在這個空間中運⾏的進程,徹底感知不到外界系統中的其餘進程或是其餘進程命名空間中運⾏的進程。
資源控制組 ( 常縮寫爲 CGroups ) 是 Linux 內核在 2.6 版本後逐漸引⼊的⼀項對計算機資源控制的模塊。 顧名思義,資源控制組的做⽤就是控制計算機資源的。與隔離進程、⽹絡、⽂件系統等虛擬資源爲⽬的 Namespace 不一樣,CGroups 主要作的是硬件資源的隔離。 以前咱們提到了,虛擬化除了製造出虛擬的環境隔離同⼀物理平臺運⾏的不一樣程序以外,另⼀⼤做⽤就是控制硬件資源的分配,CGroups 的使⽤正是爲了這樣的⽬的。 須要再強調⼀次的是,CGroups 除了資源的隔離,還有資源分配這個關鍵性的做⽤。經過 CGroups,咱們能夠指定任意⼀個隔離環境對任意資源的佔⽤值或佔⽤率,這對於不少分佈式使⽤場景來講是⾮ 常有⽤的功能。
聯合⽂件系統 ( Union File System ) 是⼀種可以同時掛載不一樣實際⽂件或⽂件夾到同⼀⽬錄,造成⼀種聯合⽂件結構的⽂件系統。聯合⽂件系統本⾝與虛擬化並⽆太⼤的關係,但 Docker 卻創新的將其引⼊ 到容器實現中,⽤它解決虛擬環境對⽂件系統佔⽤過量,實現虛擬環境快速啓停等問題。 在 Docker 中,提供了⼀種對 UnionFS 的改進實現,也就是 AUFS ( Advanced Union File System )。
屬性 | Docker | 虛擬機 |
---|---|---|
啓動速度 | 秒級 | 分鐘級 |
硬盤使⽤ | MB 級 | GB 級 |
性能 | 接近原⽣ | 較低 |
普通機器⽀撐量 | 數百個 | ⼏個 |
從理論上咱們已經知道 Docker 可以爲咱們的⼯做帶來巨⼤的便利,那麼將其放於實踐中,咱們應該如何正確的使⽤它呢?這⾥我摘錄整理了⼀段來⾃ Docker 官⽅⽂檔的指導意見,但願可以對⼤家的實 踐提供參考。
使⽤ Docker 後,開發者可以在本地容器中獲得⼀套標準的應⽤或服務的運⾏環境,由此能夠簡化開發的⽣命週期 ( 減小在不一樣環境間進⾏適配、調整所形成的額外消耗 )。對於整個應⽤迭代來講,加⼊ Docker 的⼯做流程將更加適合持續集成 ( Continuous Integration ) 和持續交付 ( Continuous Delivery )。 舉個具體的例⼦: 開發者可以使⽤ Docker 在本地編寫代碼並經過容器與其餘同事共享他們的⼯做。 他們可以使⽤ Docker 將編寫好的程序推送⾄測試環境進⾏⾃動化測試或是⼈⼯測試。 當出現 Bugs 時,開發者能夠在開發環境中修復它們,並很快的從新部署到測試環境中。 在測試完成後,部署裝有應⽤程序的鏡像就能完成⽣產環境的發佈。
基於容器技術的 Docker 擁有很⾼的跨平臺性,Docker 的容器可以很輕鬆的運⾏在開發者本地的電腦,數據中⼼的物理機或虛擬機,雲服務商提供的雲服務器,甚⾄是混合環境中。 同時,Docker 的輕量性和⾼可移植性可以很好的幫助咱們完成應⽤的動態伸縮,咱們能夠經過⼀些⼿段近實時的對基於 Docker 運⾏的應⽤進⾏彈性伸縮,這可以⼤幅提⾼應⽤的健壯性。
Docker 的⾼效和輕量等特徵,爲替代基於 Hypervisor 的虛擬機提供了⼀個經濟、⾼效、可⾏的⽅案。在 Docker 下,你能節約出更多的資源投⼊到業務中去,讓應⽤程序產⽣更⾼的效益。同時,如此低的 資源消耗也說明了 Docker ⾮常適合在⾼密度的中⼩型部署場景中使⽤。
在 Docker 體系⾥,有四個對象 ( Object ) 是咱們不得不進⾏介紹的,由於⼏乎全部 Docker 以及周邊⽣態的功能,都是圍繞着它們所展開的。它們分別是:鏡像 ( Image )、容器 ( Container )、⽹絡 ( Network )、數據卷 ( Volume )。
鏡像,能夠理解爲⼀個只讀的⽂件包,其中包含了虛擬環境運⾏最原始⽂件系統的 內容。 固然,Docker 的鏡像與虛擬機中的鏡像仍是有⼀定區別的。⾸先,以前咱們談到了 Docker 中的⼀個創新是利⽤了 AUFS 做爲底層⽂件系統實現,經過這種⽅式,Docker 實現了⼀種增量式的鏡像結構。
容器 ( Container ) 就更好理解了,在容器技術中,容器就是⽤來隔離虛擬環境的基礎設施,⽽在 Docker ⾥,它也被引伸爲隔離出來的虛擬環境。 若是把鏡像理解爲編程中的類,那麼容器就能夠理解爲類的實例。鏡像內存放的是不可變化的東西,當以它們爲基礎的容器啓動後,容器內也就成爲了⼀個「活」的空間。 ⽤更官⽅的定義,Docker 的容器應該有三項內容組成:
在 Docker 中,實現了強⼤的⽹絡功能,咱們不但可以⼗分輕鬆的對每一個容器的⽹絡進⾏配置,還能在容器間建⽴虛擬⽹絡,將數個容器包裹其中,同時與其餘⽹絡環境隔離。
除了⽹絡以外,⽂件也是重要的進⾏數據交互的資源。在以往的虛擬機中,咱們一般直接採⽤虛擬機的⽂件系統做爲應⽤數據等⽂件的存儲位置。然⽽這種⽅式其實並⾮徹底安全的,當虛擬機或者容器 出現問題致使⽂件系統⽆法使⽤時,雖然咱們能夠很快的經過鏡像重置⽂件系統使得應⽤快速恢復運⾏,可是以前存放的數據也就消失了。 爲了保證數據的獨⽴性,咱們一般會單獨掛載⼀個⽂件系統來存放數據。這種操做在虛擬機中是繁瑣的,由於咱們不但要搞定掛載在不一樣宿主機中實現的⽅法,還要考慮掛載⽂件系統兼容性,虛擬操做 系統配置等問題。值得慶幸的是,這些在 Docker ⾥都已經爲咱們輕鬆的實現了,咱們只須要簡單的⼀兩個命令或參數,就能完成⽂件系統⽬錄的掛載。 可以這麼簡單的實現掛載,主要仍是得益於 Docker 底層的 Union File System 技術。在 UnionFS 的加持下,除了可以從宿主操做系統中掛載⽬錄外,還可以建⽴獨⽴的⽬錄持久存放數據,或者在容器間共 享。 在 Docker 中,經過這⼏種⽅式進⾏數據共享或持久化的⽂件或⽬錄,咱們都稱爲數據卷 ( Volume )。
時⾄今⽇,Docker ⽣態已經遠⽐它誕⽣之初要龐⼤許多,雖然咱們仍然習慣使⽤ Docker 這個名字去指代實現容器技術⽀持的軟件,但顯然更加容易與其餘的概念產⽣混淆。這⾥咱們頗有必要對這個 Docker 中最核⼼的軟件進⾏介紹,不只由於它在 Docker ⽣態中扮演着中⼼的地位,也由於它是咱們在開發中實實在在接觸最多的東西。 ⽬前這款實現容器化的⼯具是由 Docker 官⽅進⾏維護的,Docker 官⽅將其命名爲 Docker Engine,同時定義其爲⼯業級的容器引擎 ( Industry-standard Container Engine )。在 Docker Engine 中,實現了 Docker 技術中最核⼼的部分,也就是容器引擎這⼀部分。
雖然咱們說 Docker Engine 是⼀款軟件,但實實在在去深究的話,它其實算是由多個獨⽴軟件所組成的軟件包。在這些程序中,最核⼼的就是 docker daemon 和 docker CLI 這倆了。 全部咱們一般認爲的 Docker 所能提供的容器管理、應⽤編排、鏡像分發等功能,都集中在了 docker daemon 中,⽽咱們以前所提到的鏡像模塊、容器模塊、數據卷模塊和⽹絡模塊也都實如今其中。在操 做系統⾥,docker daemon 一般以服務的形式運⾏以便靜默的提供這些功能,因此咱們也一般稱之爲 Docker 服務。