Docker與Kubernetes的前世今生(上)

隨着大數據和移動技術的快速發展以及企業業務需求的不斷變化,越來越多的企業選擇使用雲服務器來處理業務,以適應龐大數據量和複雜業務下基礎設施部署困難、運營成本高的現狀。在這樣的背景下,誕生了許許多多的雲服務商,一系列和雲服務相關的概念如IaaS、PaaS、SaaS也孕育而生。

在雲服務發展的過程中,容器技術和雲服務促成了相互推進和成就,而其中知名度最高的兩個開源項目毫無疑問便是Docker和Kubernetes。那麼Docker和Kubernetes爲什麼會誕生,前世今生是什麼,又有怎樣的聯繫和關係呢?本文將詳細介紹。

容器技術的由來

在虛擬機出現前的業務環境中,應用往往部署在物理機器上,但這樣的部署方式存在一些弊端:

1、空閒資源難以得到複用;
2、部署異構系統時需要重新採購物理資源;
3、大量中小容量的機器使得運維成本提升。

在這樣的情況下,如何降低基礎設施的管理成本便成爲急切的需求。虛擬機的出現使得用戶在一臺物理機上能夠獨立運行多個相互隔離的系統,通過對資源的抽象化使得主機資源能夠被有效複用,這對於企業IT管理十分有益。

然而,虛擬機同樣也會帶來一些問題:大量獨立系統的運行會佔用許多額外開銷,消耗宿主機器資源,資源競爭時可能會嚴重影響系統響應;此外,每運行新的虛擬機都需要重新配置一遍環境,和在物理機上的情況基本無異,重複的環境配置操作則會消耗開發和運維人員的工作時間。此時需求便關注到如何減少虛擬化時的資源損耗,同時還能保證隔離性,以及使應用的上線週期更短,這便引導了容器技術的發展。從2000年開始,各家類Unix操作系統廠商開始陸續推出容器相關的項目,2008年Google的Cgroups貢獻給Linux kernel 2.6.24後創造了LXC( Linux Containers),實現了多個獨立的Linux環境(容器)可運行在同一個內核。對於一個完整獨立運行環境來說,需要包含三個關鍵:環境隔離、資源控制和文件系統。在LXC中則分別通過Namespace、Cgroups、rootfs來實現相應的能力。

環境隔離——Namespace:LXC將內核全局資源封裝,每個Namespace都有一份獨立的資源,使得不同的進程在各自Namespace內對同一種資源的使用互不干擾,不會影響其他Namespace下的資源,實現了進程隔離。
資源控制——Cgroups:LXC通過Cgroups對資源進行控制,限制和隔離一組進程對系統資源的使用。在Cgroups出現之前OS只能對一個進程做資源限制,而 Cgroups可以對進程進行任意分組,如何分組由用戶自定義,藉此實現對於一個Namespace的資源調度管理。

文件系統——rootfs:rootfs掛載在容器根目錄上,用來爲容器進程提供隔離後執行環境的文件系統。rootfs包含一個操作系統所涉及的文件、配置和目錄,在Linux 操作系統內核啓動時,內核會先掛載一個只讀的rootfs,當系統檢測其完整性之後,決定是否將其切換到讀寫模式。

在通過LXC構建容器後,一臺宿主機能夠實現多個相互隔離應用的運行。同時,共享內核使得每個容器又很輕量,解決了運行大量隔離應用時虛擬機資源消耗過重的弊端。然而,LXC雖解決了應用隔離的問題,但卻只是輕量的容器技術,沒有解決各平臺軟件交付標準不統一的問題,如不同的軟件交付工具、應用運行規範不統一、環境依賴複雜等帶來的配置開銷。這些問題使容器技術的推廣依然比較有限,直到Docker的出現。

Docker的誕生

早期Docker是基於LXC開發,因此Docker容器也有着和LXC相似的特性,僅需要較少資源便可以啓動。但不同於LXC,Docker除了容器運行,還是一個打包、分發和運行應用程序的平臺。Docker允許將應用和其依賴的運行環境打包在一起,打包好的“集裝箱“(鏡像)能夠被分發到任何節點上執行,無需再進行配置環境的部署。這樣使得Docker解決了開發和部署應用時環境配置的問題,規範化了應用交付和部署,降低了部署測試的複雜度以及開發運維的耦合度,極大提升了容器移植的便利性,便於構建自動化的部署交付流程。- ## Docker與虛擬機架構對比

