天天看點

docker學習總結第一篇

docker學習總結第一篇

容器”這個概念從來就不是什麼新鮮的東西,也不是 Docker 公司發明的。即使在當時最熱門的 PaaS 項目 Cloud Foundry 中,容器也隻是其最底層、最沒人關注的那一部分。說到這裡,我正好以當時的事實标準 Cloud Foundry 為例,來解說一下 PaaS 技術。

PaaS 項目被大家接納的一個主要原因,就是它提供了一種名叫“應用托管”的能力。 在當時,虛拟機和雲計算已經是比較普遍的技術和服務了,那時主流使用者的普遍用法,就是租一批 AWS 或者 OpenStack 的虛拟機,然後像以前管理實體伺服器那樣,用腳本或者手工的方式在這些機器上部署應用。

當然,這個部署過程難免會碰到雲端虛拟機和本地環境不一緻的問題,是以當時的雲計算服務,比的就是誰能更好地模拟本地伺服器環境,能帶來更好的“上雲”體驗。而 PaaS 開源項目的出現,就是當時解決這個問題的一個最佳方案。

舉個例子,虛拟機建立好之後,運維人員隻需要在這些機器上部署一個 Cloud Foundry 項目,然後開發者隻要執行一條指令就能把本地的應用部署到雲上,這條指令就是:

$ cf push " 我的應用 "
           

是不是很神奇?

事實上,像 Cloud Foundry 這樣的 PaaS 項目,最核心的元件就是一套應用的打包和分發機制。 Cloud Foundry 為每種主流程式設計語言都定義了一種打包格式,而“cf push”的作用,基本上等同于使用者把應用的可執行檔案和啟動腳本打進一個壓縮包内,上傳到雲上 Cloud Foundry 的存儲中。接着,Cloud Foundry 會通過排程器選擇一個可以運作這個應用的虛拟機,然後通知這個機器上的 Agent 把應用壓縮包下載下傳下來啟動。

這時候關鍵來了,由于需要在一個虛拟機上啟動很多個來自不同使用者的應用,Cloud Foundry 會調用作業系統的 Cgroups 和 Namespace (容器核心)機制為每一個應用單獨建立一個稱作“沙盒”的隔離環境,然後在“沙盒”中啟動這些應用程序。這樣,就實作了把多個使用者的應用互不幹涉地在虛拟機裡批量地、自動地運作起來的目的。

這,正是 PaaS 項目最核心的能力。 而這些 Cloud Foundry 用來運作應用的隔離環境,或者說“沙盒”,就是所謂的“容器”。

而 Docker 項目,實際上跟 Cloud Foundry 的容器并沒有太大不同,是以在它釋出後不久,Cloud Foundry 的首席産品經理 James Bayer 就在社群裡做了一次詳細對比,告訴使用者 Docker 實際上隻是一個同樣使用 Cgroups 和 Namespace 實作的“沙盒”而已,沒有什麼特别的黑科技,也不需要特别關注。

然而,短短幾個月,Docker 項目就迅速崛起了。它的崛起速度如此之快,以至于 Cloud Foundry 以及所有的 PaaS 社群還沒來得及成為它的競争對手,就直接被宣告出局了。那時候,一位多年的 PaaS 從業者曾經如此感慨道:這簡直就是一場“降維打擊”啊。

難道這一次,連闖蕩多年的“老江湖”James Bayer 也看走眼了麼?

并沒有。

事實上,Docker 項目确實與 Cloud Foundry 的容器在大部分功能和實作原理上都是一樣的,可偏偏就是這剩下的一小部分不一樣的功能,成了 Docker 項目接下來“呼風喚雨”的不二法寶。

這個功能,就是 Docker 鏡像。(docker核心競争力)

恐怕連 Docker 項目的作者 Solomon Hykes 自己當時都沒想到,這個小小的創新,在短短幾年内就如此迅速地改變了整個雲計算領域的發展曆程。

我前面已經介紹過,PaaS 之是以能夠幫助使用者大規模部署應用到叢集裡,是因為它提供了一套應用打包的功能。可偏偏就是這個打包功能,卻成了 PaaS 日後不斷遭到使用者诟病的一個“軟肋”。

出現這個問題的根本原因是,一旦用上了 PaaS,使用者就必須為每種語言、每種架構,甚至每個版本的應用維護一個打好的包。這個打包過程,沒有任何章法可循,更麻煩的是,明明在本地運作得好好的應用,卻需要做很多修改和配置工作才能在 PaaS 裡運作起來。而這些修改和配置,并沒有什麼經驗可以借鑒,基本上得靠不斷試錯,直到你摸清楚了本地應用和遠端 PaaS 比對的“脾氣”才能夠搞定。

