看完這個,你就知道Docker是什麼了

在開始談docker容器以前,先須要清楚什麼是虛擬化,什麼是容器docker

虛擬化

若是要⽤簡單的語句來闡述虛擬化技術的話,那麼能夠這麼解釋: 虛擬化技術是⼀種將計算機物理資源進⾏抽象、轉換爲虛擬的計算機資源提供給程序使⽤的技術。 這⾥所指的計算機資源,就包括了 CPU 提供的運算控制資源,硬盤提供的數據存儲資源,⽹卡提供的⽹絡傳輸資源等。 編程

在這裏插入圖片描述

爲跨平臺而生

計算機發展早期,各種計算機平臺,計算資源所提供的接口都不同,調用十分混亂,沒有像今天同樣有相對統一的標準。因爲爲兼容不一樣的平臺寫各類各樣的兼容代碼,因而虛擬技術運應而生。虛擬化技術經過自己適配不一樣平臺的硬件,抽象成統一的接口,從而實現程序的跨平臺。安全

將虛擬化技術用於資源管理

在虛擬化技術發展的過程當中,人們又發現了虛擬化技術的另一個用途:資源管理。 由於虛擬化技術原本就是對計算機物理資源的抽象轉換成虛擬的計算機資源,這樣就很容易在這裏對計算機資源進行修改,好比能夠告訴程序這臺計算機只有4G內存,而不管計算機是有16G仍是32G,程序都會按照虛擬機告訴它的4G內存來進行使用。 經過虛擬化技術管理計算機資源的方式,不當能讓咱們對計算機資源的控制更加靈活,並且還能極大的提交計算機資源的使用率。 看到這可能會有些迷惑,虛擬化技術自己就要耗費部分的計算機資源,怎麼還能產生1+1>2的效果? 其實這裏指的是計算機的使用率,而非計算機的佔用率,這二者看似很相近,其實並不是一個概念。虛擬化技術可以提升計算機資源的使用率,是指利用虛擬化技術,將本來程序使用不到的資源分配給其餘程序使用,從而提高計算機資源的總體利用率。 例如,這⾥咱們有⼀臺運⾏ Nginx 的機器,因爲 Nginx 運⾏對系統資源的消耗並不⾼,這就讓系統⼏乎 95% 以上的資源處於閒置狀態。這時候咱們經過虛擬化技術,把其餘的⼀些程序放到這臺機器上來 運⾏,它們就可以充分利⽤閒置的資源。這帶來的好處就是咱們不須要再爲這些程序單獨部署機器,從⽽節約很多的成本。 服務器

在這裏插入圖片描述
部分讀者讀到這⾥就會產⽣疑惑了,我本⾝就能夠在操做系統⾥安裝這些程序而且同時運⾏,爲何還要把它們分別裝到不一樣的虛擬環境中去呢? 其實道理很簡單,雖然咱們可以在操做系統⾥同時運⾏多個程序,但前提得是這些程序本⾝不存在衝突。這⾥的衝突體如今不少的⽅⾯,例如不一樣的程序同時使⽤了同⼀個端⼜;不一樣程序依賴於同⼀個 ⼯具庫的不一樣版本;程序本⾝限制了同時開啓的進程數等。虛擬化技術經過資源隔離的⽅式,⽆形地也能夠把這些程序隔離在不一樣的虛擬環境中,既然虛擬環境不一樣,⾃然運⾏在不一樣環境中的程序就不 會互相⼲擾或爭搶資源了。

虛擬化的分類
  • 硬件虛擬化
  • 軟件虛擬化

