所屬技術領域:
雲原生
| 名詞定義|
容器運作時所需要的所有的檔案集合稱之為容器鏡像。
| 發展曆程|
2008年,以Google公司開發人員為主導實作的Linux Container(即LXC)功能在被merge到Linux核心中。LXC是一種核心級虛拟化技術,主要基于Namespaces和Cgroups技術,實作共享一個作業系統核心前提下的程序資源隔離,為程序提供獨立的虛拟執行環境,這樣的一個虛拟的執行環境就是一個容器。本質上說,LXC容器與現在的Docker所提供容器是一樣的。Docker也是基于Namespaces和Cgroups技術之上實作的,Docker的創新之處在于其基于Union File System技術定義了一套容器打包規範,真正将容器中的應用及其運作的所有依賴都封裝到一種特定格式的檔案中去,而這種檔案就被稱為鏡像(即image),原理見下圖(引自Docker官網):

圖1:Docker鏡像原理
自從2013年dotCloud公司(現已改名為Docker Inc)釋出Docker容器技術以來,到目前為止已經有四年多的時間了。這期間Docker技術飛速發展,并催生出一個生機勃勃的、以輕量級容器技術為基礎的龐大的容器平台生态圈。作為Docker三大核心技術之一的鏡像技術在Docker的快速發展之路上可謂功不可沒:鏡像讓容器真正插上了翅膀,實作了容器自身的重用和标準化傳播,使得開發、傳遞、運維流水線上的各個角色真正圍繞同一傳遞物,“test what you write, ship what you test”成為現實。
| 技術特點|
容器鏡像都是隻讀的,當容器啟動時,一個新的可寫層被加載到鏡像的頂部。
這一層通常被稱作“容器層”,“容器層”之下的都叫“鏡像層”
适用場景:
應用打包
制作過RPM、GEM等軟體包的同學可能很清楚,每一個軟體包依賴于哪個庫的哪個版本,
往往需要明确的寫在依賴清單裡。而依賴又往往分為編譯時依賴和運作時依賴。
在傳統的基礎設施環境下,為了保證所生成的軟體包在其它機器上可正常安裝且運作,
一般需要在打包之前建立個幹淨的虛拟機,或者手工建立個chroot環境,
然後在這個幹淨的環境下安裝安全各種依賴包,然後執行打包腳本。
生成軟體包以後,需要再建立一個幹淨的環境安裝、運作這個軟體包,來驗證是否符合預期。
這樣雖然也能完成打包工作,但至少有以下缺點:
耗時耗力
依賴關系容易漏掉,比如:在幹淨的環境中經過多次調試,把缺少的依賴包一個一個的裝上了,但最後寫spec檔案時卻忘記添加某個依賴,導緻下次打包時需要重新調試或者打包後軟體包無法使用等問題。
通過docker可以很好的解決打包問題。具體作法如下:
“幹淨的打包環境”很容易準備,docker官方提供的ubuntu、centos等系統鏡像天生就能作為純淨無污染的打包環境使用
Dockerfile本身能起到文檔固化的作用,隻要寫好Dockerfile,建立好打包鏡像,以後就能無限次重複使用這個鏡像進行打包
多版本混合部署
随着産品的不斷更新換代,一台伺服器上部署多個應用或者同一個應用的多個版本在企業内部非常常見。
但一台伺服器上部署同一個軟體的多個版本,檔案路徑、端口等資源往往會發生沖突,造成多個版本無法共存的問題。
如果用docker,這個問題将非常簡單。由于每個容器都有自己獨立的檔案系統,是以根本不存在檔案路徑沖突的問題;
對于端口沖突問題,隻需要在啟動容器時指定不同的端口映射即可解決問題。
更新復原
一次更新,往往不僅僅是應用軟體本身的更新,通過還會包含依賴項的更新。
但新舊軟體的依賴項很可能是不同的,甚至是有沖突的,是以在傳統的環境下做復原一般比較困難。
如果使用docker,我們隻需要每次應用軟體更新時制作一個新的docker鏡像,更新時先停掉舊的容器,
然後把新的容器啟動。需要復原時,把新的容器停掉,舊的啟動即可完成復原,整個過程各在秒級完成,非常友善。
多租戶資源隔離
資源隔離對于提供共享hosting服務的公司是個強需求。
如果使用VM,雖然隔離性非常徹底,但部署密度相對較低,會造成成本增加。
docker容器充分利用linux核心的namespaces提供資源隔離功能。
結合cgroup,可以友善的設定某個容器的資源配額。
既能滿足資源隔離的需求,又能友善的為不同級别的使用者設定不同級别的配額限制。
但在這種應用場景下,由于容器中運作的程式對于hosting服務提供方來說是不可信的,
是以需要特殊的手段來保證使用者無法從容器中操作到主控端的資源(即:越獄,盡管這種問題發生的機率很小,但安全無小事,多一層防護肯定讓人更加放心)。
安全及隔離性加強方面,可考慮以下措施:
通過iptables阻斷從容器到所有内網IP的通信(當然如果需要也可以針對特定的IP/端口開放權限)2. 通過selinux或者apparmor限制某個容器所能通路的資源3. 對某些sysfs或者procfs目錄,采用隻讀方式挂載4. 通過grsec來加強系統核心5. 通過cgroup對記憶體、CPU、磁盤讀寫等資源進行配額控制6. 通過tc對每個容器的帶寬進行控制
另外我們在實際測試中發現系統的随機數生成器很容易因熵源耗盡而發生阻塞。
在多租戶共享環境下需要在主控端上啟用rng-tools來補充熵源。
這個應用場景下有很多工作是docker本身所不能提供的,并且實施起來需要關注的細節比較多。
為此我們提供了安全加強版docker管理平台,可完美解決以上問題。
需要的朋友可以通過csphere官網了解更多細節。
内部開發環境
在容器技術出現之前,公司往往是通過為每個開發人員提供一台或者多台虛拟機來充當開發測試環境。
開發測試環境一般負載較低,大量的系統資源都被浪費在虛拟機本身的程序上了。
docker容器沒有任何CPU和記憶體上的額外開銷,很适合用來提供公司内部的開發測試環境。
而且由于docker鏡像可以很友善的在公司内部分享,這對開發環境的規範性也有極大的幫助。
如果要把容器作為開發機使用,需要解決的是遠端登入容器和容器内程序管理問題。
雖然docker的初衷是為“微服務”架構設計的,但根據我們的實際使用經驗,
在docker内運作多個程式,甚至sshd或者upstart也是可行的。
這方面csphere也有成熟的産品及解決方案,歡迎感興趣的朋友試用回報。