Docker與容器快速入門

【雲計算】Docker與容器快速入門





Docker之風席捲全球,但很多人覺得docker入門確實不太容易,其原因在於很多知識點上沒準備好,在docker解決了什麼問題、怎麼解決的、用什麼技術解決的都還沒想清楚的時候就去探索docker組件原理,自然會犯迷糊,與其迷茫地寸步難行,不如先看看知識準備,入門了繼續進行研究。 
Docker是一種在Linux容器裏運行應用的開源工具,一種輕量級的虛擬機。除了運行應用,Docker還提供了一些工具,藉助Docker Index或自己託管的Docker註冊表對進行了集裝箱化處理的應用進行分發,從而簡化複雜應用的部署過程。 
本文將介紹如今在部署複雜系統時公司所面臨的挑戰,Docker怎樣有效地解決這個問題,在宏觀上對docker項目進行介紹,並發表一些自己理解的看法。之後的文章會慢慢深入,對docker模塊逐個剖析。

0x01 什麼是容器

容器指用來包裝或裝載物品的貯存器(如箱、罐、壇)或者成形或柔軟不成形的包覆材料。在web環境中,容器是應用服務器中位於組件和平臺之間的接口集合。在docker級別,容器可以理解爲一個邊界,邊界裏面是所想運行的各種程序,邊界外面是基礎環境,邊界裏外儘量少的耦合。 
這裏寫圖片描述

0x02 容器的作用

服務器應用的部署已經越來越複雜了。把幾個Perl腳本拷貝到正確目錄就完成服務器應用的安裝,這種時代已經一去不復返了。如今的軟件有很多類型的需求: 
對已安裝軟件和庫的依賴(“Python版本高於2.6.3,使用Django 1.2”) 
依賴於正在運行的服務(“需要一個MySQL 5.5數據庫和一個RabbitMQ隊列”) 
依賴於特定的操作系統(“在64位的Ubuntu Linux 12.04上構建、測試”) 
資源需求: 
最小的可用內存(“需要1GB的可用內存”) 
能綁定特定的端口(“綁定80和443端口”) 
我們來看一個相對簡單的應用的部署:Wordpress。Wordpress的安裝通常要求: 
這裏寫圖片描述 
在服務器上部署、運行這樣一個系統,我們可能會遇到下面的問題和挑戰: 
隔離性:如果我們已經在這個服務器上部署了不同的網站,已有的網站只能在nginx上 運行,而Wordpress依賴於Apache,這時我們就會有麻煩:它們都監聽80端口。同時運行兩個網站是可以的,但需要調整配置(修改監聽端口), 設置反向代理等。庫級別也會出現類似的衝突,如果還要運行一個仍然依賴PHP4的老應用就會出問題,因爲Wordpress不再支持PHP4,同時運行 PHP4和PHP5則非常困難。運行在同一個服務器上的應用沒有互相隔離(在文件系統級別和網絡級別),所以它們可能會互相沖突。 
**安全性:**Wordpress的安全記錄並不是非常好。所以還是給它創建個沙箱,至少黑客入侵時不會影響其他運行的應用。 
升級、降級:升級應用一般會覆蓋現有文件。升級過程中會發生什麼?系統要關閉麼?如果升級失敗,或者不對該怎麼辦?我們怎樣快速回退到先前的版本? 
快照、備份:一旦所有的內容都設置好,就給系統創建一個“快照”,以便能備份快照,甚至能移到另一個服務器上再次啓動,或者拷貝到多個服務器上以備不時之需。 
重複性:系統出新版本之後,比較好的做法是先在測試基礎設施上自動部署並測試,然後再發布到生產系統。通常會利用諸如Chef、Puppet等 工具在服務器上自動安裝一堆包,等一切內容都就緒後,再在生產系統上運行相同的部署腳本。這在百分之九十九的情況下都沒有問題。但有百分之一的例外,在部 署到測試環境和生產環境之間的時間跨度裏,你依賴的包在包倉庫裏有了更新,而新版本並不兼容。結果生產環境的設置和測試環境不同,還有可能破壞生產系統。 假如沒有控制部署的每一個方面(例如託管自己的APT或YUM倉庫),持續在多個階段(比如測試、預演、生產環境)重複搭建出完全相同的系統就很困難。 
資源限制:如果我們的Wordpress耗費CPU資源,並佔用了所有的CPU週期,導致其他應用無法做任何事情怎麼辦?如果它用盡了全部可用的內存呢?或者瘋狂寫日誌阻塞磁盤呢?要是能限制應用的可用資源,比如CPU、內存和磁盤空間,就會非常方便。 
易於安裝:也許有Debian或CentOS包,抑或是能自動執行所有複雜步驟並安裝 Wordpress的Chef菜譜。但這些菜譜很難穩定下來,因爲它們需要考慮目標系統上可能的系統配置。很多情況下,這些菜譜只能在乾淨的系統上運行。 因此,你不太可能更換成自己的包或Chef菜譜。這樣的話,安裝就是個複雜的系統工程,而不是午休期間就能搞定的事情。 
易於移除:軟件應該能輕鬆、乾淨地移除,不留痕跡。但部署應用通常要調整已有的配置文件、設置狀態(MySQL數據庫的數據,日誌),完全移除應用也變得不那麼容易。 
那我們應該如何解決這些問題呢?