所謂硬件虛擬化,指的是物理硬件本⾝就提供虛擬化的⽀持。舉個例⼦來講,某個平臺的 CPU,可以將另外⼀個平臺的指令集轉換爲⾃⾝的指令集執⾏,並給程序徹底運⾏在那個平臺上的感受。又或者 說,CPU 可以⾃⾝模擬裂變,讓程序或者操做系統認爲存在多個 CPU,進⽽可以同時運⾏多個程序或者操做系統。這些都是硬件虛擬化的體現。 ⽽軟件虛擬化則指的是經過軟件的⽅式來實現虛擬化中關鍵的指令轉換部分。依然⽤ CPU 的例⼦來講話,在軟件虛擬化實現中,經過⼀層夾雜在應⽤程序和硬件平臺上的虛擬化實現軟件來進⾏指令的轉換。也就是說,雖然應⽤程序向操做系統或者物理硬件發出的指令不是當前硬件平臺所⽀持的指令,這個實現虛擬化的軟件也會將之轉換爲當前硬件平臺所能識別的架構

在實際場景中,虛擬化還能進⾏更加細化的分類,例如:運維

  • 平臺虛擬化:在操做系統和硬件平臺間搭建虛擬化設施,使得整個操做系統都運⾏在虛擬後的環境中。
  • 應⽤程序虛擬化:在操做系統和應⽤程序間實現虛擬化,只讓應⽤程序運⾏在虛擬化環境中。
  • 內存虛擬化:將不相鄰的內存區,甚⾄硬盤空間虛擬成統⼀連續的內存地址,即咱們常說的虛擬內存。
  • 桌⾯虛擬化:讓本地桌⾯程序利⽤遠程計算機資源運⾏,達到控制遠程計算機的⽬的。

虛擬機

虛擬機 ( Virtual Machine )。所謂虛擬機,一般來講就是經過⼀個虛擬機監視器 ( Virtual Machine Monitor ) 的設施來隔離操做系統與硬件或者應⽤程序與操做系統,以此達到虛擬化的⽬的。這個夾在其中的虛擬機監視器,經常被稱爲 Hypervisor。 分佈式

在這裏插入圖片描述
從咱們習慣⽤來搭建虛擬操做系統環境的 VMware Workstation、Xen 等軟件,到 Java 虛擬機 JVM,PHP 虛擬 機 HHVM 等等,都充活躍在咱們程序開發到程序運⾏的過程當中。 這個時候可能聰明的大家會發現,發現原來 JVM、HHVM 等特定語⾔運⾏環境中的核⼼部分,也是虛擬化的⼀種實實在在的實現。沒錯,只要⼤家仔細分析和思考⼀下就會發現,它們正是基於虛擬化的思想來實現的。它們經過隔離程序和操做系統,將程序的指令轉換爲當前所在操做系統平臺所能執⾏的指令,達到了不⽤對程序進⾏任何修改便可執⾏的⽬的。也正是這個緣由,這些語⾔的程序都具備⾮常強的跨平臺性。 雖然虛擬機技術得益於 Hypervisor 的加持,使得應⽤程序或者操做系統能夠在⽆任何修改的狀況下運⾏在另⼀平臺上,但⼤家很容易發現,其有⼀個致命的缺陷,就是全部的指令都必須通過虛擬機監視器的處理。這也就意味着,虛擬機的性能是低下的,例如運⾏在 ZendVM 或者 HHVM 中的 PHP 程序,全部代碼雖然編譯成了 Opcode 碼,但其依然是經過虛擬機才最終轉換爲機器所能識別的機器碼去執⾏。 這種效率的低下有時候是⽆法容忍的,爲了解決這個問題,真實的虛擬機程序經常不徹底遵循 Hypervisor 的設計結構,⽽是引⼊⼀些其餘技術來解決效率問題。 例如,在 VMware Workstation、Xen 中咱們可以看到硬件輔助虛擬化的使⽤,經過讓指令直達⽀持虛擬化的硬件,以此避開了效率低下的 Hypervisor。⽽如 JRE、HPHP 中,除了基於 Hypervisor 實現的解 釋執⾏機制外,還有即時編譯 ( Just In Time ) 運⾏機制,讓程序代碼在運⾏前編譯成符合當前硬件平臺的機器碼。

容器技術

