在這篇文章中,我將介紹一下爲何須要虛擬化的環境。mysql
而後我將介紹耳熟能詳的虛擬化技術:虛擬機,並大體的介紹一下虛擬機的原理,但願可以讓你知道虛擬機的優劣。redis
在以後,針對虛擬機存在的問題,引出Docker是怎麼提升性能的。sql
最後,我將簡單的介紹一下Docker中比較重要的三個概念,鏡像、容器、和倉庫。docker
在學習Docker以前,咱們須要知道Docker能夠幹什麼,有哪些優勢。網絡
直接看看官方文檔的介紹:架構
Developing apps today requires so much more than writing code. Multiple languages, frameworks, architectures, and discontinuous interfaces between tools for each lifecycle stage creates enormous complexity. Docker simplifies and accelerates your workflow, while giving developers the freedom to innovate with their choice of tools, application stacks, and deployment environments for each project.併發
如今寫個項目,裝個環境均可能須要很長的一段時間。若是你須要在新的機器上部署項目,尤爲是當你須要在不少臺機器上部署項目的時候,會顯得更加的麻煩。app
不只如此,在裝好了環境以後,也有可能由於你和同事之間的某些依賴版本不一致,致使可能會發生」剛剛在我電腦上還能用「的問題。dom
而使用Docker的話,就不須要擔憂環境方面的問題了,使用Docker能夠構建一個一致的環境,而且能夠」一次構建,屢次使用「。也就是說,在你配置好一次環境以後,你能夠將你構建的這個環境用在各類不一樣的地方。工具
Docker是一個虛擬環境容器,能夠將你的開發環境、代碼、配置文件等一併打包到這個容器中,併發布和應用到任意平臺中。在這裏你可能會以爲」容器「這個詞比較難理解,那麼你能夠暫時的理解爲這是一個虛擬機。
爲了實現咱們上面說的」一次構建,屢次使用「,咱們只須要把那些環境都安裝在這個虛擬機裏面,而後把這個虛擬機拷貝不少份,就能在不一樣的地方使用了。
可是上面那麼說實際上是不太嚴謹的,或者說是不對的。
可是我認爲在學習一個新的東西以前,若是可以跟一箇舊的事物做對比,實際上是對咱們的學習特別有幫助的。
思考一下Docker與虛擬機有哪些異同。
相同點:
不一樣點:
那麼在這裏,我想先簡單的介紹一下虛擬的的實現方式,可是由於我對這方面沒有深刻的研究,因此若是有哪些地方說的不對,請不吝指教!
其實虛擬機分爲兩類,一種是構建於操做系統之上的應用軟件,好比VM Workstations,又或者是各類安卓模擬器等;另外一種是直接的虛擬機管理系統。
咱們主要說說應用軟件類型的虛擬機,在早期,這類虛擬機是徹底用模擬電路的形式來實現的。由於咱們知道計算機硬件的組成,歸根結底就是各類門電路,因此在早期虛擬機就經過模擬數字電路,來模擬出一套計算機所需的硬件。而後在這個硬件之上,安裝所須要的操做系統。
這樣的實現方式很容易理解,可是咱們一樣也可以推測,這樣的實現方式效率很低。
因此在這以後,出現了一種新的虛擬機實現方式,若是虛擬機運行的操做系統,他須要的硬件架構跟宿主機(原來的機器)是同樣的,那麼也就不須要去模擬這個電路了,能夠直接」借用「宿主機的電路來輸入輸出。這樣作的話,虛擬機的效率就變高了。
此外,若是虛擬機須要運行的目標操做系統,所須要的指令集跟宿主機是不一致的,好比宿主機上安裝了一個Windows,這是x86架構的,而若是我想要運行Android,這是Arm架構的,那麼就沒辦法借用宿主機上的硬件進行輸入輸出了,因此就須要一個模擬器,也就是咱們說的」安卓模擬器「。
介紹完這些,你大概知道了虛擬機的實現方式了,可是就算是同種架構,同樣的指令集,能夠借用宿主機的硬件,這樣虛擬化出來的操做系統仍是會顯得比較慢。你想,安裝一個Windows,就要十幾G的硬盤空間了,就算什麼都不幹,也要佔用兩三G的內存,這些資源加起來,一臺機器,最多模擬幾臺虛擬機。爲了實現環境的隔離,在資源佔用上消耗了這麼多,實在是不值得。
因此,就有了Docker。
Docker解決了爲了分割環境須要很大資源代價的這個問題。
你想,咱們最開始的需求只是但願能有個獨立的環境,在這個環境裏面有獨立的文件系統、網絡系統、進程系統等等。因此其實咱們不須要耗費這麼大的功夫去模擬一個操做系統出來,咱們只須要想辦法限制每一個進程可以訪問的資源,分配好這些資源,讓進程」覺得「本身運行在一個獨立的操做系統中,就能夠了。咱們全部的進程都是基於當前的操做系統,不管是啓動,仍是運行,速度都會很快。而且,也沒有額外運行一個或多個操做系統的資源損耗。
因此,爲了區別於硬件層面的虛擬機,就有了操做系統層虛擬化這種技術,也稱爲:容器。
而後我想再介紹一下Docker中很重要的兩個概念:鏡像和容器。
鏡像就是模板,你能夠理解爲咱們把環境配置好後,保存起來做爲構建容器的模板,有點像面相對象中」類「的概念。
容器是Docker運行的實體,你能夠理解爲一個個」虛擬的操做系統「,這個容器是根據鏡像構建出來的,好比你構建了一個包含了jdk,mysql,redis的鏡像,那麼只要根據這個鏡像,你能夠建立出不少個如出一轍的容器。這裏有點像面相對象中」對象「的概念。
而後我還想介紹一下倉庫這個概念,你能夠理解爲,倉庫裏面存儲了不少的鏡像。爲何須要這麼作呢,我認爲一個是爲了方便,另外一個是爲了複用。方便,是由於咱們以前提到了」一次構建,屢次使用「這個概念。咱們只須要把配置好的環境打包成一個鏡像,那麼只須要把這個鏡像拷貝出來,就能夠在任何地方進行構建了。那麼倉庫就是像GitHub同樣,咱們能夠把打包好的鏡像push上去,在須要的機器上再pull下來,減小了運輸成本。
另一點,複用,是由於在不少時候,你們都是須要構建同樣的環境了,好比某個版本的Redis,某個版本的MySQL,某個版本的JDK等等,那麼有了倉庫的話,咱們就不須要再構建一次了,只須要使用別人構建過的就能夠了。
若是咱們把容器理解爲運行在當前操做系統中的進程的話,只不過這個進程可以訪問的資源是有限的,會讓這個進程誤覺得」本身運行在了獨立的操做系統中「,那麼咱們就可以理解這句話了:
Docker容器沒有本身的Kernel,他使用的Kernel版本,跟鏡像無關,宿主機有關。
這個問題其實蠻有趣的,原文在這裏。
可是當初我還有個問題,咱們在Docker的倉庫中,有看到CentOS的鏡像,也有看到Ubuntu的鏡像。可是咱們上面又說,容器用的是宿主機上的Kernel版本,而不是鏡像的。那若是我在CentOS上運行了一個Ubuntu的鏡像,該怎麼解釋呢?
緣由是這樣的,咱們說的內核(Kernel),指的是Linux的核心,好比他的內存管理,文件管理等等,可是說的Ubuntu、CentOS這些,指的是Linux的發行版,這些發行版,都是基於Linux製做的,只不過在不一樣的發行版中,添加了不一樣的工具。好比在CentOS中,用的是yum包管理工具,在Ubuntu中,用的是apt包管理工具。
因此,他們的內核,其實仍是Linux的內核。
嗨,很久不見。
謝謝你能看到這裏!
這篇文章主要是起到一個入門的做用,但願可以讓你對Docker有一個初步的認識。
固然了,由於做者學識有限,在這篇文章中不少地方的講解都是不到位的,若是有哪裏講得不到位,講得不對,但願你能不吝指教,謝謝你!
在後面的文章中,我會給你介紹一下namespace這個概念,讓你大概的知道容器究竟是怎麼實現的。
可是關於Docker的那些操做,不必定會寫一篇文章。由於我以爲這方面優秀的文章已經不少了,官方文檔也很詳細。
《Docker入門》系列的文章目前的規劃是大概會有兩到三篇,定位是偏向於瞭解Docker及一點點的原理,實用性應該不會特別強。
再次感謝你能看到這裏!
PS:若是有其餘的問題,也能夠在公衆號找到我,歡迎來找我玩~