Docker: 現在和未來
Docker – 迄今為止的故事
Docker是一種Linux容器工具集,它是為“構建(build)、交付(ship)和運行(運行)”分布式應用而設計的。作為DotCloud公司的開源項目,其首發版本的時間是2013年的3月份。該項目很快就受到歡迎,這也使得DotCloud公司將其品牌改為Docker(并最終將其原有的PaaS業務出售而專注在Docker上)。Docker 1.0在2014年6月發布,而且延續了之前每月發布一個版本的節奏。
其1.0版本標志著Docker公司認為Docker平臺已經足夠成熟,并可以被應用到產品中(公司及其合作伙伴們還提供了一些需要付費的支持選項)。每月的版本更新顯示出該項目仍在快速發展,比如增加新的特性,解決發現的問題。這個項目成功地將“交付”和“運行”解耦,這樣源自任意Docker版本的鏡像都可以和其它任意不同版本一起工作(前向和后向均可兼容),這就為Docker應用提供了穩定的基礎,以應對快速的變化。
Docker發展成最受歡迎的開源項目可能會被人看作是一種炒作,但其實這個結果還是有堅實的基礎來支撐的。Docker吸引了業界眾多知名大牌廠家的支持,其中包括亞馬遜(Amazon)、Canonical、CenturyLink、谷歌(Google)、IBM、 Microsoft、New Relic、Pivotal、Red Hat和VMware,這使得只要在有Linux的地方,Docker就幾乎隨處可用。除了這些大廠家,許多初創企業也圍繞著Docker來發展,或是將它們的發展方向和Docker更好地結合起來。所有這些合作伙伴(或大或小)驅動著核心項目和周邊生態系統的快速發展。
Docker利用了一些Linux核心工具,比如cGruops、命名空間和SELinux來支撐容器之間的隔離。起初Docker只是LXC容器管理子系統的前端,但它在0.9版本中引入了libcontainer,這個原生的Go語言庫提供了用戶空間和內核之間的接口。
Docker技術的簡要綜述
Docker容器是基于聯合文件系統(union file system)的,比如AUFS,利用它可以跨多個容器來共享一些組件,如操作系統鏡像和安裝的庫文件。這種分層的方式也被Dockerfile DevOps工具充分利用,這可以緩存那些已經成功完成的操作。這就省掉了那些安裝操作系統和應用程序依賴文件的時間,大幅度加速了測試周期。另外,在容器之間共享庫還能減少內存的占用。
Docker容器是從鏡像開始的,鏡像可以是本地創建的、本地緩存的,或者是從注冊庫中下載的。Docker公司運營著DockerHub公有注冊庫,上面有官方的數據倉庫,是為不同的操作系統、中間件和數據庫而創建的。組織和個人可以在Docker Hub上發布鏡像的公有庫,也可以將其注冊成私有庫。由于上傳的鏡像文件可以包含任何東西,所以Docker Hub提供了一種自動構建工具(之前被稱為“可信的構建”),鏡像構建于一個Dockerfile,它作為鏡像內容的清單。
容器和虛擬機的對比
Docker容器要比虛擬機有效率的多,這是因為它們可以共享內核和相關的庫。同樣的原因,容器所占用的內存也要比虛擬機少得多,雖然虛擬機利用了RAM的過度承諾技術(RAM overcommitment)。容器也減少了對存儲的占用,因為部署的容器會共享鏡像的底層。IBM的Boden Russel已經做了一個基準測試(benchmarking)來對比兩者的不同。
容器也表現出比虛擬機更低的系統負載,所以同樣的應用,在容器中相比在虛擬機中,性能通常會相當或者更好。IBM的研究者團隊發布了一個虛擬機和Linux容器性能對比的報告可以參考。
容器只是在隔離特性上要比虛擬機差,虛擬機可以使用ring-1特權的硬件隔離技術,如Intel的VT-d and VT-x。這種隔離技術可以防止虛擬機破出(breaking out)和彼此交互。容器沒有任何形式的硬件隔離,這使得它容易受到漏洞的利用。從Shocker(可對Docker進行概念攻擊)的驗證來看,Docker 1.0之前的版本都是很脆弱的。盡管利用Shocker,Docker在1.0版本中修復了一些特定的問題,但Docker的CTO Solomon Hykes仍然表示:“當我們感覺可以輕松地宣稱Docker打開箱(out-of-the-box)可以安全容納非受信的uid0程序(譯者注: root和超級用戶權限)時,我們一定會明言相告”。Hykes的話從另一方面承認仍然存在一些其他的漏洞和相關的風險,在容器變得可靠之前還有很多工作要做。
對于許多用戶案例,在容器和虛擬機二者之間選擇其一是種錯誤的二分法。Docker可以在虛擬機中運行地很好,這可以讓它應用在已有的虛擬化框架中,如私有云和公有云。同樣也有可能在容器中運行虛擬機,這有點像谷歌在它的云平臺中使用容器的方式。只要IaaS得到廣泛應用,并可按需提供虛擬機服務,那么就有理由期待未來數年容器和虛擬機的應用可以并存。還有一種可能,即將容器管理和虛擬化技術進行融合以提供一種兩全其美的方法:所以硬件信任錨微虛擬化實現支撐libcontainer能夠與Docker的工具鏈和生態系統的前端進行集成,而使用不同的提供了更好隔離性的后端。微虛擬技術(類似于Bromium的 vSentry和VMware的 Project Fargo)已經應用到桌面環境中為應用提供基于硬件的隔離,所以相同的方法可以使用到libcontainer上,作為Linux核心容器機制的替代技術。
“容器化”的應用
幾乎所有的Linux應用都可以運行在Docker容器里,并且對編程語言或架構的選擇沒有任何的限制。實際上僅有的限制在于從操作系統的角度來看容器被允許做什么。即使如此,也可以通過在特權模式下運行容器來降低限制,以大幅度地減少受到的控制(與此對應的是裝載到容器里的應用風險增加,并可能會導致對主機操作系統的損壞。)
容器從鏡像開始,反過來鏡像也可以從運行的容器中得到。從本質上說有兩種方法可以把應用置入到容器中-手動和Dockerfile。
手動構建
手動構建從啟動一個基礎操作系統的容器開始,然后通過交互式終端,用所選Linux相關的包管理器安裝應用程序及其依賴項(dependencies)。Zef Hemel在他的文章“使用Linux容器以支持便捷的應用部署”中提供了這個過程的細致描述。一旦應用完成安裝,新的容器就可以推送到注冊庫(比如Docker Hub)中或者被導出成一個tar文件。
Dockerfile
Dockerfile是對Docker容器創建過程進行腳本化的系統。每個Dockerfile詳細說明了開始的基礎鏡像,以及隨后一系列在容器中運行的命令和添加到容器中的文件。Dockerfile也可以說明容器對外的端口,啟動時的工作目錄和缺省執行的命令。用Dockerfile構建的容器可以象手動構建那樣被推送到注冊庫中或者導出成tar文件。Dockerfile也可以應用到Docker Hub的自動構建系統中,即在Docker公司的控制下,在系統中根據Dockerfile從頭構建鏡像,并且這個鏡像的源對于使用它的任何人都是可見的。
一個進程?
手動構建還是使用Dockerfile來構建鏡像,考慮的關鍵在于容器剛啟動時只能執行一個單進程。如果容器的服務目的比較單一,比如只運行一個應用服務器,那么運行單個進程就沒什么問題(一些爭論說容器本應該只包括一個進程)。對于那些希望在容器中運行多個進程的情況,管理進程(supervisor process)需要先啟動,這樣它可以接著孵化出其他期望的進程。此時容器中沒有初始的系統,所以任何事都要依賴systemd,不修改新興系統或類似系統都無法工作。
容器和微服務
全面描述使用微服務架構的哲理和益處已經超出了本文的范圍(InfoQ eMag: Microservices中有全面的闡述)。容器仍然是一種方便的方法來綁定和部署微服務的實例。
雖然目前微服務大規模的部署實例還是在(大量)虛擬機上,但容器提供了一種小規模部署的機會。容器具有共享的內存和針對操作系統的磁盤占用、通用代碼庫,這也意味著可以非常有效地一起部署多個版本的服務。
連接的容器
一些小的應用適合放在單個容器中,但許多情況下應用需要擴展到多個容器。Docker成功催生了一系列新的應用合成工具、編制工具以及平臺即服務實現。絕大多數努力的后面,是希望能簡化從一組相互連接的容器來創建應用的過程。很多工具在擴展、容錯、性能管理和部署資產的版本控制方面也提供了幫助。
連接性
Docker的網絡能力相當原始,容器中的服務對相同主機的其它容器是可見的,并且Docker可以映射端口到主機操作系統,使得服務在網絡中也是可見的。Libchan是Docker官方贊助的連接方法,它提供了Go語言的網絡服務庫,類似于channels。在libchan找到自己應用的道路之前,還是有空間留給第三方程序來提供一些補充性的網絡服務。例如,Flocker采用了基于代理的方法,這使得服務(連同底層的存儲)可以在主機間進行遷移。
合成
Docker有個原生的機制來連接容器,它所依賴的元數據可以被傳送到相關的容器中,這些元數據被用做環境變量和主機入口。類似Fig和geard這樣的應用合成工具,可以在單文件中表達這種依賴關系圖,這樣多個容器就可以互相配合成為一個系統。CenturyLink的Pannamax合成工具在底層采用了和Fig、geard相似的方法,但加入了基于Web的用戶接口,并且直接和GitHub進行了集成,這樣就可以分享合成后的應用了。
編制
編制系統包括Decking、New Relic公司的Centurion和谷歌公司的Kubernetes,它們的目標都是幫助實現容器的部署和它的生命周期管理。也有很多基于Apache Mesos系統(特別是它為應用長期運行設計的Marathon框架)的商業化實現(比如Mesosphere),它們可以和Docker一起使用。通過提供在應用需求和底層架構間的抽象(例如,需求表達為CPU核數和內存大小),編制工具提供了兩者之間的解耦,這種設計簡化了應用開發和數據中心的運維。還有各種各樣的編制系統,這主要是因為之前許多內部系統工具冒出來了,它們之前開發出來是用于管理容器大規模部署的。例如Kubernetes就是基于谷歌的Omega系統,而Omega系統是用來管理整個谷歌云環境中的容器。
合成工具和編制工具功能上會有部分的重合,所以使用時它們彼此可以作為補充。例如Fig可以用來描述容器功能上如何交互,同時Kubernetes pods(譯者注:pods可以被看成一個容器組)可以用來提供相關的監測和擴展功能。
平臺即服務
有很多原生于Docker的PaaS實現,例如Deis和Flynn,已經體現出Linux容器在支持開發靈活性上的強大優勢(而不是那些自以為是給定的一套語言和框架)。其它的云平臺如CloudFoundry、OpenShift和Apcera Continuum,已經采用集成基于Docker相關功能到現有系統中的技術路線,這樣基于Docker鏡像(或者是創建它們的Dockerfiles)的應用在部署和管理的同時,仍然可以使用之前系統支持的語言和框架。
所有的云
由于Docker可以運行在任何有合理數據內核的Linux虛擬機上,所以它可以運行在很多IaaS提供的云上。許多大的云提供商宣布了對Docker和它的生態系統的附加支持。
亞馬遜已經引入Docker到它的彈性豆莖(Elastic Beanstalk)系統中(這是在IaaS之上的編制服務)。谷歌使Docker成為可管理的虛擬機(managed VMs),它提供了在應用程序引擎的PaaS和計算引擎的的IaaS之間的中間站。微軟和IBM也都宣布了基于Kubernetes的服務,這樣在他們的云上就可以部署和管理多容器應用了。
為了給當前使用的廣泛多樣的后端提供一致性的接口,Docker團隊引入了libswarm,它會被集成到多數的云和資源管理系統中。Libswarm一個明確的目標是“通過切換服務來源的辦法來防止供應商鎖定”。這通過呈現一組一致性的服務(以及相關的API)來完成,這些服務會附著到特定后端的實現上。比如Docker服務器服務會呈現Docker遠程API到本地Docker命令行工具中,這樣眾多的服務提供者就可以管理相關的容器了。
基于Docker的新的服務類型仍在起步階段。雖然位于倫敦的果園實驗室(Orchard labs)可以提供Docker容器的托管服務,但Docker公司表示,在它收購果園實驗室后相關服務不會被置于優先位置。Docker公司還向cloudControl公司出售了其先前的DotCloud PaaS 業務。如OpenVZ之類基于舊的容器管理系統的服務已經比較普通了,所以在一定程度上Docker需要向主機提供商們證明其價值。
Docker和它的發行版
Docker已經成為主流Linux版本的標準特性,比如Ubuntu, Red Hat Enterprise Linux (RHEL) 和CentOS。遺憾的是這些Linux發行版與Docker項目在步調上并不一致,從而導致這些Linux發行版中Docker的版本比當前能用的老得多。例如Ubuntu 14.04的Docker版本是0.9.1,并且在Ubuntu升級到14.04.1時Docker的版本也沒有變(當時Docker項目版本是1.1.2)。在官方庫中還有一個命名空間沖突的問題,因為Docker也是KDE系統托盤的名字,所以在Ubuntu 14.04中Docker包和命令行工具起了另一個名稱“docker.io”。
在企業級Linux發行版中情況也沒有太大的不同,CentOS 7中Docker的版本是0.11.1,這是Docker公司宣布1.0版本產品準備就緒之前的一個開發版。Linux發行版用戶如果要使用最新的版本以保證穩定性、性能和安全,那么按照Docker安裝指導操作并使用Docker公司提供的庫,要比使用Linux發行版中的版本要好得多。
Docker的到來也催生了新的Linux發行版,比如CoreOS和Red Hat的Project Atomic,它們設計成能運行容器的最小環境系統。這些發行版相比傳統Linux發行版本,有比較新的內核和Docker版本,對內存和硬盤的占用也比較小。新的發行版本中也有一些新的工具用來管理大容量的容器部署,比如fleet負責分布式系統啟動,而etcd負責元數據管理。這些Linux發行版針對自身的分布式更新采用了新的機制,這樣就可以使用最新版本的內核和Docker了。這表示對Docker應用的其中一種效果的認可,那就是把注意力重心從發行版和包管理解決方案轉到Linux內核(和使用內核的Docker子系統)上來。
盡管新發行版(譯者注:類似于CoreOS)可能是Docker最佳的運行方式,但支持容器的傳統發行版和它們的包管理工具仍然非常重要。Docker Hub上提供了 Debian、Ubuntu和CentOS的正式鏡像,還有“半官方”Fedora的鏡像庫。RHEL沒有在Docker Hub上的鏡像,因為它們是直接由Red Hat發行的。這意味著Docker Hub上的自動構建機制只對那些純開源的Linux發行版本可用(并愿意信任那些起源于Docker公司團隊策劃的基礎鏡像)。
Docker Hub同時集成了源控制系統,如GitHub和Bitbucker,用來自動構建包管理器。包管理器可以在鏡像構建過程中生成構建規格(在Dockerfile中)和最終構建鏡像之間的復雜關系。構建過程的結果具有不確定性,這不是Docker的特定問題,而和包管理器如何工作相關。今天構建的是這個版本,在另一個時間構建可能會得到一個新的版本,這也就是包管理器需要更新功能的原因。容器抽象(即較少關注容器中的內容)與容器擴展(因為輕量級資源利用率)可能會使這種不確定性成為Docker相關的痛點。
Docker的未來
Docker公司已經建立了清晰的道路,即發展核心能力(libcontainer)、跨業務管理(libswarm)和容器間消息(libchan)。與此同時,通過收購果園實驗室(Orchard labs),Docker公司表達了利用自身生態系統的意愿。但是,這不僅僅關注Docker公司,這個項目的貢獻者還來自于一些大牌公司,如谷歌、IBM和Red Hat。在仁慈的獨裁者、首席技術官Solomon Hykes的掌舵下,Docker公司和Docker項目的技術領先有著明確的聯系。在項目初始的18個月里,它已經顯示出通過自己的輸出來快速前進的能力,并且沒有減弱的跡象。
許多投資者正著眼于十年前VMware公司ESX/ vSphere平臺的功能矩陣,試圖找出已經由虛擬機普及而驅動的企業預期和現有Docker生態系統之間的差距(和機會)。在網絡存儲和細粒度的版本管理(用于容器中的內容)領域,現有Docker生態系統做得并不好,這就為初創企業和在職人員提供了機會。
隨著時間的推移,虛擬機和容器(Docker中的“運行”部分)之間的區別很可能變得不再那么重要,這將使注意力轉到“構建(build)”和“交付(ship)”方面。這些變化將使 “Docker會發生什么?”的問題,相比“Docker會帶給IT業什么?”的問題,變得更不重要。
關于作者
Chris Swan 是云網絡軟件供應商CohesiveFT的首席技術官。作為銀行業的技術專家和技術領域的銀行專家,他曾經有十幾年的時間在從事金融服務業。他大部分時間是在大型瑞士銀行中與應用服務器、計算網格、安全、移動和云這些基礎設施打交道。克里斯還喜歡參與互聯網上的修補工作,包括一些Raspberry Pi項目。
原文出自:http://blog.csdn.net/miller_lover/article/details/41073547