0x03 虛擬機VS容器-虛擬機解決方案

我們決定在單獨的虛擬機上運行獨立的應用,例如Amazon的EC2,大部分問題這時會迎刃而解: 
隔離性:在一個VM上安裝一個應用,應用是完全獨立的,除非它們攻入了對方的防火牆。 
重複性:用你喜歡的方式準備系統,然後創建一個AMI。你可以隨意實例化多個AMI實例。完全是可重現的。 
安全性:由於我們完全隔離,如果Wordpress遭到攻擊,其餘的基礎設施並不會受到影響——除非你沒有保管好SSH密鑰或者在哪裏都使用同一個密碼,但你應該不會這麼做吧? 
**資源限制:**VM會分配特定的CPU週期、可用內存和磁盤空間,沒有加價的話就不能超額。 
易於安裝:越來越多的應用能夠在EC2上運行,只要在AWS marketplace上點擊一個按鈕就能實例化應用。啓動只需要幾分鐘,就是這樣。 
易於移除:不需要某個應用了?銷燬VM。乾淨又方便。 
**升級、降級:**Netflix如何部署代碼裏提到,只需要在新VM上部署新版本,然後讓負載均衡器指向部署了新版本的VM。不過應用如果需要在本地保存狀態,這種方法就不是很好用了。 
快照、備份:點擊一個按鈕(或者調用一下API)就能獲得EBS磁盤的快照,快照會備份到S3中。 
完美! 
不過……我們有個新問題:虛擬機在兩個方面比較昂貴: 
金錢:你真的有那麼多錢爲每個應用啓動一個EC2實例?另外你能預測到需要多少個實例麼?如果你以後需要更多的資源,你需要停止VM進行升級——否則就要爲閒置資源白白付錢,直到真正用起來(除非你用能動態調整大小的Solaris Zones,比如Joyent上的)。 
時間:虛擬機相關的操作大多都很慢:啓動要幾分鐘,捕捉快照要幾分鐘,創建鏡像也需要幾分鐘。世界不停轉動,我們可沒有這種時間! 
我們能做得更好嗎?

0x04 虛擬機VS容器-容器解決方案

Docker是由公共PaaS提供商dotCloud的人發起的開源項目,於去年初發起。從技術角度來說,Docker(主要用Go語言編寫)試圖簡化兩種已有技術的使用: 
**LXC:**Linux容器,允許獨立進程在比普通Unix進程更高的隔離級別上運行。使用的技術術語是集裝箱化:一個容器裏運行一個進程。容器支持的隔離級別有: 
文件系統:容器只能訪問自己的沙箱文件系統(類似於chroot),否則要專門掛載到容器的文件系統中才能訪問。 
用戶名字空間:容器有自己的用戶數據庫(也就是容器的root不等於主機的root賬戶)。 
進程名字空間:只有容器裏的進程纔是可見的(ps aux的輸出會非常簡潔)。 
網絡名字空間:每個容器都有自己的虛擬網絡設備和虛擬IP(因此它可以綁定任意端口,不用佔用主機端口)。 
AUFS:高級多層的統一文件系統,可用來創建聯合、寫時拷貝的文件系統。 
Docker可以安裝在任何支持AUFS和內核版本大於等於3.8的Linux系統上。但從概念上來說它並不依賴於這些技術,以後也可以和類似的技術一起運行,例如Solaris的Zones或BSD jails,並將ZFS作爲文件系統。不過目前只能選擇Linux 3.8+和AUFS。

0x05 爲什麼是Docker

Docker非常輕量。啓動VM是個大動作,需要佔用大量內存;而啓動Docker容器只耗費很少的CPU和內存,並且非常快。幾乎和啓動一個常規進程沒什麼區別。不僅運行容器快,構建鏡像、捕獲文件系統的快照也很快。 
它運行在已經虛擬化過的環境中。也就是說,你可以在EC2實例、Rackspace VM或VirtualBox裏運行Docker。事實上,在Mac和Windows上使用Docker的首選方式是使用Vagrant。 
Docker容器能移植到任何運行Docker的操作系統上。無論是Ubuntu還是CentOS,只要Docker運行着,你的容器就能運行。 
讓我們回到前面的部署、操作問題列表,看看Docker是怎麼解決的: 
隔離性:Docker在文件系統和網絡級別隔離了應用。從這個意義上來講很像在運行”真正的“虛擬機。 
重複性:用你喜歡的方式準備系統(登錄並在所有軟件裏執行apt-get命令,或者使用Dockerfile),然後把修改提交到鏡像中。你可以隨意實例化若干個實例,或者把鏡像傳輸到另一臺機器,完全重現同樣的設置。 
**安全性:**Docker容器比普通的進程隔離更爲安全。Docker團隊已經確定了一些安全問題,正在着手解決。 
**資源約束:**Docker現在能限制CPU的使用率和內存用量。目前還不能直接限制磁盤的使用情況。 
**易於安裝:**Docker有一個Docker Index,這個倉庫存儲了現成的Docker鏡像,你用一條命令就可以完成實例化。比如說,要使用Clojure REPL鏡像,只要運行docker run -t -i zefhemel/clojure-repl命令就能自動獲取並運行該鏡像。 
易於移除:不需要應用了?銷燬容器就行。 
升級、降級:和EC2 VM一樣:先啓動應用的新版本,然後把負載均衡器切換到新的端口。 
**快照、備份:**Docker能提交鏡像並給鏡像打標籤,和EC2上的快照不同,Docker是立即處理的。