容器技術是⼀種全新意義上的虛擬化技術,按分類或者實現⽅式來講,其應該屬於操做系統虛擬化的範疇,也就是在由操做系統提供虛擬化的⽀持。 所謂容器技術,指的是操做系統⾃⾝⽀持⼀些接⼜,可以讓應⽤程序間能夠互不⼲擾的獨⽴運⾏,而且可以對其在運⾏中所使⽤的資源進⾏⼲預。 因爲應⽤程序的運⾏被隔離在了⼀個獨⽴的運⾏環境之中,這個獨⽴的運⾏環境就好似⼀個容器,包裹住了應⽤程序,這就是容器技術名字的由來。 虛擬機VS容器 模塊化

在這裏插入圖片描述
因爲沒有了虛擬操做系統和虛擬機監視器這兩個層次,從而省略了指令轉換這一操做,⼤幅減小了應⽤程序運⾏帶來的額外消耗。 更準確的來講,全部在容器中的應⽤程序其實徹底運⾏在了宿主操做系統中,與其餘真實運⾏在其中的應⽤程序在指令運⾏層⾯是徹底沒有任何區別的。

什麼是Docker

Docker是由 dotCloud 在2013年開源的一個由Go實現的容器引擎。微服務

Docker帶來什麼

利⽤它的全⾯性和易⽤性帶來的提高咱們的⼯做效率,能夠將開發人員或者運維人員從重複且容易出錯的服務搭建中解放出來,特別是在微服務的浪潮下,項目多模塊化和服務化,一個完整的項目由不少小服務組成,這對於搭建來講也是一個不小的挑戰。 docker技術實現 Docker 的實現,主要歸結於三⼤技術:命名空間 ( Namespaces ) 、控制組 ( Control Groups ) 和聯合⽂件系統 ( Union File System ) 。 性能

在這裏插入圖片描述

Namespace

命名空間是 Linux 核⼼在 2.4 版本後逐漸引⼊的⼀項⽤於運⾏隔離的模塊。Linux 內核的命名空間,就是可以將計算機資源進⾏切割劃分,造成各⾃獨⽴的空間。 就實現⽽⾔,Linux Namespaces 能夠分爲不少具體的⼦系統,如 User Namespace、Net Namespace、PID Namespace、Mount Namespace 等等。 這⾥咱們以進程爲例,經過 PID Namespace,咱們能夠造就⼀個獨⽴的進程運⾏空間,在其中進程的編號又會從 1 開始。在這個空間中運⾏的進程,徹底感知不到外界系統中的其餘進程或是其餘進程命名空間中運⾏的進程。

在這裏插入圖片描述
利⽤ PID Namespace,Docker 就實現了容器中隔離程序運⾏中進程隔離這⼀⽬標。

Control Groups

資源控制組 ( 常縮寫爲 CGroups ) 是 Linux 內核在 2.6 版本後逐漸引⼊的⼀項對計算機資源控制的模塊。 顧名思義,資源控制組的做⽤就是控制計算機資源的。與隔離進程、⽹絡、⽂件系統等虛擬資源爲⽬的 Namespace 不一樣,CGroups 主要作的是硬件資源的隔離。 以前咱們提到了,虛擬化除了製造出虛擬的環境隔離同⼀物理平臺運⾏的不一樣程序以外,另⼀⼤做⽤就是控制硬件資源的分配,CGroups 的使⽤正是爲了這樣的⽬的。 須要再強調⼀次的是,CGroups 除了資源的隔離,還有資源分配這個關鍵性的做⽤。經過 CGroups,咱們能夠指定任意⼀個隔離環境對任意資源的佔⽤值或佔⽤率,這對於不少分佈式使⽤場景來講是⾮ 常有⽤的功能。

Union File System

聯合⽂件系統 ( Union File System ) 是⼀種可以同時掛載不一樣實際⽂件或⽂件夾到同⼀⽬錄,造成⼀種聯合⽂件結構的⽂件系統。聯合⽂件系統本⾝與虛擬化並⽆太⼤的關係,但 Docker 卻創新的將其引⼊ 到容器實現中,⽤它解決虛擬環境對⽂件系統佔⽤過量,實現虛擬環境快速啓停等問題。 在 Docker 中,提供了⼀種對 UnionFS 的改進實現,也就是 AUFS ( Advanced Union File System )。

