天天看點

溫故知新:Docker基礎知識知多少一、容器的用途二、容器與集裝箱的關系三、容器核心技術揭秘四、容器的架構一覽五、關于Docker Compose六、小結參考資料

​記得之前曾經粗略的寫過一篇Docker的基礎及ASP.NET Core部署Docker示例的 入門文章 ,但那個時候剛剛學習Docker對Docker的認知還比較淺,現在重新來溫故知新一下。此外,本篇已加入《 .NET Core on K8S學習實踐系列文章索引 》,可以點選檢視更多容器化技術相關系列文章。

一、容器的用途

首先,我們來溫習一下Docker的幾個用途,亦或者說Docker到底幫我們解決什麼問題?

1、标準化打包

記得在容器技術出來之前,我們開發者進行打包一般都依賴于各自開發語言平台獨有的打包機制,比如.NET和Java平台下都會依賴于各自不同的釋出部署技術,但在容器技術出來之後,不管是.NET還是Java都會将其釋出為容器鏡像推送到鏡像倉庫中來進行複用。

溫故知新:Docker基礎知識知多少一、容器的用途二、容器與集裝箱的關系三、容器核心技術揭秘四、容器的架構一覽五、關于Docker Compose六、小結參考資料

2、隔離

每個容器在運作時都會認為自己是獨自占有了一台機器,即一個獨立的環境互不幹擾。其實,容器的本質是一個程序,程序與程序之間互相隔離造就了容器與容器互不影響的特性。在啟動一個容器(即建立一個程序時),通過 Namespace 技術實作容器的隔離、通過 Cgroups 來實作容器的資源控制。

溫故知新:Docker基礎知識知多少一、容器的用途二、容器與集裝箱的關系三、容器核心技術揭秘四、容器的架構一覽五、關于Docker Compose六、小結參考資料

關于Namespace 和 Cgroups 可以繼續浏覽本文3.3小節。

3、标準化部署

在容器技術出來之前,和打包機制一樣,我們都依賴于具體開發語言平台的部署機制,比如IIS、Tomcat等。但是,容器技術出來之後,即使我們使用不同的開發語言都可以使用同樣的部署技術,例如Mesos或Kubernetes。至此,之前的運維人員也不在需要學習多套部署技術,隻需要了解如K8s一類的标準化容器編排平台即可。

溫故知新:Docker基礎知識知多少一、容器的用途二、容器與集裝箱的關系三、容器核心技術揭秘四、容器的架構一覽五、關于Docker Compose六、小結參考資料

二、容器與集裝箱的關系

提到容器要解決的問題,就不得不提一下運輸業以及集裝箱。幾十年前,運輸業面臨着因貨物類型不同而導緻損失,又或者在運輸過程中使用不同的交通工具也會讓整個過程痛苦不堪。幸運的是,集裝箱的發明幫助運輸業解決了這個問題:

(1)任何貨物,無論是鋼琴還是瑪莎拉蒂,都被放到各自的集裝箱中。

(2)集裝箱在整個運輸過程中都是密封的,隻有到達最終目的地才被打開。

(3)集裝箱可以被高效地裝卸、重疊和長途運輸。例如:現代化的起重機可以自動在卡車、輪船和火車之間移動集裝箱。

溫故知新:Docker基礎知識知多少一、容器的用途二、容器與集裝箱的關系三、容器核心技術揭秘四、容器的架構一覽五、關于Docker Compose六、小結參考資料

容器的核心思想其實也就是将集裝箱的思想應用到了軟體的打包和部署上,為各類不同的代碼提供了一個基于容器的标準化運輸系統。換句話說,容器可以将任何應用及其依賴環境打包為一個輕量級、可移植、自包含的獨立運作環境,容器可以運作在幾乎所有的作業系統之上。

不得不說,Docker的Logo就是一堆集裝箱放在海豚上,作為海豚的docker就是一個标準化的運輸系統:

溫故知新:Docker基礎知識知多少一、容器的用途二、容器與集裝箱的關系三、容器核心技術揭秘四、容器的架構一覽五、關于Docker Compose六、小結參考資料

