Docker入門(1):概述

紅雞菌發表於2020-06-28

1.摘要

在這篇文章中,我將介紹一下為什麼需要虛擬化的環境。

然後我將介紹耳熟能詳的虛擬化技術:虛擬機器,並大致的介紹一下虛擬機器的原理,希望能夠讓你知道虛擬機器的優劣。

在之後,針對虛擬機器存在的問題,引出Docker是怎麼提高效能的。

最後,我將簡單的介紹一下Docker中比較重要的三個概念,映象、容器、和倉庫。

2.介紹

在學習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.

現在寫個專案,裝個環境都可能需要很長的一段時間。如果你需要在新的機器上部署專案,尤其是當你需要在很多臺機器上部署專案的時候,會顯得更加的麻煩。

不僅如此,在裝好了環境之後,也有可能因為你和同事之間的某些依賴版本不一致,導致可能會發生”剛剛在我電腦上還能用“的問題。

而使用Docker的話,就不需要擔心環境方面的問題了,使用Docker可以構建一個一致的環境,並且可以”一次構建,多次使用“。也就是說,在你配置好一次環境之後,你可以將你構建的這個環境用在各種不同的地方。

Docker是一個虛擬環境容器,可以將你的開發環境、程式碼、配置檔案等一併打包到這個容器中,併發布和應用到任意平臺中。在這裡你可能會覺得”容器“這個詞比較難理解,那麼你可以暫時的理解為這是一個虛擬機器。

為了實現我們上面說的”一次構建,多次使用“,我們只需要把那些環境都安裝在這個虛擬機器裡面,然後把這個虛擬機器拷貝很多份,就能在不同的地方使用了。

3.虛擬機器

但是上面那麼說其實是不太嚴謹的,或者說是不對的。

但是我認為在學習一個新的東西之前,如果能夠跟一箇舊的事物作對比,其實是對我們的學習特別有幫助的。

思考一下Docker與虛擬機器有哪些異同。

相同點:

  • 可以啟動一個系統映象
  • 各個”系統“之間是相互隔離的,包括網路,檔案等
  • 兩者都像是在執行虛擬的作業系統

不同點:

  • Docker的啟動更快
  • Docker佔用的資源更小
  • 虛擬機器可以執行不同平臺的作業系統,比如在Windows上可以模擬Android

那麼在這裡,我想先簡單的介紹一下虛擬的的實現方式,但是因為我對這方面沒有深入的研究,所以如果有哪些地方說的不對,請不吝指教!

其實虛擬機器分為兩類,一種是構建於作業系統之上的應用軟體,比如VM Workstations,又或者是各種安卓模擬器等;另一種是直接的虛擬機器管理系統。

我們主要說說應用軟體型別的虛擬機器,在早期,這類虛擬機器是完全用類比電路的形式來實現的。因為我們知道計算機硬體的組成,歸根結底就是各種閘電路,所以在早期虛擬機器就通過模擬數位電路,來模擬出一套計算機所需的硬體。然後在這個硬體之上,安裝所需要的作業系統。

這樣的實現方式很容易理解,但是我們同樣也能夠推測,這樣的實現方式效率很低。

所以在這之後,出現了一種新的虛擬機器實現方式,如果虛擬機器執行的作業系統,他需要的硬體架構跟宿主機(原來的機器)是一樣的,那麼也就不需要去模擬這個電路了,可以直接”借用“宿主機的電路來輸入輸出。這樣做的話,虛擬機器的效率就變高了。

此外,如果虛擬機器需要執行的目標作業系統,所需要的指令集跟宿主機是不一致的,比如宿主機上安裝了一個Windows,這是x86架構的,而如果我想要執行Android,這是Arm架構的,那麼就沒辦法借用宿主機上的硬體進行輸入輸出了,所以就需要一個模擬器,也就是我們說的”安卓模擬器“。

介紹完這些,你大概知道了虛擬機器的實現方式了,但是就算是同種架構,一樣的指令集,可以借用宿主機的硬體,這樣虛擬化出來的作業系統還是會顯得比較慢。你想,安裝一個Windows,就要十幾G的硬碟空間了,就算什麼都不幹,也要佔用兩三G的記憶體,這些資源加起來,一臺機器,最多模擬幾臺虛擬機器。為了實現環境的隔離,在資源佔用上消耗了這麼多,實在是不值得。

4.Docker

所以,就有了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:如果有其他的問題,也可以在公眾號找到我,歡迎來找我玩~

相關文章