AUFS
AUFS 將⽂件的更新掛載到⽼的⽂件之上,⽽不去修改那些不更新的內容,這就意味着即便虛擬的⽂件系統被反覆修改,也能保證對真實⽂件系統的空間佔⽤保持⼀個較低⽔平。 也許這個表述還不夠形象,那麼咱們來⽤ Git 進⾏⽐較,會讓⼤家會更容易理解。⼤家知道,咱們在 Git 中每進⾏⼀次提交,Git 並非將咱們全部的內容打包成⼀個版本,⽽只是將修改的部分進⾏記 錄,這樣即便咱們提交不少次後,代碼庫的空間佔⽤也不會倍數增長。 一樣的,經過 AUFS,Docker ⼤幅減小了虛擬⽂件系統對物理存儲空間的佔⽤。由此,Docker 也開創出了虛擬化領域不少新的輕量級解決⽅案,這在以後的⼩節⾥咱們會提到。 Docker 的理念 在對 Docker 及其背後的⼀些技術有了⼀個初步瞭解以後,咱們還要着重說⼀下 Docker 本⾝的⼀些設計理念。若是說熟悉 Docker 背後的技術可以更好的幫助你正確使⽤ Docker,那麼理解 Docker 的理念 將更好的指導你如何搭配 Docker 容器間的關係。 讓咱們先來從⼀張 Docker 官⽅提供的架構圖來看看 Docker 對容器結構的設計。
在這裏插入圖片描述
與其餘虛擬化實現甚⾄其餘容器引擎不一樣的是,Docker 推崇⼀種輕量級容器的結構,即⼀個應⽤⼀個容器。 舉個具體的例⼦,在常見的虛擬機實現中,咱們要搭建⼀套 LAMP 結構的服務,咱們一般會建⽴⼀個虛擬機,在虛擬機中安裝上 Linux 系統,以後分別安裝 Apache、MySQL 和 PHP。⽽在 Docker ⾥,最佳的實踐是分別基於 Apache、MySQL 和 PHP 的鏡像建⽴三個容器,分別運⾏ Apache、MySQL 和 PHP ,⽽它們所在的虛擬操做系統也直接共享於宿主機的操做系統。 若是咱們將 Docker 的輕量級容器實現和虛擬機的⼀些參數進⾏對⽐,更容易獲得結果。

屬性 Docker 虛擬機
啓動速度 秒級 分鐘級
硬盤使⽤ MB 級 GB 級
性能 接近原⽣ 較低
普通機器⽀撐量 數百個 ⼏個
Docker 能作什麼

從理論上咱們已經知道 Docker 可以爲咱們的⼯做帶來巨⼤的便利,那麼將其放於實踐中,咱們應該如何正確的使⽤它呢?這⾥我摘錄整理了⼀段來⾃ Docker 官⽅⽂檔的指導意見,但願可以對⼤家的實 踐提供參考。

更快、更⼀致的交付你的應⽤程序

使⽤ Docker 後,開發者可以在本地容器中獲得⼀套標準的應⽤或服務的運⾏環境,由此能夠簡化開發的⽣命週期 ( 減小在不一樣環境間進⾏適配、調整所形成的額外消耗 )。對於整個應⽤迭代來講,加⼊ Docker 的⼯做流程將更加適合持續集成 ( Continuous Integration ) 和持續交付 ( Continuous Delivery )。 舉個具體的例⼦: 開發者可以使⽤ Docker 在本地編寫代碼並經過容器與其餘同事共享他們的⼯做。 他們可以使⽤ Docker 將編寫好的程序推送⾄測試環境進⾏⾃動化測試或是⼈⼯測試。 當出現 Bugs 時,開發者能夠在開發環境中修復它們,並很快的從新部署到測試環境中。 在測試完成後,部署裝有應⽤程序的鏡像就能完成⽣產環境的發佈。