三、容器核心技術揭秘

1、Linux作業系統核心一窺

為了進一步了解Docker,我們先來看看Linux作業系統及其核心,如下圖所示:

溫故知新:Docker基礎知識知多少一、容器的用途二、容器與集裝箱的關系三、容器核心技術揭秘四、容器的架構一覽五、關于Docker Compose六、小結參考資料

從上圖可知,最底層為硬體層,包含了記憶體、磁盤、CPU、網卡等;往上一層是核心空間,Kernel就是作業系統核心,負責管理硬體層中的各種資源 以及 排程程序 等工作;頂層是使用者空間,使用者程式就在此空間内運作,并調用核心空間提供的服務;

2、虛拟機和容器的差别

大概了解了作業系統的核心之後,我們再來看看老生常談的容器和虛拟機的差異,如下圖所示:

溫故知新:Docker基礎知識知多少一、容器的用途二、容器與集裝箱的關系三、容器核心技術揭秘四、容器的架構一覽五、關于Docker Compose六、小結參考資料

虛拟機:主要是由硬體虛拟化+核心虛拟化技術來實作,它在主控端作業系統或硬體層的基礎之上引入一層Hypervisor來虛拟出磁盤、CPU等資源,然後在虛拟出來的資源的基礎之上運作Guest OS進而實作最終的虛拟機。

容器:直接在主控端作業系統之上建構一個Docker Engine,共享主控端作業系統核心,在此基礎之上隻引入了少量的Guest OS來實作。

對比:

(1)虛拟機的隔離性比容器好,因為虛拟機是一種強隔離機制;

(2)虛拟機比較重量級,啟動時速度比較慢,消耗資源也比較多;

(3)容器的隔離性不如虛拟機,它是一種軟體隔離機制,但它比較輕量級,引入的東西較少,是以速度快消耗資源少;是以,在同一個實體機上能夠啟動的容器的數量遠遠多于虛拟機的數量;

3、容器的核心技術

了解了作業系統的核心以及和虛拟機的差異,現在我們可以正式了解一下基于Linux核心的Docker容器核心技術到底有哪些(當然,本文隻是粗略的介紹一下,更詳細的部分請浏覽本文的參考資料文章),如下圖所示:

溫故知新:Docker基礎知識知多少一、容器的用途二、容器與集裝箱的關系三、容器核心技術揭秘四、容器的架構一覽五、關于Docker Compose六、小結參考資料

(1)CGroups:

容器程序建立好後,若不進行其他處理,該程序運作時所消耗及占用的資源(如 CPU、記憶體)等,是可以被其他主控端程序或其他容器程序享用的。為了解決這個問題,Linux 容器設計中引入了 Cgroups 的概念。

Linux CGroups 的全稱是 Linux Control Group,它的主要作用就是限制一個程序(這裡也可以指容器)能夠使用的資源上限(如 Cpu、記憶體、網絡等等)。關于Docker的資源限制,可以閱讀我這一篇《

Docker資源限制學習與驗證

》文章。

(2)Namespaces:

剛剛提到,容器的本質是一個程序,程序與程序之間互相隔離造就了容器與容器互不影響的特性。在啟動一個容器(即建立一個程序時),通過 Namespaces 技術實作容器的隔離。

容器程序的建立通過 Linux 平台下的 Clone 方法建立,在調用該方法建立程序時,通過指定額外的 Namespace 參數,使得剛建立的程序屬于一個獨立的空間。

int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL)           

指定額外參數 CLONE_NEWPID 建立的新程序,有一個自己的 獨立程序空間,在這個空間裡,它的程序 ID 為 1。它既看不到其在主控端的真正程序、也看不到其他容器的程序。

(3)Networking

容器的建立還需要網絡的支援,Networking這一塊主要是虛拟網卡、網橋及iptables為容器提供組網支援;

(4)Storage

最後,容器的建立還需要存儲的支援,Storage這一塊提供了容器支援的一些檔案系統,如Device Mapper、Btrfs 及 Aufs 等等;

