Docker容器化引擎
摘自《Java微服務分散式架構企業實戰》
如今Docker在一線網際網路公司的應用已經非常普遍,使用Docker技術可以給企業帶來極大的好處,使企業的業務水平擴充套件更快速,從而到達彈性部署業務的能力。在雲服務概念興起之後,Docker的使用場景和範圍得到了進一步發展,如今在微服務架構越來越流行的情況下,微服務+Docker的組合方式,更加方便微服務架構運維部署落地,使應用部署、測試和請求都變得前所未有的便捷和輕鬆。
1 Docker與傳統虛擬化方式的區別
百度百科中對Docker的解釋是“Docker是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然後釋出到任何流行的Linux機器上,也可以實現虛擬化。”它是谷歌公司基於Linux核心,通過GO語言開發的。Docker技術與虛擬機器技術相比,前者更加輕便、快捷。之前在安裝Ubuntu時就已經使用過虛擬機器技術VMware,接下來,把Docker技術與傳統虛擬化技術進行比較,瞭解Docker的優點。
傳統的基礎服務設施是由硬體和作業系統組成的,然後在作業系統上再安裝QQ、微信、瀏覽器等軟體,如圖3. 1所示。
傳統的虛擬化技術可以將眾多的計算機結合在一起統一管理,在這個過程中需要用到虛擬化技術(Hypervisor).基於硬體,通過虛擬化技術將多臺主機連線在一起,共同進行管理,如圖3.2所示
圖3. 2類似一個雲服務平臺,假設該平臺有四臺Service(計算機),這四臺機器通過Hypervisor(虛擬化技術),整體虛擬化作業系統,最終組成一個超級計算機。該超級計算機能夠統一排程資源,統一進行管理,能夠分配給使用者一定量的空間供使用者使用,然後每個使用者可以操作自己所分配的那塊空間,且與其他使用者得到的空間中儲存的資訊和分配的資源互不相干。
虛擬機器也是同樣的道理,先是在硬體之上安裝宿主機,在宿主機之上使用Hypervisor實現虛擬化技術,然後再安裝客戶機。以通常使用的計算機為例,在最底層的硬體之上安裝Windows作業系統,然後在作業系統之上使用虛擬化技術(安裝VMware),最後再安裝Ubuntu,使用者可以根據自己的需求,在Ubuntu之上安裝應用程式,如圖3. 3(a)所示。
然而,從圖3. 3(b)中可以發現,有了Docker技術後將不再使用虛擬機器,Ubuntu直接安裝在Docker之上即可。雖然圖3. 3(a)和圖3. 3(b)兩部分看似差別不大,只是用Docker取代虛擬機器而已,但是,在使用Docker時可以發現,Docker直接利用的是宿主機(圖3. 3中安裝了Windows的機器)的核心與資源。安裝在Docker之上的Linux的所有資源都來自於底層裝置,這個時候它的資源是共享狀態的,即Windows中的資源與Docker之上安裝的Ubuntu的資源之間可以共享,而虛擬機器安裝後則會從宿主機中佔用部分資源,而且這部分資源與主機之間是不能夠共享的。如有一臺宿主機,CPU引數為3. 0GHz4核,記憶體16GB,當在該宿主機中安裝虛擬機器(VMware)後,一個虛擬機器開啟後將被分配2GB記憶體,此時宿主機能夠使用的記憶體只剩14GB,如果在虛擬機器上安裝一個App,當App的使用資源超出2GB時,還會發生記憶體溢位,當App的使用資源只有1GB時,宿主機分配給它的資源將會浪費掉一半,假如不安裝虛擬機器,使用Docker的情況時,宿主機不需要單獨為Docker分
配任何資源,Docker可以直接使用宿主機的記憶體,屆時不必擔心為Docker分配的資源大小是否合適、資源是否因為分配不均而導致浪費問題,只要是宿主機的資源即可全部拿來使用。
2.Docker 容器化引擎
簡單來說,Docker就是使用客戶端-伺服器(C/S)架構模式,通過遠端API管理和建立容器的。Docker在容器的基礎之上,會進一步地封裝,把檔案系統、網路互聯、程序隔離等都封裝在不同的層面之上,這些都極大地簡化了Docker容器的建立與維護。Docker容器化引擎也是一種伺服器,這種伺服器可以長時間地執行,可以通過REST API和守護程序完成通訊,如圖3. 4所示。
圖3. 4中 Server Docker Daemon 即為Docker的守護程序,Client Docker CLI是客戶端命令列工具。請求會通過命令列工具去呼叫Docker提供的REST API,將命令傳送給守護程序。通過API可以對映象(Image)、容器(Container)、網路(Network)、資料卷(DataVolumes進行管理,守護程序最後會把命令的執行結果返回給客戶端。
3.Docker 映象、容器、倉庫
Docker映象是Docker容器執行的前提,容器是映象執行的例項,有了映象才能夠啟動容器。Docker映象是一個特殊的檔案系統,它的內部除了包含提供容器執行時所需要的程式、庫、資源、配置等檔案外,還包含了容器在執行時需要準備的一些配置引數資訊(如匿名卷、環境變數、使用者等)。Docker映象裡面不會包含任何動態資料,它的內容在構建之後也不會被改變,而且,Docker映象是分層構建的,前一層是後一層的基礎,每一層在構建完成後都不會再發生改變,後一層上的任何改變都只發生在當前這一層上,並不會影響到之前已經構建好的層。例如,在當前層中刪除前一層的檔案時,實際上並不是真刪除了前一層的檔案,只是在當前層標記該檔案被刪除,最終容器執行的時候,雖然看不到該檔案,但是實際上該檔案會一直跟隨映象。因此,在構建Docker映象時需要特別注意,每一層都要儘量只包含該層所必須新增的東西,其他額外的東西都應該在該層構建結束前清理掉。通常在構建Docker映象時會把之前構建好的映象用來作為基礎層,然後進一步新增新的層,在新層中定製自己所需要的內容,構建新的映象,如圖3. 5所示。
從圖3. 5可以看出,Docker引擎之上,安裝了作業系統(OS),這時就相當於封裝了一層映象,該層將不再發生變化。在OS的基礎上再新增一層,第二層當中裝載了Java,由於該層是在第一層OS的基礎上新加的,因此,該層不僅包含了Java也繼承了第一層OS的Linux,這時的映象又再一次進行了封裝,當新增到第三層時,可以發現,在構建的新映象中,不僅包含新安裝的MySQL,還包含了前兩層中的Linux和Java.
映象(Image)和容器(Container)的關係,就像是面向物件程式設計思想中的類和例項一樣,容器是映象執行時的實體。容器同樣也能夠被建立、啟動、停止、刪除、暫停等。每一個容器都是一個程序,但它與宿主機中的程序之間的區別就是容器擁有自己的名稱空間。
前面講過映象使用的是分層儲存,容器也是如此,每一個容器在執行時,都是以映象為基礎層,在基礎層的上面會再建立一個儲存層用來為容器執行時的讀和寫做準備。該儲存層的生命週期會伴隨著容器的消亡而消亡,所以儲存在儲存層中的資訊都會有丟失的風險。因此,所有的檔案在寫入時,都應該使用資料卷(資料卷是一個可以供一個或多個容器使用的特殊目錄)或者繫結宿主目錄,這樣檔案的讀寫操作會跳過容器儲存層,直接對宿主(或網路儲存)發生讀寫,其效能和穩定性更高。
資料卷的生存週期並不會因為容器的消亡而消亡。因此,使用資料卷後,容器無論是被刪除還是被重新執行,資料都不會丟失。
映象構建完成後,可以很容易地在當前宿主機上執行,但是,如果需要在其他伺服器上使用這個映象,就需要一個集中的儲存、分發映象的服務-Docker Registry服務,如圖3. 6所示。
在Docker Registry服務中包含有多個Repository(集中存放映象檔案的倉庫),每個Repository又包含了多個Tag(標籤),標籤和映象是一一對應的關係,可以通過<倉庫名>:<標籤>的格式指定具體的映象檔案。Docker Registry服務又分為公有的和私有的,公有的Docker Registry服務是開放給使用者使用、允許使用者管理映象的Registry服務,可以滿足使用者上傳和下載映象的需求,最常使用的Registry公有的服務是官方的 Docker Hub,這也是預設的Registry,並且擁有大量高質量的官方映象,但是由於種種原因在國內訪問這些服務可能會比較慢,國內不少雲服務提供商(如時速雲、阿里雲等)也提供了倉庫的本地源,可以提供穩定的國內訪問。當然,使用者如果不希望公開分享自己的映象檔案,Docker也支援使用者在本地網路內建立一個只能自己訪問的私有倉庫。當用戶建立了自己的映象之後就可以使用push命令將它上傳到指定的公有或者私有倉庫。這樣使用者下次在另外一臺機器上使用該映象時,將其從倉庫上使用pull命令拉下來就可以了。
5.Docker Compose官方容器
Compose專案是Docker官方的開源專案,它負責實現對 Docker 容器叢集的快速編排。通過前面的介紹,可以瞭解 Dockerfile模板檔案,讓使用者很方便地定義一個單獨的應用容器。但是,在日常工作中,經常會遇到需要多個容器相互配合完成某項任務的情況。例如,當需要實現一個Web專案時,除了Web服務容器本身之外,往往還需要再配置與之相關的後端資料庫服務容器,甚至包括負載均衡容器等,在這種情況下,使用Docker Compose技術,就能夠很簡單地滿足這些需求。
定義和執行多個容器的Docker應用程式,在Compose中可以使用YML檔案配置應用服務。然後,只需要一個簡單的命令,就可以建立並啟動配置的所有服務。
使用Compose基本有如下三步流程。
(1)在Dockfile中定義應用環境,使其可以在任何地方複製。
(2)在docker-compose.yml中定義組成應用程式的服務,以便它們可以在隔離的環境中一起執行。
(3)執行 dcoker-compose up,Compose將啟動並執行整個應用程式。
Compose中還有兩個重要的概念:服務和專案。
服務(Service):一個應用的容器,實際上可以包括若干執行相同映象的容器例項。
專案(Project):由一組關聯的應用容器組成的一個完整業務單元,在docker-compose.yml檔案中定義。
Compose的預設管理物件是專案,通過子命令對專案中的一組容器進行便捷的生命週期管理。
Compose專案用Python編寫,呼叫Docker服務提供的API實現對容器的管理。因此,只要所操作的平臺支援Docker API,就可以在其上利用Compose進行編排管理。