跨平臺部署和動態伸縮

基於容器技術的 Docker 擁有很⾼的跨平臺性,Docker 的容器可以很輕鬆的運⾏在開發者本地的電腦,數據中⼼的物理機或虛擬機,雲服務商提供的雲服務器,甚⾄是混合環境中。 同時,Docker 的輕量性和⾼可移植性可以很好的幫助咱們完成應⽤的動態伸縮,咱們能夠經過⼀些⼿段近實時的對基於 Docker 運⾏的應⽤進⾏彈性伸縮,這可以⼤幅提⾼應⽤的健壯性。

讓一樣的硬件提供更多的產出能⼒

Docker 的⾼效和輕量等特徵,爲替代基於 Hypervisor 的虛擬機提供了⼀個經濟、⾼效、可⾏的⽅案。在 Docker 下,你能節約出更多的資源投⼊到業務中去,讓應⽤程序產⽣更⾼的效益。同時,如此低的 資源消耗也說明了 Docker ⾮常適合在⾼密度的中⼩型部署場景中使⽤。

Docker核心組成

在 Docker 體系⾥,有四個對象 ( Object ) 是咱們不得不進⾏介紹的,由於⼏乎全部 Docker 以及周邊⽣態的功能,都是圍繞着它們所展開的。它們分別是:鏡像 ( Image )、容器 ( Container )、⽹絡 ( Network )、數據卷 ( Volume )。

鏡像

鏡像,能夠理解爲⼀個只讀的⽂件包,其中包含了虛擬環境運⾏最原始⽂件系統的 內容。 固然,Docker 的鏡像與虛擬機中的鏡像仍是有⼀定區別的。⾸先,以前咱們談到了 Docker 中的⼀個創新是利⽤了 AUFS 做爲底層⽂件系統實現,經過這種⽅式,Docker 實現了⼀種增量式的鏡像結構。

在這裏插入圖片描述
每次對鏡像內容的修改,Docker 都會將這些修改鑄形成⼀個鏡像層,⽽⼀個鏡像其實就是由其下層全部的鏡像層所組成的。固然,每⼀個鏡像層單獨拿出來,與它之下的鏡像層均可以組成⼀個鏡像。 另外,因爲這種結構,Docker 的鏡像實質上是⽆法被修改的,由於全部對鏡像的修改只會產⽣新的鏡像,⽽不是更新原有的鏡像。

容器

容器 ( Container ) 就更好理解了,在容器技術中,容器就是⽤來隔離虛擬環境的基礎設施,⽽在 Docker ⾥,它也被引伸爲隔離出來的虛擬環境。 若是把鏡像理解爲編程中的類,那麼容器就能夠理解爲類的實例。鏡像內存放的是不可變化的東西,當以它們爲基礎的容器啓動後,容器內也就成爲了⼀個「活」的空間。 ⽤更官⽅的定義,Docker 的容器應該有三項內容組成:

  • ⼀個 Docker 鏡像
  • ⼀個程序運⾏環境
  • ⼀個指令集合
⽹絡

在 Docker 中,實現了強⼤的⽹絡功能,咱們不但可以⼗分輕鬆的對每一個容器的⽹絡進⾏配置,還能在容器間建⽴虛擬⽹絡,將數個容器包裹其中,同時與其餘⽹絡環境隔離。

在這裏插入圖片描述
另外,利⽤⼀些技術,Docker 可以在容器中營造獨⽴的域名解析環境,這使得咱們能夠在不修改代碼和配置的前提下直接遷移容器,Docker 會爲咱們完成新環境的⽹絡適配。對於這個功能,咱們甚⾄能 夠在不一樣的物理服務器間實現,讓處在兩臺物理機上的兩個 Docker 所提供的容器,加⼊到同⼀個虛擬⽹絡中,造成徹底屏蔽硬件的效果。

數據卷

