摘要:本文立足于新手,從容器和虛擬機兩個大的概念入手,由淺入深,由宏轉微,為我們解析了的方方面面。出于各種考量與需求,容器在外觀上與虛擬機非常相似。大家可以在數秒鐘內完成容器的創建與運行,而虛擬機則由于需要引導完整的虛擬操作系統而耗費更多時間。
當小數看到這篇文章時內心是激動的,因為或許介紹Docker容器的文章有無數,但是如此清晰易懂、對小白如此友好的卻不多見。本文立足于新手,從容器和虛擬機兩個大的概念入手,由淺入深,由宏轉微,為我們解析了Docker的方方面面。來吧朋友們,理解它,熱愛它,然后更好地使用它。
作為程序員或者技術人員,大家肯定聽說過Docker的鼎鼎大名——這款工具能夠幫助我們高效打包、發布及運行承載著應用程序的“容器”系統。其發展如火如荼——從開發者到運維人員,每個人都在關注著這位技術新貴。即使是像谷歌、VMware與Amazon這樣的技術巨擘也在構建相關服務為其提供支持。
無論大家是否有意立即使用Docker,我們都應當對其基礎概念加以了解,并明確區分容器與虛擬機之間的差異所在。目前網絡上已經存在大量對二者關聯與區別的闡述性文章,不過在今天的綜述中,我們將立足于新手對其加以剖析。
下面首先聊聊虛擬機與容器究竟是什么。
容器與虛擬機究竟是什么?容器與虛擬機擁有著類似的使命:對應用程序及其關聯性進行隔離,從而構建起一套能夠隨處運行的自容納單元。
此外,容器與虛擬機還擺脫了對物理硬件的需求,允許我們更為高效地使用計算資源,從而提升能源效率與成本效益。
容器與虛擬機之間的核心差異在于其架構方法。下面一起進行深入了解。
虛擬機虛擬機在本質上就是在模擬一臺真實的計算機設備,同時遵循同樣的程序執行方式。虛擬機能夠利用“虛擬機管理程序”運行在物理設備之上。反過來,虛擬機管理程序則可運行在主機設備或者“裸機”之上。
下面用更直白的表達來說明:
虛擬機管理程序可表現為軟件、固件或者硬件,并作為虛擬機的運行基礎。虛擬機管理程序本身運行在物理計算機之上,我們也將這種底層硬件稱為“主機設備”。主機設備為虛擬機提供資源,包括內存與CPU。這些資源由不同虛擬機共享,并根據需要進行隨意分配。因此如果一套虛擬機運行有需求大量資源的高強度應用程序,那么我們可以在同一主機設備上為其分配遠高于其它虛擬機的資源配額。
運行在主機設備上的虛擬機(當然,需要配合虛擬機管理程序)通常被稱為一套“客戶機”。這套客戶機容納有應用程序及其運行所必需的各類組件(例如系統二進制文件及庫)。它同時還包含有完整的虛擬硬件堆棧,其中包括虛擬網絡適配器、存儲以及CPU——這意味著它也擁有自己的完整訪客操作系統。著眼于內部,這套客戶機自成體系并擁有專用資源。而從外部來看,這套虛擬機使用的則是由主機設備提供的共享資源。
如上所述,客戶機可以運行主機虛擬機管理程序或者裸機虛擬機管理程序。二者之間存在著多種重要區別。
首先,主機虛擬機管理程序運行在主機設備的操作系統之上。舉例來說,一臺運行有OS X的計算機可以在操作系統之上安裝虛擬機(例如VirtualBox或者VMware Workstation 8)。該虛擬機并不會直接訪問硬件,因此其需要經由主機操作系統(也就是Mac OS X)實現資源獲取。
主機虛擬機管理程序的優勢在于,其基本擺脫了對底層硬件的要求。該主機操作系統負責提供硬件驅動程序,而非由虛擬機管理程序自身提供,因此我們認為其具備更理想的“硬件兼容性”。在另一方面,這種介于硬件與虛擬機管理程序之間的額外層會帶來更多資源消耗,進而降低虛擬機性能表現。
裸機虛擬機管理程序則將虛擬機直接安裝并運行在主機設備硬件之上以改善性能表現。由于其直接接入底層硬件,因此我們不再需要主機操作系統作為輔助。在這種情況下,我們可以直接在硬件上安裝虛擬機管理程序并將其作為操作系統。與主機虛擬機管理程序不同,裸機虛擬機管理程序擁有自己的設備驅動程序及接口,從而直接支持各類I/O、處理或者操作系統特定任務相關組件。這種方式能夠帶來更理想的性能水平、可擴展性以及穩定性。但代價是其硬件兼容性比較有限,因為虛擬機管理程序只能包含一部分設備驅動程序。
說到這里,大家可能提出疑問:為什么我們非得在虛擬機與主機設備之間添加“虛擬機管理程序”呢?
這個嘛,因為虛擬機本身擁有一套虛擬操作系統,而虛擬機管理程序則負責為虛擬機提供平臺以管理并運行這套訪客操作系統。如此一來,主機計算機就能夠為運行于其上的各虛擬機分配共享資源了。
虛擬機原理示意圖
如大家所見,虛擬機會將虛擬硬件、內核(即操作系統)以及用戶空間打包在新虛擬機當中。
容器與提供硬件虛擬化機制的虛擬機不同,容器通過對“用戶空間”的抽象化處理提供操作系統層級的虛擬化機制。通過對容器進行分解,大家將可以非常清晰地理解其中含義。
出于各種考量與需求,容器在外觀上與虛擬機非常相似。舉例來說,二者皆擁有專有處理空間、能夠作為root執行命令、提供專有網絡接口與IP地址、允許定制化路由及iptable規則,且可啟動文件系統等等。
容器與虛擬機間的最大區別在于,各容器系統共享主機系統的內核。
容器原理示意圖
以上示意圖顯示了容器如何對用戶空間進行打包,而不像虛擬機那樣同樣對內核或者虛擬硬件進行打包。每套容器都擁有自己的隔離化用戶空間,從而使得多套容器能夠運行在同一主機系統之上。我們可以看到全部操作系統層級的架構都可實現跨容器共享。惟一需要獨立構建的就是二進制文件與庫。正因為如此,容器才擁有極為出色的輕量化特性。
Docker的功能定位Docker為基于Linux容器的開源項目,其利用Linux內核中的各項功能——例如命名空間與控制組——以在操作系統之上創建容器。
容器概念并不是什么新鮮事物; 谷歌公司多年來一直在使用自己開發的容器技術。其它Linux容器技術方案還包括Solaris Zones、BSD jails以及LXC,且其都已經擁有多年的發展歷史。
那么為什么Docker的出現會快速吸引到技術業界的注意?
易用性: Docker能夠為潛在受眾帶來出色的易用性——開發者、系統管理員以及架構師等等——從而幫助其充分利用容器技術優勢以快速構建并測試可移植應用程序。每個人都可以在自己的筆記本上打包應用程序,并將其直接運行在任何公有云、私有云甚至是裸機之上。其座右銘是:一次構建,隨處運行。
速度: Docker容器具備輕量化與高速特性。由于容器本身屬于運行在內核之上的沙箱環境,因為其對資源的需求量極低。大家可以在數秒鐘內完成容器的創建與運行,而虛擬機則由于需要引導完整的虛擬操作系統而耗費更多時間。
Docker Hub: Docker用戶還能夠享受由Docker Hub帶來的豐富生態系統支持,我們可以將其理解成“Docker鏡像的應用商店”。Docker Hub提供成千上萬由社區開發的公共鏡像,且可立即加以使用。我們可以輕松根據需要搜索到合適的鏡像,將其提取并稍加修改即加以使用。
模塊性與可擴展性: Docker允許我們輕松將應用程序的功能拆分成多個獨立容器。舉例來說,我們可以將自己的Postgres數據庫運行在一套容器當中,并將Redis服務器運行在另一容器內,而Node.js也擁有自己的容器系統。在Docker的幫助上,大家能夠輕松將這些容器對接起來以創建完整的應用程序,這就讓未來的規模伸縮或者組件更新得以通過相互獨立的方式完成。
最后但同樣重要的是,Docker鯨魚實在是太惹人喜愛了~
Docker基本概念現在我們對Docker有了宏觀印象,下面具體對其組件進行解讀:
Docker EngineDocker Engine屬于Docker的運行層。這是一套輕量化運行時及工具組合,負責管理容器、鏡像、構建 等等。它以原生方式運行在Linux系統之上,并由以下元素構成:
Docker Daemon,運行在主機計算機之上。
Docker Client,負責與Docker Daemon通信以執行命令。
REST API,用于同Docker Daemon遠程交互。
Docker Client正是我們作為最終用戶的通信對象。我們可以將其視為Docker的UI。
我們進行的一切操作都將直接接入Docker Client,再由其將指令傳遞至Docker Daemon。
Docker Daemon直接將執行命令發送至Docker Client——例如構建、運行以及分發等等。Docker Daemon運行在主機設備之上,但作為用戶,我們永遠不會直接與該Daemon進行通信。Docker Client也可以運行在主機設備上,但并非必需。它亦能夠運行在另一臺設備上,并與運行在目標主機上的Docker Daemon進行遠程通信。
DockerfileDockerfile是我們編寫指令以構建Docker鏡像的載體。這些指令包括:
RUN apt-get y install some-package:安裝某軟件包
EXPOSE 8000: 開放端口
ENV ANT_HOME /usr/local/apache-ant:傳遞環境變量
類似的指令還有很多。一旦設置了Dockerfile,大家就可以利用docker build命令來構建鏡像了。下面來看Dockerfile示例:
示例Dockerfile
鏡像屬于只讀模板,大家可以借此配合Dockerfile中的編寫指令集進行容器構建。鏡像定義了打包的應用程序以及其相關依賴。這些依賴就好像是其啟動時需要運行的進程。
Docker鏡像利用Dockerfile實現構建。Dockerfile中的每條指令都會在鏡像中添加一個新的“層”,這些層則表現為鏡像文件系統中的一個分區——我們可以對其進行添加或者替換。層概念正是Docker輕量化的基礎。Docker利用一套Union File System建立起這套強大的結構:
Union File SystemDocker利用Union File System以構建鏡像。大家可以將Union File System視為一套可堆疊文件系統,這意味著各文件系統中的文件與目錄(在Docker中被稱為分支)可以透明方式覆蓋并構成單一文件系統。
覆蓋分支內的各目錄內容擁有同樣的路徑,并將被視為單一合并目錄,這就避免了需要為每個層分別創建副本的麻煩。相反,這些目錄可調用特定指針以指向同樣的資源; 當特定層需要進行修改時,其會分別創建修改前與修改后的本地副本。通過這種方式,文件系統表現出可寫入特性,但其實際上并未接受任何寫入操作。(換言之,這是一套‘寫入即復制’系統。)
分層系統擁有兩大核心優勢:
無重復數據: 分層機制使得我們在使用鏡像創建并運行新容器時無需復制完整的文件集,從而保證Docker容器實例擁有良好的運行速度與低廉的資源成本。
層隔離: 變更操作速度很快——當我們對鏡像進行變更時,Docker只需要對進行了變更的層進行廣播。
Volumes屬于容器中的“數據”部分,會在容器創建時進行初始化。Volumes機制允許我們持久保留并共享容器數據。數據卷 獨立于默認Union File System之外,且作為普通目錄及文件存在于主機文件系統當中。因此即使是在對容器進行銷毀、更新或者重構時,數據卷仍然不受影響。當我們需要對某一數據卷進行更新時,直接加以變更即可。(作為另一項優勢,數據卷還能夠在不同容器之間進行共享與復用。)
Docker容器如上所述,Docker容器將一款應用程序的軟件打包在單一環境當中,同時包含全部運行必需的要素。其中包括操作系統、應用程序代碼、運行時、系統工具、系統庫等等。Docker容器由Docker鏡像構建而成。由于鏡像存在只讀屬性,因此Docker會在鏡像在只讀文件系統之上添加一套讀取-寫入文件系統以實現容器創建。
另外,在創建容器時,Docker還會創建一套網絡接口以幫助容器同本地主機通信、對接可用IP地址并執行用戶在定義鏡像時所執行的進程以運行應用程序。
在成功創建了一套容器之后,我們隨后可以將其運行在任何環境當中,而不必再做任何變更。
打開容器,我們會發現其中包含大量活動組件。容器的實現機制一直令我感到驚訝而好奇,特別是考慮到容器不存在任何抽象的基礎設施邊界。在閱讀了大量材料之后,我將結合自己的理解為大家進行講解:)
“容器”這一術語其實只是個抽象概念,用于表述多種不同的相關特性,而其與原詞“container”的另一含義“集裝箱”有著千絲萬縷的聯系。下面就來一起了解:
1) 命名空間
命名空間為容器提供對應的底層Linux系統視圖,即限制容器的查看與訪問范疇。當我們運行一套容器時,Docker會創建多個命名空間供特定容器使用。
Docker會在內核中使用多種不同類型的命名空間,例如:
NET: 為容器提供獨特的系統網絡堆棧視圖(例如自有網絡設備、IP地址、IP路由表、/proc/net目錄、端口編號等等)。
PID: PID代表進程ID。如果大家曾經在命令行中運行過ps aux以檢查當前系統正在運行的進程,就會發現其中一欄名為“PID”。PID命名空間為容器提供其能夠查看與交互的進程范圍,其中包括獨立的init(PID 1),其屬于“所有進程的元祖”。
MNT: 為容器提供獨特的系統“mounts”視圖。這樣不同mount命名空間內的進程就將擁有彼此不同的文件系統結構。
UTS: UTS代表UNIX分時系統。它允許某一進程識別系統身份(例如主機名稱或者域名等)。UTS允許容器擁有不同于其它容器以及主機系統的主機名稱與NIS域名。
IPC: IPC代表進程間通信。IPC命名空間負責對運行在每套容器內的進程進行IPC資源隔離。
USER: 此命名空間用于對每套容器內的用戶進行隔離。其允許各容器擁有不同的uid(即用戶ID)與gid(組ID)視圖區間,并將其與主機系統進行比對。這樣一來,某一進程的uid與gid在用戶命名空間之內與之外即有所不同,這也使得該進程能夠在不影響容器內root權限的情況下,撤銷同一用戶在容器外的權限。
Docker將這些命名空間結合起來以隔離并創建容器。下面要講的則是控制組。
2) 控制組
控制組(也被稱為cgroups)屬于Linux內核中的一項功能,用于對一組進程的資源使用量(包括CPU、內存、磁盤I/O以及網絡等)進行隔離、排序與計數。這意味著cgroup能夠確保Docker容器只使用其必需的資源——并在必要情況下設置其所能使用的資源上限。另外,cgroups還能夠確保單一容器不至于占用太多資源并導致整體系統陷入癱瘓。
最后要說明的是Union文件系統:
3) 隔離化Union file system:
我們在之前的Docker鏡像章節中已經解釋過了:)
這就是關于Docker容器的全部內容了(當然,實現細節才是最麻煩的環節——例如如何管理不同組件間的交互)。
Docker的未來:Docker與虛擬機將并生共存盡管Docker已經開始逐步成為主流,但我認為它不太可能對虛擬機造成真正的威脅。容器將繼續發展壯大,但虛擬機也仍然擁有適合自己的生存空間。
舉例來說,如果我們需要在多臺服務器上運行多款應用程序,那么最理想的辦法就是使用虛擬機。在另一方面,如果我們需要運行同一應用程序的多套副本,那么Docker則擁有更多具體優勢。
另外,盡管容器允許我們將應用程序拆分成多個功能組件,但這種分散化趨勢意味著我們需要管理更多功能部件,即帶來更為復雜的控制與協調任務。
安全同時也是Docker容器需要解決的一大難題——由于各容器共享同一套內核,因此不同容器之間的屏障非常薄弱。與只需要調用主機虛擬機管理程序的虛擬機方案不同,Docker容器需要向主機內核發出系統調用,而這會帶來更龐大的攻擊面。出于安全性的考量,很多開發人員可能更傾向于選擇虛擬機——其由抽象化硬件進行隔離,從而顯著提升了彼此交互的難度。
當然,安全性與管理等難題必將隨著容器在生產環境下的進一步普及而得到解決。就目前來講,關于容器與虛擬機孰優孰劣的議題已經成為開發人員與運維人員間的日常爭論素材。
最后到這里,希望大家已經擁有了關于Docker的必要知識,也祝愿各位早日將Docker引入自己的日常工作。
當然,如果大家在文章中發現了什么謬誤,也歡迎在評論欄中做出說明。感謝大家,小數與你下次再見!
原文鏈接:https://medium.freecodecamp.com/a-beginner-friendly-introduction-to-containers-vms-and-docker-79a9e3e119b#.sl2xp8tiv
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/26551.html
摘要:二月份,微軟正式加入支持的行列,宣布容器服務支持。去年月,在亞馬遜彈性容器服務首次亮相。是年的最后一次重大更新,于月日正式推出。值得注意的公告包括亞馬遜網絡服務于八月份以白金會員最高級別加入了。 2017年的云計算市場,有一個領域獲得了空前的關注 -- Kubernetes。 Kubernetes可以追溯到2014年,當時Google公開發布了該項目的開源代碼。2017年,Kubern...
摘要:二月份,微軟正式加入支持的行列,宣布容器服務支持。去年月,在亞馬遜彈性容器服務首次亮相。是年的最后一次重大更新,于月日正式推出。值得注意的公告包括亞馬遜網絡服務于八月份以白金會員最高級別加入了。 2017年的云計算市場,有一個領域獲得了空前的關注 -- Kubernetes。 Kubernetes可以追溯到2014年,當時Google公開發布了該項目的開源代碼。2017年,Kubern...
摘要:響應一般由三個部分組成由一個數字和文字組成的狀態碼,用來顯示請求是成功還是失敗響應頭,包含服務器類型,日期時間,內容類型和長度等響應體,也就是響應正文。獲得形式的相應數據。和以數字和文本形式返回狀態碼。 學習目錄: AJAX基礎 PHP與AJAX JSON格式 jQuery中的AJAX 個人網站原創鏈接地址:不足之處歡迎留言...逃... showImg(https://segm...
摘要:響應一般由三個部分組成由一個數字和文字組成的狀態碼,用來顯示請求是成功還是失敗響應頭,包含服務器類型,日期時間,內容類型和長度等響應體,也就是響應正文。獲得形式的相應數據。和以數字和文本形式返回狀態碼。 學習目錄: AJAX基礎 PHP與AJAX JSON格式 jQuery中的AJAX 個人網站原創鏈接地址:不足之處歡迎留言...逃... showImg(https://segm...
閱讀 2562·2021-09-02 15:40
閱讀 1565·2019-08-30 15:54
閱讀 1079·2019-08-30 12:48
閱讀 3398·2019-08-29 17:23
閱讀 1046·2019-08-28 18:04
閱讀 3664·2019-08-26 13:54
閱讀 606·2019-08-26 11:40
閱讀 2390·2019-08-26 10:15