0x06 Docker入門知識準備

Namespace定義與概念 
每個用戶實例之間相互隔離, 互不影響。 一般的硬件虛擬化方法給出的方法是VM,而LXC給出的方法是container,更細一點講就是kernel namespace。其中pid、net、ipc、mnt、uts、user等namespace將container的進程、網絡、消息、文件系統、UTS(“UNIX Time-sharing System”)和用戶空間隔離開。 
Cgroups定義與概念 
cgroups 實現了對資源的配額和度量。 cgroups 的使用非常簡單,提供類似文件的接口,在 /cgroup目錄下新建一個文件夾即可新建一個group,在此文件夾中新建task文件,並將pid寫入該文件,即可實現對該進程的資源控制。 groups可以限制blkio、cpu、cpuacct、cpuset、devices、freezer、memory、net_cls、ns九大子系 統的資源 
AUFS定義與概念 
AUFS (AnotherUnionFS) 是一種 Union FS, 簡單來說就是支持將不同目錄掛載到同一個虛擬文件系統下(unite several directories into a single virtual filesystem)的文件系統, 更進一步的理解, AUFS支持爲每一個成員目錄(類似Git Branch)設定readonly、readwrite 和 whiteout-able 權限, 同時 AUFS 裏有一個類似分層的概念, 對 readonly 權限的 branch 可以邏輯上進行修改(增量地, 不影響 readonly 部分的)。通常 Union FS 有兩個用途, 一方面可以實現不借助 LVM、RAID 將多個disk掛到同一個目錄下, 另一個更常用的就是將一個 readonly 的 branch 和一個 writeable 的 branch 聯合在一起,Live CD正是基於此方法可以允許在 OS image 不變的基礎上允許用戶在其上進行一些寫操作 
這裏寫圖片描述

0x07 Docker有哪些缺點

儘管Docker有助於系統的可靠部署,但它本身並不是個完全成熟的部署系統。它操作的是容器裏運行的應用。哪個容器安裝在哪個服務器上,以及如何啓動它們,則超出了Docker的範圍。 
同樣的,Docker也不處理跨多個容器(可能在多個物理服務器上,也可能在多個VM上)運行的應用。要讓容器互相通信,需要某些發現機制,來找出哪些IP和端口上的其他應用可用。這和跨常規虛擬機的服務發現非常相似。etcd等工具,或者其他的服務發現機制都能用來解決這個問題。

0x08 Docker未來發展

雖然Docker目前默認使用LXC和AUFS,但是Docker的核心思想本身,並不強制綁定這兩者,0.8版本已經可以使用BTRFS,而整個Docker框架也改成了插件式的架構,便於添加替換各個功能模塊 
這裏寫圖片描述

例如更多的Storage方案的支持,規避AUFS當前的問題,除了LXC以外更多的虛擬化方案等

0x09 總結

容器實質上是一個職責劃分的工具。Docker與容器不是等價的,docker是容器,但容器不僅僅指的是docker,docker爲容器的一個代表,個人理解的docker主要解決的問題爲如下兩方面 
1、不同層之間的依賴關係解耦;例如:安裝、移除、重複利用。如下圖中,container與Host OS和Server之間的解耦。 
2、同層之間資源隔離與資源限制;例如:端口、cpu搶佔,同服站點互不影響。下圖中App A與APP B之間的隔離,和APP各自的資源利用限制。 
這裏寫圖片描述 
容器解決的問題虛擬機已全部解決,爲什麼還需要容器docker呢?原因是虛擬機在架構上太重,在資源上有很多不必要的花費,在時間上啓動、創建鏡像、快照等消耗較長,在層次結構上虛擬機只具有一層封裝,將操作系統、服務、應用全部封裝,並不能靈活的拆卸與組裝,職責劃分並不明確。 
Docker略帶積木化色彩,將雜糅的運行環境積木化,用於更快更好的搭建和複用。

參考文檔

Docker容器http://www.infoq.com/cn/articles/docker-containers 
http://blog.csdn.net/colorant/article/details/20608157 
LXC 入門文章http://www.cnblogs.com/lisperl/archive/2012/04/15/2450183.html 
Docker核心技術預覽:http://www.infoq.com/cn/articles/docker-core-technology-preview


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