Docker和虛擬機都是資源虛擬化發展的產物,但二者在架構上又有區別。虛擬機通過Hypervisor虛擬化主機硬件資源,然後構建客戶機操作系統,由宿主機的管理程序管理;Docker直接運行於主機內核,應用在主操作系統的用戶空間上執行獨立任務,不需要從操作系統開始構建環境,賦予了應用從交付到部署再到運維的獨立性。

Docker容器和虛擬機架構區別(圖片來源:https://www.docker.com/resources/what-container)

虛擬機的啓動時間可能是分鐘級的,而Docker容器創建是秒級別。對於硬盤的使用Docker一般爲MB級別,遠小於包含操作系統的虛擬機GB級磁盤使用量。對於操作系統來說,能支持運行的Docker容器數量遠多於虛擬機。

用Docker運行一個應用

那麼,如何用Docker啓動一個應用呢?對於啓動應用來說,首先需要獲得程序本身和所需要的環境配置。Docker會將應用運行所有需要的靜態資源如代碼、運行時環境、配置封裝爲鏡像,鏡像通過Union FS採用分層存儲架構,通過描述文件Dockerfile指令構建鏡像層。Dockerfile裏包含多條指令描述該層應當如何構建,隨着鏡像層的逐層疊加,將一個完整的鏡像所需要的信息全部包含。外部則通過統一文件系統將相互疊加的層整合起來,以只可讀的統一文件(Union Read-Only File System)形式展現,這樣的分層存儲使得鏡像的複用和定製變的更爲容易,壓縮了存儲空間。鏡像運行之後的實體是容器。Docker容器同樣採用分層存儲,通過在鏡像頂部增加一層可讀可寫層,外部以可讀寫的統一文件(Union Read-Wirte File System)形式展現。當容器運行時所有的進程操作均在可讀可寫層,而下面的鏡像則不會被修改。容器的實質是進程,運行於自己獨立的命名空間。容器存儲層的生命週期和容器一樣,一旦容器消亡,存儲層也一併消亡,所以原生的容器是無狀態的,這也就是爲什麼之後編排系統會引入有狀態服務和持久化存儲以支持有狀態服務。

容器分層存儲示意圖(圖片來源:https://docker-doc.readthedocs.io/zh_CN/latest/terms/layer.html)

Docker架構

Docker的鏡像和容器通過三端的服務操作和管理:請求端Docker Client、主機端Docker Host和遠端拉取鏡像的倉庫Registry。Docker Client負責接收指令,與Docker Host下的守護進程Docker Daemon進行交互。Host提供了執行和運行應用程序的完整環境,其中的Docker Daemon用於管理Docker鏡像、容器、網絡和存儲卷,負責所有與容器相關的操作如拉取鏡像、創建容器等,會不斷偵聽Docker API請求並進行處理。Registry則是鏡像管理的倉庫,用戶可以將創建的鏡像提交到倉庫進行存儲,同時方便從倉庫拉下來鏡像爲自己所用。

Docker架構簡圖(圖片來源:https://docs.docker.com/get-started/overview/#docker-architecture)

本文小結

虛擬化技術的出現使企業只需要通過線上租用即可獲得所需的運行環境。而Docker容器技術實現了容器間的相互隔離並提供標準化和可複用的服務,給予開發、測試和生產環境統一的運行環境,爲企業實現DevOps提供有力支持。

然而,Docker也並非可完全取代虛擬機。與虛擬機相比,Docker隔離性相對較弱,屬於進程之間的隔離,而虛擬機可實現系統級別隔離;Docker尚且面向開發人員,和虛擬機的可視化操作界面相比增加了學習成本,並且對GUI應用不夠友好;對於使用場景而言,虛擬機面向虛擬資源隔離,容器面向應用隔離,因此在虛擬機上面跑容器並不衝突。

綜上所述,雖然Docker容器技術幫助開發人員提升了生產力,但實際生產環境相比開發環境更復雜、規模更大,僅靠Docker容器技術並不意味着能把系統架構以微服務化的形式帶上生產。當面對容器間通信處理、跨節點的資源調度等情況時,必須存在接口規範以及編排工具進行容器統一管理。那麼主流容器編排工具有哪些?編排工具的作用又是什麼呢?下一篇文章會詳細介紹。

往期原創文章TCOS – 業界首個支持生產級大數據業務的容器操作系統
TDC–帶來新一代大數據產品形態
行業觀察: 雲+大數據+AI推動企業數據業務演進TCOS 2.0 發佈 | 面向異構聯邦的容器操作系統

作者介紹:

本文轉載自大數據開放實驗室,已經過對方授權。大數據開放實驗室由星環信息科技(上海)有限公司運營,致力於大數據技術的研究和傳播。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章