|
說(shuō)到容器,這個(gè)概念現(xiàn)在非常火;實(shí)際上,在IT領(lǐng)域內(nèi)各種技術(shù)一直是逐步迭代演進(jìn)的,而每一次技術(shù)革新,正是從發(fā)現(xiàn)問題開始。 問題一:windows系統(tǒng)方面 先從大家用的windows說(shuō)起。我們經(jīng)常有這樣的操作,打開一個(gè)word進(jìn)行文檔編輯,然后又打開了另外一個(gè)程序的安裝包setup。Ok,這樣我們可以簡(jiǎn)單認(rèn)為開了兩個(gè)windows進(jìn)程,一個(gè)word進(jìn)程,一個(gè)setup進(jìn)程,那么可能存在的問題: 第一: 兩個(gè)程序可以訪問相同的資源,比如C盤上的數(shù)據(jù);在編輯文檔時(shí),setup進(jìn)程占用cpu過(guò)高,從而影響了編輯文檔的體驗(yàn)。 第二:
Window里有個(gè)叫注冊(cè)表的東西,這個(gè)被搞亂會(huì)帶來(lái)很多麻煩。而setup如果設(shè)計(jì)兼容性不好,就有可能把注冊(cè)表搞亂. 第三: 對(duì)于開發(fā)者而言,如果寫這兩個(gè)程序的人或團(tuán)隊(duì)屬于不同機(jī)構(gòu)的,那么就有可能產(chǎn)生配置沖突或兼容性的問題。
問題二:linux系統(tǒng)方面 linux系統(tǒng)
我們?cè)賮?lái)看一下linux系統(tǒng): 首先: 我們知道linux系統(tǒng)有很多發(fā)行版本,比如centos、ubuntu等。我們的應(yīng)用有app1 for centos,也有app2 for ubuntu的,那現(xiàn)在我需要在一個(gè)OS里能跑app1和app2,怎么辦? 其次: 對(duì)于app1和app2的開發(fā)者需要編譯出不同發(fā)行版的應(yīng)用程序:for centos、for ubuntu等,如何實(shí)現(xiàn)? 最后: 對(duì)于開發(fā)者而言,一個(gè)程序?qū)懞脺y(cè)試過(guò)后,在最終的地用戶環(huán)境里可能會(huì)產(chǎn)生環(huán)境不匹配而導(dǎo)致運(yùn)行異常的問題,如何解決?
如何解決上述問題? 一個(gè)自然的想法就是“隔離”+”運(yùn)行環(huán)境打包”。把各個(gè)程序或app及相應(yīng)的運(yùn)行環(huán)境打包交付成鏡像,這樣既可以避免環(huán)境兼容的問題,又可以互補(bǔ)干擾和破壞。那么在一臺(tái)機(jī)器上同時(shí)運(yùn)行各個(gè)打包交付的鏡像時(shí),就需要把各個(gè)鏡像隔離加載運(yùn)行才能保證各個(gè)app的運(yùn)行環(huán)境獨(dú)立而不沖突。這里大家自然就會(huì)想到虛擬機(jī),沒錯(cuò),虛擬機(jī)可以做這樣的事情,每個(gè)鏡像就是一個(gè)虛擬機(jī)文件,虛擬機(jī)的優(yōu)勢(shì)顯而易見。但是我們現(xiàn)在只是希望在一臺(tái)機(jī)器上高效運(yùn)行多個(gè)程序,那么用虛擬機(jī)的方式缺點(diǎn)也很明顯: 1.每個(gè)app鏡像里需要包含一個(gè)OS,體積過(guò)大; 2.一個(gè)機(jī)器運(yùn)行多個(gè)不同環(huán)境的app需要多個(gè)OS虛擬機(jī),管理和運(yùn)行的效率成問題。
我們看到,這里的主要矛盾是為了運(yùn)行不同環(huán)境的app要把OS也加進(jìn)來(lái)作為支撐環(huán)境,那么為了進(jìn)一步容易管理和提升運(yùn)行效率,能不能把OS這一層精簡(jiǎn)呢? 答案是可以,這就是容器要做的事情,精簡(jiǎn)OS這一層。 精簡(jiǎn)OS層 精簡(jiǎn)OS這一層,各個(gè)app執(zhí)行環(huán)境共享OS是一個(gè)有效的方法。我們先看看linux為什么能做到這一點(diǎn)。 實(shí)際上現(xiàn)在的linux可以理解為兩部分,一是內(nèi)核,一是發(fā)行環(huán)境。比如我們說(shuō)的centos,ubuntu,redhat等,就是指的發(fā)行環(huán)境。大家都在相同的linux內(nèi)核的外圍發(fā)行自己的管理執(zhí)行程序,各個(gè)發(fā)行版本就是目前的centos,ubuntu等,這時(shí)候解決方法就來(lái)了:提供多個(gè)發(fā)行環(huán)境共享一個(gè)linux內(nèi)核的功能。
好,這時(shí)候容器的概念就出來(lái)了。linux容器可以理解為多個(gè)發(fā)行環(huán)境共享一個(gè)內(nèi)核,因此各容器可以有不同的發(fā)行環(huán)境(如centos,ubuntu等),但只有一個(gè)共同的內(nèi)核,所以你不能啟動(dòng)一個(gè)其它內(nèi)核的運(yùn)行環(huán)境(如windows)。如果你需要運(yùn)行一個(gè)centos環(huán)境的容器和一個(gè)windows環(huán)境的容器,這時(shí)你需要的就是虛擬機(jī)了,而不是容器,或者說(shuō)需要帶有虛擬機(jī)內(nèi)核功能的容器了。再就是你的發(fā)行環(huán)境里需要的內(nèi)核版本功能比容器共享內(nèi)核版本功能高也會(huì)有問題,那么就需要升級(jí)你的共享內(nèi)核。說(shuō)簡(jiǎn)單了容器就是共享OS內(nèi)核的隔離支撐環(huán)境。
linux容器核心功能
我們來(lái)來(lái)看看linux容器的基本核心功能:
1.文件系統(tǒng)隔離 每個(gè)容器運(yùn)行在完全獨(dú)立的根文件系統(tǒng)里。
2.網(wǎng)絡(luò)隔離 每個(gè)進(jìn)程容器在自己的網(wǎng)絡(luò)命名空間里,擁有自己的虛擬接口和網(wǎng)絡(luò)地址。
3.資源隔離 為每個(gè)進(jìn)程容器分配不同系統(tǒng)資源,如cpu,mem,io等。 windows容器價(jià)值 再看看windows,上述的三點(diǎn)同樣需要,不同的是大家都知道windows里有個(gè)注冊(cè)表,這個(gè)對(duì)windows而言非常重要,因此windows的容器對(duì)這個(gè)問題自然不能回避,那么windows容器是如何解決這個(gè)問題的呢? Windows有一個(gè)主機(jī)注冊(cè)表,容器里的注冊(cè)表繼承它,但修改時(shí)容器自己保存了自己對(duì)注冊(cè)表的修改部分,那么容器里把注冊(cè)表改亂了也不影響到host和其他容器,進(jìn)一步Windwos里用jobobject來(lái)限制容器的資源使用,而linux使用cgroup來(lái)限制容器的資源使用,限于篇幅這里就不再詳述了。
我們要使用容器,自然就不能回避容器的設(shè)計(jì)生成過(guò)程,而生成之后就涉及到加載運(yùn)行和管理,那么今天我們就從設(shè)計(jì)交付和架構(gòu)這兩個(gè)角度來(lái)說(shuō)一下容器。
設(shè)計(jì)交付運(yùn)行角度 簡(jiǎn)述 Docker Image的設(shè)計(jì)者按Dockerfile的語(yǔ)法規(guī)則進(jìn)行Docker Image的設(shè)計(jì)描述,描述完成后通過(guò)build命令生成Docker Image; 交付測(cè)試者時(shí),測(cè)試者只需基于Docker Image進(jìn)行加載測(cè)試即可。 使用過(guò)程 我們看容器的好處很多,那么使用容器的過(guò)程是怎樣的呢?
首先,不能回避的是容器的設(shè)計(jì),也就是用戶用自己的需要設(shè)計(jì)容器。這里我們先看看傳統(tǒng)的編譯型語(yǔ)言的使用過(guò)程:一個(gè)程序員先寫好代碼,然后通過(guò)編譯器把代碼編譯成機(jī)器指令,并按一定的系統(tǒng)規(guī)則組織起來(lái)形成執(zhí)行文件 ( 如Windows里的exe文件),然后交付給測(cè)試者,測(cè)試者測(cè)試完成通過(guò)后交付給使用者,使用者直接執(zhí)行這個(gè)文件,而不用關(guān)心代碼的設(shè)計(jì)編譯和測(cè)試過(guò)程。
對(duì)應(yīng)容器而言,也有個(gè)設(shè)計(jì)編譯和測(cè)試使用過(guò)程;在容器設(shè)計(jì)過(guò)程有一個(gè)叫Dockerfile的東西,這個(gè)文件就相當(dāng)于用戶Docker的設(shè)計(jì),在Dockerfile完成后build命令可以理解為編譯過(guò)程,實(shí)際上就是通過(guò)Dockerfile的描述生成Docker鏡像Image,然后把鏡像交付給測(cè)試者,測(cè)試者測(cè)試通過(guò)后把鏡像提交給使用者。其對(duì)應(yīng)的階段表格為:
上述表格可以理解為通過(guò)描述文件Dockerfile生成了鏡像文件Docker Image,加載Docker Image運(yùn)行就形成了動(dòng)態(tài)進(jìn)程容器Container。 一旦加載執(zhí)行起來(lái),容器進(jìn)程的行為就需要跟Linux 內(nèi)核進(jìn)行交互了。容器進(jìn)程基于Linux內(nèi)核的支持,那么把這個(gè)因素考慮進(jìn)去后我們可以把圖畫成這樣。
從圖上看到Container進(jìn)程通過(guò)Libcontainer來(lái)進(jìn)行跟Linux內(nèi)核的交互,由于新版本的Docker不支持LXC了,因此只列了Libcontainer。Container執(zhí)行需要Linux內(nèi)核的支持,這里為簡(jiǎn)單起見只說(shuō)一下兩個(gè)基礎(chǔ)的功能,空間的隔離和資源的限制。 空間隔離 空間的隔離就是用了Linux 的Namespaces,也就是名字空間,這個(gè)功能的基本作用就是隔離,比如兩個(gè)用戶u1和u2,在不同的Namespace下運(yùn)行是互相不可見的,一個(gè)具體的例子是u1的進(jìn)程PID和u2的進(jìn)程PID可以是相同的,如果是常規(guī)進(jìn)程,那么同一個(gè)OS下兩個(gè)進(jìn)程PID是不相同的。 資源限制 資源限制用了Linux內(nèi)核的Cgroups,此功能是用來(lái)限制每個(gè)容器進(jìn)程對(duì)資源使用量的,比如CPU,內(nèi)存,IO等,這樣避免一個(gè)容器進(jìn)程占用資源過(guò)大而使其它資源進(jìn)程受到影響。
有了Namespaces和Cgroups這兩個(gè)非?;A(chǔ)的重要功能,空間的隔離使各個(gè)容器進(jìn)程有了接近虛擬機(jī)的獨(dú)立性,資源的限制使各個(gè)容器進(jìn)程有了運(yùn)行資源的”平等性”,這樣基于容器的應(yīng)用就具備了接近虛擬機(jī)的一些基本特性,同時(shí)看到容器實(shí)際上是強(qiáng)依賴Linux內(nèi)核功能的,這一點(diǎn)上跟虛擬機(jī)大家各自的OS或內(nèi)核獨(dú)立又很大的不同,比如說(shuō)內(nèi)核的Bug和漏洞都會(huì)影響到各個(gè)容器進(jìn)程,這些需要篇幅,這里就先不展開了。
這里看到容器進(jìn)程的運(yùn)行是依賴Linux內(nèi)核的,那么這里就不能回避操作系統(tǒng)了,那么問題就來(lái)了:用什么樣的操作系統(tǒng)來(lái)支持容器的運(yùn)行?CentOS,Ubuntu是現(xiàn)在大家常用的,這里提一下CoreOS和Rancher OS,這兩系統(tǒng)非常合適容器的支撐。為什么這么說(shuō)呢?
我們已經(jīng)知道容器共享內(nèi)核的運(yùn)行環(huán)境,這個(gè)操作系統(tǒng)有了基本的內(nèi)核功能就可以了,實(shí)際上相對(duì)操作系統(tǒng)而言可以做得非常小,當(dāng)然也可以自己拿通用的操作系統(tǒng)進(jìn)行裁減,但并不是最優(yōu)的方案,之所以提到CoreOS和Rancher OS,這兩個(gè)OS不但體積小(Rancher OS 29兆左右,CoreOS 200多兆),而且針對(duì)容器的支持做了很多調(diào)整。比如Rancher OS,里面進(jìn)程皆容器,System Docker 起了系統(tǒng)運(yùn)行的各種必備功能,然后起了User Docker(Container)。 所以CoreOS和Rancher OS可以認(rèn)為是為容器而生的。
Docker 架構(gòu)
現(xiàn)在我們從另一個(gè)角度看一下容器:對(duì)于Docker的運(yùn)行,是一個(gè)典型的客戶機(jī)服務(wù)器C/S模型或架構(gòu),如下面的圖:
圖里列了三個(gè)常用的基本命令:build(建鏡像),pull(從倉(cāng)庫(kù)拉鏡像),run(運(yùn)行Docker),不同的顏色代表了不同的命令執(zhí)行的流程。我們看到所有的client命令都提交給了Docker Daemon, Docker Daemon 負(fù)責(zé)鏡像(Image), 容器進(jìn)程(Container),倉(cāng)庫(kù)(Registry)的協(xié)調(diào)和管理,Docker Daemon 里有Docker Engine和Docker Job的概念。 對(duì)于深入理解Docker Daemon,建議看一下Docker的Golang源代碼,想省時(shí)間可以從MainDaemon或NewDaemon看起。
上述角度都是基于單個(gè)節(jié)點(diǎn)上的Docker(container)而言的,當(dāng)有多個(gè)主機(jī)上運(yùn)行Docker時(shí),多節(jié)點(diǎn)上的Docker管理和協(xié)調(diào)就需要新的工具了,也可以理解為Docker集群的管理,有Swarm,Rancher,Kunbernets等,這里先不展開了。 |
|
|
來(lái)自: magicvuyoo9k7b > 《容器、虛擬化》