除了⽹絡以外,⽂件也是重要的進⾏數據交互的資源。在以往的虛擬機中,咱們一般直接採⽤虛擬機的⽂件系統做爲應⽤數據等⽂件的存儲位置。然⽽這種⽅式其實並⾮徹底安全的,當虛擬機或者容器 出現問題致使⽂件系統⽆法使⽤時,雖然咱們能夠很快的經過鏡像重置⽂件系統使得應⽤快速恢復運⾏,可是以前存放的數據也就消失了。 爲了保證數據的獨⽴性,咱們一般會單獨掛載⼀個⽂件系統來存放數據。這種操做在虛擬機中是繁瑣的,由於咱們不但要搞定掛載在不一樣宿主機中實現的⽅法,還要考慮掛載⽂件系統兼容性,虛擬操做 系統配置等問題。值得慶幸的是,這些在 Docker ⾥都已經爲咱們輕鬆的實現了,咱們只須要簡單的⼀兩個命令或參數,就能完成⽂件系統⽬錄的掛載。 可以這麼簡單的實現掛載,主要仍是得益於 Docker 底層的 Union File System 技術。在 UnionFS 的加持下,除了可以從宿主操做系統中掛載⽬錄外,還可以建⽴獨⽴的⽬錄持久存放數據,或者在容器間共 享。 在 Docker 中,經過這⼏種⽅式進⾏數據共享或持久化的⽂件或⽬錄,咱們都稱爲數據卷 ( Volume )。

Docker Engine

時⾄今⽇,Docker ⽣態已經遠⽐它誕⽣之初要龐⼤許多,雖然咱們仍然習慣使⽤ Docker 這個名字去指代實現容器技術⽀持的軟件,但顯然更加容易與其餘的概念產⽣混淆。這⾥咱們頗有必要對這個 Docker 中最核⼼的軟件進⾏介紹,不只由於它在 Docker ⽣態中扮演着中⼼的地位,也由於它是咱們在開發中實實在在接觸最多的東西。 ⽬前這款實現容器化的⼯具是由 Docker 官⽅進⾏維護的,Docker 官⽅將其命名爲 Docker Engine,同時定義其爲⼯業級的容器引擎 ( Industry-standard Container Engine )。在 Docker Engine 中,實現了 Docker 技術中最核⼼的部分,也就是容器引擎這⼀部分。

docker daemon 和 docker CLI

雖然咱們說 Docker Engine 是⼀款軟件,但實實在在去深究的話,它其實算是由多個獨⽴軟件所組成的軟件包。在這些程序中,最核⼼的就是 docker daemon 和 docker CLI 這倆了。 全部咱們一般認爲的 Docker 所能提供的容器管理、應⽤編排、鏡像分發等功能,都集中在了 docker daemon 中,⽽咱們以前所提到的鏡像模塊、容器模塊、數據卷模塊和⽹絡模塊也都實如今其中。在操 做系統⾥,docker daemon 一般以服務的形式運⾏以便靜默的提供這些功能,因此咱們也一般稱之爲 Docker 服務。

在這裏插入圖片描述
在 docker daemon 管理容器等相關資源的同時,它也向外暴露了⼀套 RESTful API,咱們可以經過這套接⼜對 docker daemon 進⾏操做。或者更確切的說,是經過這套 RESTful API 對 docker daemon 中運 ⾏的容器和其餘資源進⾏管理。 一般來講,咱們是採⽤在控制檯或者命令⾏輸⼊命令來控制 docker daemon 的,由於這樣很酷也更容易適應那些有或者沒有圖形界⾯的操做系統。 若是咱們在控制檯中編寫⼀個 HTTP 請求以藉助 docker daemon 提供的 RESTful API 來操控它,那顯然是個費腦、費⼿又費時間的活⼉。因此在 Docker Engine ⾥還直接附帶了 docker CLI 這個控制檯程序。
在這裏插入圖片描述
熟悉程序結構的朋友們⽐較容易看出來,docker daemon 和 docker CLI 所組成的,正是⼀個標準 C/S ( Client-Server ) 結構的應⽤程序。銜接這二者的,正是 docker daemon 所提供的這套 RESTful API。
相關文章
相關標籤/搜索