最後結局就是,“cf push”确實是能一鍵部署了,但是為了實作這個一鍵部署,使用者為每個應用打包的工作可謂一波三折,費盡心機。

而Docker 鏡像解決的,恰恰就是打包這個根本性的問題。 所謂 Docker 鏡像,其實就是一個壓縮包。但是這個壓縮包裡的内容,比 PaaS 的應用可執行檔案 + 啟停腳本的組合就要豐富多了。實際上,大多數 Docker 鏡像是直接由一個完整作業系統的所有檔案和目錄構成的,是以這個壓縮包裡的内容跟你本地開發和測試環境用的作業系統是完全一樣的。

這就有意思了:假設你的應用在本地運作時,能看見的環境是 CentOS 7.2 作業系統的所有檔案和目錄,那麼隻要用 CentOS 7.2 的 ISO 做一個壓縮包,再把你的應用可執行檔案也壓縮進去,那麼無論在哪裡解壓這個壓縮包,都可以得到與你本地測試時一樣的環境。當然,你的應用也在裡面!

這就是 Docker 鏡像最厲害的地方:隻要有這個壓縮包在手,你就可以使用某種技術建立一個“沙盒”,在“沙盒”中解壓這個壓縮包,然後就可以運作你的程式了。

更重要的是,這個壓縮包包含了完整的作業系統檔案和目錄,也就是包含了這個應用運作所需要的所有依賴,是以你可以先用這個壓縮包在本地進行開發和測試,完成之後,再把這個壓縮包上傳到雲端運作。

在這個過程中,你完全不需要進行任何配置或者修改,因為這個壓縮包賦予了你一種極其寶貴的能力:本地環境和雲端環境的高度一緻!

這,正是 Docker 鏡像的精髓。

那麼,有了 Docker 鏡像這個利器,PaaS 裡最核心的打包系統一下子就沒了用武之地,最讓使用者抓狂的打包過程也随之消失了。相比之下,在當今的網際網路裡,Docker 鏡像需要的作業系統檔案和目錄,可謂唾手可得。

是以,你隻需要提供一個下載下傳好的作業系統檔案與目錄,然後使用它制作一個壓縮包即可,這個指令就是:

$ docker build " 我的鏡像 "
           

一旦鏡像制作完成,使用者就可以讓 Docker 建立一個“沙盒”來解壓這個鏡像,然後在“沙盒”中運作自己的應用,這個指令就是:

$ docker run " 我的鏡像 "
           

當然,docker run 建立的“沙盒”,也是使用 Cgroups 和 Namespace 機制建立出來的隔離環境。我會在後面的文章中,詳細介紹這個機制的實作原理。

是以,Docker 項目給 PaaS 世界帶來的“降維打擊”,其實是提供了一種非常便利的打包機制。這種機制直接打包了應用運作所需要的整個作業系統,進而保證了本地環境和雲端環境的高度一緻,避免了使用者通過“試錯”來比對兩種不同運作環境之間差異的痛苦過程。

而對于開發者們來說,在終于體驗到了生産力解放所帶來的痛快之後,他們自然選擇了用腳投票,直接宣告了 PaaS 時代的結束。

不過,Docker 項目固然解決了應用打包的難題,但正如前面所介紹的那樣,它并不能代替 PaaS 完成大規模部署應用的職責。

遺憾的是,考慮到 Docker 公司是一個與自己有潛在競争關系的商業實體,再加上對 Docker 項目普及程度的錯誤判斷,Cloud Foundry 項目并沒有第一時間使用 Docker 作為自己的核心依賴,去替換自己那套飽受诟病的打包流程。

反倒是一些機敏的創業公司,紛紛在第一時間推出了 Docker 容器叢集管理的開源項目(比如 Deis 和 Flynn),它們一般稱自己為 CaaS,即 Container-as-a-Service,用來跟“過時”的 PaaS 們劃清界限。

而在 2014 年底的 DockerCon 上,Docker 公司雄心勃勃地對外釋出了自家研發的“Docker 原生”容器叢集管理項目 Swarm,不僅将這波“CaaS”熱推向了一個前所未有的高潮,更是寄托了整個 Docker 公司重新定義 PaaS 的宏偉願望。

總結

2013~2014 年,以 Cloud Foundry 為代表的 PaaS 項目,逐漸完成了教育使用者和開拓市場的艱巨任務,也正是在這個将概念逐漸落地的過程中,應用“打包”困難這個問題,成了整個後端技術圈子的一塊心病。

Docker 項目的出現,則為這個根本性的問題提供了一個近乎完美的解決方案。這正是 Docker 項目剛剛開源不久,就能夠帶領一家原本默默無聞的 PaaS 創業公司脫穎而出,然後迅速占領了所有雲計算領域頭條的技術原因。