Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的鏡像中,然后發布到任何流行的 Linux或Windows 機器上,也可以實現虛擬化。容器是完全使用沙箱機制,相互之間不會有任何接口。
一個完整的Docker有以下幾個部分組成:
⒈ DockerClient客戶端
⒉ Docker Daemon守護進程
⒊ Docker Image鏡像
⒋ DockerContainer容器
Docker 是 PaaS 提供商 dotCloud 開源的一個基于 LXC 的高級容器引擎,源代碼托管在 Github 上, 基于go語言并遵從Apache2.0協議開源。
Docker自2013年以來非?;馃?,無論是從 github 上的代碼活躍度,還是Redhat在RHEL6.5中集成對Docker的支持, 就連 Google 的 Compute Engine 也支持 docker 在其之上運行。
一款開源軟件能否在商業上成功,很大程度上依賴三件事 - 成功的 user case(用例), 活躍的社區和一個好故事。 dotCloud 之家的 PaaS 產品建立在docker之上,長期維護且有大量的用戶,社區也十分活躍,接下來我們看看docker的故事。
? 環境管理復雜 - 從各種OS到各種中間件到各種app, 一款產品能夠成功作為開發者需要關心的東西太多,且難于管理,這個問題幾乎在所有現代IT相關行業都需要面對。
? 云計算時代的到來 - AWS的成功, 引導開發者將應用轉移到 cloud 上, 解決了硬件管理的問題,然而中間件相關的問題依然存在 (所以openstack HEAT和 AWS cloudformation 都著力解決這個問題)。開發者思路變化提供了可能性。
? 虛擬化手段的變化 - cloud 時代采用標配硬件來降低成本,采用虛擬化手段來滿足用戶按需使用的需求以及保證可用性和隔離性。然而無論是KVM還是Xen在 docker 看來,都在浪費資源,因為用戶需要的是高效運行環境而非OS, GuestOS既浪費資源又難于管理, 更加輕量級的LXC更加靈活和快速。
? LXC的移動性 - LXC在 linux 2.6 的 kernel 里就已經存在了,但是其設計之初并非為云計算考慮的,缺少標準化的描述手段和容器的可遷移性,決定其構建出的環境難于遷移和標準化管理(相對于KVM之類image和snapshot的概念)。docker 就在這個問題上做出實質性的革新。這是docker最獨特的地方。
面對上述幾個問題,docker設想是交付運行環境如同海運,OS如同一個貨輪,每一個在OS基礎上的軟件都如同一個集裝箱,用戶可以通過標準化手段自由組裝運行環境,同時集裝箱的內容可以由用戶自定義,也可以由專業人員制造。這樣,交付一個軟件,就是一系列標準化組件的集合的交付,如同樂高積木,用戶只需要選擇合適的積木組合,并且在最頂端署上自己的名字(最后一個標準化組件是用戶的app)。這也就是基于docker的PaaS產品的原型。
Docker使用客戶端-服務器 (C/S) 架構模式,使用遠程API來管理和創建Docker容器。Docker 容器通過 Docker 鏡像來創建。容器與鏡像的關系類似于面向對象編程中的對象與類。
Docker | 面向對象 |
---|---|
容器 | 對象 |
鏡像 | 類 |
Docker采用 C/S架構 Docker daemon 作為服務端接受來自客戶的請求,并處理這些請求(創建、運行、分發容器)。 客戶端和服務端既可以運行在一個機器上,也可通過 socket 或者RESTful API 來進行通信。
Docker daemon 一般在宿主主機后臺運行,等待接收來自客戶端的消息。 Docker 客戶端則為用戶提供一系列可執行命令,用戶用這些命令實現跟 Docker daemon 交互。
在docker的網站上提到了docker的典型場景:
? Automating the packaging and deployment of applications(使應用的打包與部署自動化)
? Creation of lightweight, private PAAS environments(創建輕量、私密的PAAS環境)
? Automated testing and continuous integration/deployment(實現自動化測試和持續的集成/部署)
? Deploying and scaling web apps, databases and backend services(部署與擴展webapp、數據庫和后臺服務)
由于其基于LXC的輕量級虛擬化的特點,docker相比KVM之類最明顯的特點就是啟動快,資源占用小。因此對于構建隔離的標準化的運行環境,輕量級的PaaS(如dokku), 構建自動化測試和持續集成環境,以及一切可以橫向擴展的應用(尤其是需要快速啟停來應對峰谷的web應用)。
⒈ 構建標準化的運行環境,現有的方案大多是在一個baseOS上運行一套puppet/chef,或者一個image文件,其缺點是前者需要base OS許多前提條件,后者幾乎不可以修改(因為copy on write 的文件格式在運行時rootfs是read only的)。并且后者文件體積大,環境管理和版本控制本身也是一個問題。
⒉ PaaS環境是不言而喻的,其設計之初和dotcloud的案例都是將其作為PaaS產品的環境基礎
⒊ 因為其標準化構建方法(buildfile)和良好的REST API,自動化測試和持續集成/部署能夠很好的集成進來
⒋ 因為LXC輕量級的特點,其啟動快,而且docker能夠只加載每個container變化的部分,這樣資源占用小,能夠在單機環境下與KVM之類的虛擬化方案相比能夠更加快速和占用更少資源
Docker并不是全能的,設計之初也不是KVM之類虛擬化手段的替代品,簡單總結幾點:
⒈ Docker是基于Linux 64bit的,無法在32bit的linux/Windows/unix環境下使用
⒉ LXC是基于cgroup等linux kernel功能的,因此container的guest系統只能是linux base的
⒊ 隔離性相比KVM之類的虛擬化方案還是有些欠缺,所有container公用一部分的運行庫
⒋ 網絡管理相對簡單,主要是基于namespace隔離
⒌ cgroup的cpu和cpuset提供的cpu功能相比KVM的等虛擬化方案相比難以度量(所以dotcloud主要是按內存收費)
⒍ Docker對disk的管理比較有限
⒎ container隨著用戶進程的停止而銷毀,container中的log等用戶數據不便收集
針對1-2,有windows base應用的需求的基本可以pass了; 3-5主要是看用戶的需求,到底是需要一個container還是一個VM, 同時也決定了docker作為 IaaS 不太可行。
針對6,7雖然是docker本身不支持的功能,但是可以通過其他手段解決(disk quota, mount --bind)??傊?,選用container還是vm, 就是在隔離性和資源復用性上做權衡。
另外即便docker 0.7能夠支持非AUFS的文件系統,但是由于其功能還不穩定,商業應用或許會存在問題,而AUFS的穩定版需要kernel 3.8, 所以如果想復制dotcloud的成功案例,可能需要考慮升級kernel或者換用ubuntu的server版本(后者提供deb更新)。這也是為什么開源界更傾向于支持ubuntu的原因(kernel版本)
Docker并非適合所有應用場景,Docker只能虛擬基于Linux的服務。Windows Azure 服務能夠運行Docker實例,但到目前為止Windows服務還不能被虛擬化。
可能最大的障礙在于管理實例之間的交互。由于所有應用組件被拆分到不同的容器中,所有的服務器需要以一致的方式彼此通信。這意味著任何人如果選擇復雜的基礎設施,那么必須掌握應用編程接口管理以及集群工具,比如Swarm、Mesos或者Kubernets以確保機器按照預期運轉并支持故障切換。
Docker在本質上是一個附加系統。使用文件系統的不同層構建一個應用是有可能的。每個組件被添加到之前已經創建的組件之上,可以比作為一個文件系統更明智。分層架構帶來另一方面的效率提升,當你重建存在變化的Docker鏡像時,不需要重建整個Docker鏡像,只需要重建變化的部分。
可能更為重要的是,Docker旨在用于彈性計算。每個Docker實例的運營生命周期有限,實例數量根據需求增減。在一個管理適度的系統中,這些實例生而平等,不再需要時便各自消亡了。
針對Docker環境存在的不足,意味著在開始部署Docker前需要考慮如下幾個問題。首先,Docker實例是無狀態的。這意味著它們不應該承載任何交易數據,所有數據應該保存在數據庫服務器中。
其次,開發Docker實例并不像創建一臺虛擬機、添加應用然后克隆那樣簡單。為成功創建并使用Docker基礎設施,管理員需要對系統管理的各個方面有一個全面的理解,包括Linux管理、編排及配置工具比如Puppet、Chef以及Salt。這些工具生來就基于命令行以及腳本。
Docker核心解決的問題是利用LXC來實現類似VM的功能,從而利用更加節省的硬件資源提供給用戶更多的計算資源。同VM的方式不同, LXC 其并不是一套硬件虛擬化方法 - 無法歸屬到全虛擬化、部分虛擬化和半虛擬化中的任意一個,而是一個操作系統級虛擬化方法, 理解起來可能并不像VM那樣直觀。所以我們從虛擬化到docker要解決的問題出發,看看他是怎么滿足用戶虛擬化需求的。
用戶需要考慮虛擬化方法,尤其是硬件虛擬化方法,需要借助其解決的主要是以下4個問題:
? 隔離性 - 每個用戶實例之間相互隔離, 互不影響。 硬件虛擬化方法給出的方法是VM, LXC給出的方法是container,更細一點是kernel namespace
? 可配額/可度量 - 每個用戶實例可以按需提供其計算資源,所使用的資源可以被計量。硬件虛擬化方法因為虛擬了CPU, memory可以方便實現, LXC則主要是利用cgroups來控制資源
? 移動性 - 用戶的實例可以很方便地復制、移動和重建。硬件虛擬化方法提供snapshot和image來實現,docker(主要)利用AUFS實現
? 全性 - 這個話題比較大,這里強調是host主機的角度盡量保護container。硬件虛擬化的方法因為虛擬化的水平比較高,用戶進程都是在KVM等虛擬機容器中翻譯運行的, 然而對于LXC, 用戶的進程是lxc-start進程的子進程, 只是在Kernel的namespace中隔離的, 因此需要一些kernel的patch來保證用戶的運行環境不會受到來自host主機的惡意入侵, dotcloud(主要是)利用kernel grsec patch解決的。
Docker 是一個用于開發,交付和運行應用程序的開放平臺。Docker 使您能夠將應用程序與基礎架構分開,從而可以快速交付軟件。借助 Docker,您可以與管理應用程序相同的方式來管理基礎架構。通過利用 Docker 的方法來快速交付,測試和部署代碼,您可以大大減少編寫代碼和在生產環境中運行代碼之間的延遲。
⒈ 快速,一致地交付您的應用程序
Docker 允許開發人員使用您提供的應用程序或服務的本地容器在標準化環境中工作,從而簡化了開發的生命周期。
容器非常適合持續集成和持續交付(CI / CD)工作流程,請考慮以下示例方案:
您的開發人員在本地編寫代碼,并使用 Docker 容器與同事共享他們的工作。
他們使用 Docker 將其應用程序推送到測試環境中,并執行自動或手動測試。
當開發人員發現錯誤時,他們可以在開發環境中對其進行修復,然后將其重新部署到測試環境中,以進行測試和驗證。
測試完成后,將修補程序推送給生產環境,就像將更新的鏡像推送到生產環境一樣簡單。
Docker 是基于容器的平臺,允許高度可移植的工作負載。Docker 容器可以在開發人員的本機上,數據中心的物理或虛擬機上,云服務上或混合環境中運行。
Docker 的可移植性和輕量級的特性,還可以使您輕松地完成動態管理的工作負擔,并根據業務需求指示,實時擴展或拆除應用程序和服務。
⒊ 在同一硬件上運行更多工作負載
Docker 輕巧快速。它為基于虛擬機管理程序的虛擬機提供了可行、經濟、高效的替代方案,因此您可以利用更多的計算能力來實現業務目標。Docker 非常適合于高密度環境以及中小型部署,而您可以用更少的資源做更多的事情。