4、容器的鏡像

剛剛提到,容器鏡像為标準化打包提供了基礎。容器鏡像采用的是分層的方式來組織的,如下圖所示:

溫故知新:Docker基礎知識知多少一、容器的用途二、容器與集裝箱的關系三、容器核心技術揭秘四、容器的架構一覽五、關于Docker Compose六、小結參考資料

可以看到,底層的是基礎鏡像,稱為Base Image,例如Ubuntu、CentOS等,它可以和主控端的OS是不一樣的,但是它會共享主控端作業系統的核心;在基礎鏡像之上,可以有多層鏡像,例如Java JDK的依賴,.NET Core Runtime依賴等;依賴層之上呢,可以是具體的應用程式的Release。

綜上所述,容器鏡像采用分層的方式,可以很友善地實作鏡像層的複用。如果兩個容器所依賴的底層鏡像層是相同的,可以共同應用同一個Hash值的底層鏡像,進而也可以節省傳輸和網絡的開銷。例如,圖中Image1和Image2的就實作了基礎鏡像層的複用。

四、容器的架構一覽

有了之前的基礎知識,最後我們再來看看Docker的架構,如下圖所示:

溫故知新:Docker基礎知識知多少一、容器的用途二、容器與集裝箱的關系三、容器核心技術揭秘四、容器的架構一覽五、關于Docker Compose六、小結參考資料

從上圖可以看出,一個典型的Docker架構包含了三塊内容:

(1)Docker Registry:鏡像倉庫,主要負責存儲鏡像,官方的倉庫是Docker Hub,你也可以基于開源項目Harbor或者使用阿裡雲等雲服務廠商提供的鏡像倉庫服務來搭建私有鏡像倉庫,如果有興趣可以參考我的這一篇《

Docker常用流行鏡像倉庫搭建

》。

(2)Docker Host:Docker宿主,首先它會運作一個Docker daemon,會接收Docker Client發送的指令來執行拉取鏡像、緩存、啟動等操作;其次,Docker daemon執行完Docker Client發送過來的指令後,所有的容器都會在Docker Host上運作;

(3)Docker Client:用戶端操作,主要負責通過docker指令行對容器進行基本操作,如拉取鏡像,建構鏡像,運作容器等等;

更多關于Docker架構的内容請參考:

https://docs.docker.com/get-started/overview/

五、關于Docker Compose

Docker主要用來運作單容器應用,而Docker Compose則是一個用來定義和應用多容器應用的工具,如下圖所示:

溫故知新:Docker基礎知識知多少一、容器的用途二、容器與集裝箱的關系三、容器核心技術揭秘四、容器的架構一覽五、關于Docker Compose六、小結參考資料

使用Docker Compose,我們可以将多容器的定義和部署方式定義在一個yml檔案中,這種方式特别是微服務這種架構風格,可以将多個微服務的定義及部署都規範在一個yml檔案中,然後一鍵部署、啟動或銷毀整個微服務應用。所有的一切操作,隻需要下面的一句話:

$docker-compose up           

很多人建議在測試環境,使用Docker Compose來快速的部署和測試微服務應用,在生産環境則建議使用Kubernetes這種生産級的容器雲平台。

如果對Docker Compose感興趣,我之前也有寫一篇

使用Docker Compose來編排Spring Cloud微服務的示例

文章,有興趣可以看看。

六、小結

本文從Docker容器要解決的幾個問題入手,介紹了容器與集裝箱的關聯、容器的核心實作技術、容器的架構,最後簡單介紹了一個Docker Compose這個多容器應用工具,相信能夠從背景知識上幫你了解容器到底要幫助我們解決的問題。

參考資料

楊波,《

Spring Boot與Kubernetes雲原生應用實踐

》(強力推薦訂閱學習)

EdisonZhou,《

ASP.NET Core on Docker入門

godruoyi,《

容器的工作原理和隔離機制

CloudMan,《

每天5分鐘玩轉Docker容器技術