前言
本書的寫作目的不僅是在技術層面深入分析Docker背後的技術原理和設計思想,更在於從我們團隊自2011年以來在雲端運算方面的累積出發,理清目前以Docker、Kubernetes為代表的「容器雲」技術的發展脈絡,以期對IT企業的開發運行維護人員、容器雲端服務提供商以及Docker技術同好在技術選型、技術路線規劃上有所幫助。
2013年是Docker正式開放原始碼發佈的年份, 也是我們團隊開始使用Docker的時間。當時Docker作為一個單機版輕量級虛擬化工具,並沒有像目前這樣活躍的生態圈。我們使用Docker處理Cloud Foundry這種複雜分散式系統的快速部署和移轉,結果我們體驗到了驚喜,但也有遺憾。確實,那時候Docker 1.0尚未發佈,作為最先吃螃蟹的人之一,我們除了能感受到Docker相比虛擬機器在資源使用率和效能上的極大優勢以及在使用方式上的高效便捷之外,還不得不忍受當時的Docker與一個完整的資料中心運行維護系統之間的差距。例如網路,跨宿主機間的通訊在很長一段時間都困擾著我們;例如容器內部不能單獨設定核心參數,一旦應用對效能有特殊要求的時候,就無法單獨進行最佳化訂製;再例如維護,時常需要手動清理僵屍容器、映像檔等。
在隨後的一整年裡,我們真真切切地感受到了Docker是如何從一個開發運行維護人員略有耳聞的工具成長為一個技術圈裡家喻戶曉的名詞。以Docker為基礎的公有雲、私有雲專案也如雨後春筍般湧現;各大知名技術社區都為Docker開闢專欄,甚至出現了專為討論Docker而生的技術社區。以Docker為基礎的中文大陸本土化也開始萌芽,各種中國大陸映像檔託管和加速服務層出不窮。Docker官方也沒有閑著,前不久,Docker的各種郵寄清單中都出現了應徵中國區執行官的訊息。Docker生態系統的建立已經是不爭的事實,我們團隊也從Docker的使用者,成為了Docker、Kubernetes、libcontainer 等開放原始碼專案的特性維護者(maintainer)和程式貢獻者(contributor)。
目前Docker已絕不僅是一項輕量級虛擬化技術,官方的Docker運行維護三件套件、來自協力廠商的Kubernetes、OpenShift v3、Flynn、Deis等專案已經以Docker這種容器技術建置出各種各樣的容器雲端服務平台,關於Docker等容器技術的討論重心也已經從「容器」轉變為「容器雲」。Docker對於IT企業的價值也從節省資源這一方面擴充到對整個軟體開發運行維護生命週期的改造。
作為軟體企業多年的實作者和教育者,我們一直試圖探索這樣一些問題:雲端運算除了目前 被廣為接受的基礎設施雲端平台(IaaS)的形態,是否還有更加接近開發人員和運行維護人員的形態?雲端運算如何以更好的形態服務於網際網路+這樣一個以軟體連接人與人、人與企業、企業與企業的時代?正是Docker這種容器技術的出現,使得這樣的探索成為了可能。
✤ 本書結構
本書共分兩部分,沿著從容器到容器雲的發展脈絡,從「概念用法解析」到「核心原理分析」,然後到「進階實作技巧」,層層推進,全面介紹了Docker以及圍繞Docker 建置的各種容器雲端平台技術,深入分析了Kubernetes背後的技術原理和設計思想。
第一部分說明了Docker容器的核心原理和實作技巧。其中第1章和第2章能夠讓讀者在短時間內體驗這場IT界的風暴,並且初步了解Docker的使用方法,為後續的原始程式解析做準備。第3章是本書第一部分的核心,這一章以Docker 1.10版本原始程式為基礎,深入分析了容器的namespace和cgroups原理,緊接著我們以docker run指令為線索,一路貫穿Docker的容器建立、映像檔組織、聯合檔案系統以及容器網路初始化的原始程式,深入透徹地介紹了從一行指令到最後Linux容器產生的整個過程中,Docker原始程式的設計原理和執行路線。第4章則介紹了目前時髦的「容器化思維」以及Docker相關的幾種實作技巧,包含網路、監控、服務發現等。值得一提的是,在上述程式走讀的過程中,本書幾乎沒有貼出任何一部分Docker原始程式或函數,而是力圖使用平實的語言和生動的圖示來展示程式背後的執行邏輯和設計思想。Docker的原始程式字字珠璣,我們希望能夠使用這樣的解讀方式讓讀者真正了解Docker和容器背後的設計方法和技術本質,而非變成一本單純的技術手冊。
第二部分深入分析以Docker為基礎的各種「容器雲」平台的架構細節和背後的設計理念,這些容器雲雖然在底層技術上都以Docker這樣為基礎的容器技術,但在背後的設計思想上卻存在很大的差異。我們將看到一個因顛覆了原有IaaS、PaaS雲端運算生硬的分類方式而精彩紛呈的容器雲世界。其中第5章介紹了一個最簡單的容器雲解決方案作為引子;第6章和第7章分析和比較了幾種典型的容器雲開放原始碼專案,包含了Docker 官方的「三劍客」專案、Fleet以及更類似經典PaaS的Flynn和Deis;第8章是本書第二部分的重點,我們以Kubernetes 1.2版本原始程式為基礎,從核心概念到架構整理,再到深入到元件等級的Kubernetes原始程式解析,從多個維度詳細說明了Kubernetes容器雲端平台的各種技術細節,這在中文社區中尚屬第一次。我們希望透過容器雲端平台的原始程式解讀,能夠帶領讀者從紛繁複雜的容器雲專案中整理出一個細緻的脈絡,讓讀者在選型和延伸開發的過程中減少迷茫和試錯成本。而作為Kubernetes專案的貢獻者和特性維護者,我們希望有更多的技術人員能夠從原始程式層面對Kubernetes有更深刻的了解和認識,並且同我們一起來推動這個優秀的開放原始碼專案在中文使用地區的進步和落地。在第二部分的結尾,我們試圖回答之前的提問,即容器雲應該以何種形態來更進一步地支撐當今時代。
自本書第1版出版以來,容器生態圈已經發生了翻天覆地的變化。新的開放原始碼專案層出不窮,各個開放原始碼專案都在快速反覆運算演進。Docker已經從本書第1版裡的1.6.2發展為目前的1.10。Kubernetes也從本書第1版裡的0.16發展到了現在的1.2,並且在1.0.1版本時宣佈其已經正式進入可投入生產環境(production ready)的狀態。
第3章是本書第一部分的重點。Docker 1.10版相對於本書第1版中的1.6.2版,主要的更新包含以下幾個方面。
▲Docker在架構方面不斷將本身解耦,逐步發展成容器執行時期(runtime)、映像檔建置(builder)、映像檔分發(distribution)、網路(networking)、資料卷冊(volume)等獨立的功能元件,提供daemon來管理,並透過Engine曝露一組標準的API來操作這些元件(詳見本書3.2節)。
▲將網路和資料卷冊提升為「一等公民」,提供了獨立子指令操作,網路和資料卷冊具備獨立的生命週期,不再依賴容器的生命週期(詳見本書3.7節、3.8節)。
▲網路實現方面,Docker將網路相關的實現解耦為獨立的元件libnetwork,抽象出一個通用的容器網路模型(CNM),功能上也終於原生支援了跨主機通訊(詳見本書3.8節)。
▲在擴充性方面,在1.7.0版本後就開始支援網路、volume和儲存驅動(仍處於實驗階段)的外掛程式化,開發者可以透過實現Docker提供的外掛程式標準來訂製自己的外掛程式(詳見本書3.6節、3.7節、3.8節)。
▲在Docker安全方面,Docker支援了user namespace和seccomp來加強容器執行時期的安全,在全新的映像檔分發元件中引用可信賴的分發和以內容儲存為基礎的機制,進一步加強映像檔的安全性(詳見本書3.5節、3.6節、3.9節)。
需要特別指出的一點是,隨著容器如火如荼的發展,為了推動容器生態的健康發展,促進生態系統內各組織間的協作合作,容器的標準化也顯得越來越重要。Linux基金會於2015年6月成立OCI(Open Container Initiative)組織,並針對容器格式和執行時期制定了一個開放的工業化標準,即OCI標準。Docker公司率先貢獻出滿足OCI標準的容器執行時期runC,HyperHQ公司也開放原始碼了自己的OCI容器執行時期runV,相信業界會有越來越多的公司加入這個標準化浪潮中。Docker公司雖然沒有在Docker 1.10版本中直接使用runC作為容器的執行時期,但是已經將「修改Docker engine來直接呼叫runC的二進位檔案為Docker提供容器引擎」寫入到了1.10版本的roadmap中。本書在3.4.3節中對runC的建置和使用進行了介紹。
第8章是本書第二部分的重點。由於Kubernetes的程式始終處於積極更新之中,自本書第1 版截稿以來,Kubernetes又相繼發佈了0.17、0.18、0.19、0.20、0.21、1.0、1.1 與1.2等幾個版本。主要的更新包含以下幾個方面。
▲大幅豐富了支撐的應用執行場景。從全面重構的long-running service的replicaSet,到呼聲漸高的支援batch job的Job、可類比為守護處理程序的DaemonSet、負責進行應用更新的Deployment、具備自動擴充能力的HPA(Horizontal Pod Autoscaler),乃至於有狀態服務的petSet,都已經或即將涵蓋在Kubernetes的支撐場景中(詳見本書8.2節)。
▲加強各個元件的功能擴充或效能最佳化。apiserver和 controller manager為應對全新的resource和API有顯著的擴充;scheduler也在豐富排程策略和多排程器協作排程上有積極的動作;kubelet在效能上也有長足的進步,使得目前單一節點上支援的pod從原來的30個增長到了110個,叢集工作節點的規模也從100個躍升為1000個;多為人詬病的kube-proxy如今也鳥槍換炮,預設升級為iptables模式,在傳輸量上也更為樂觀;在可以預期的未來,rescheduler將成為Kubernetes家庭中的新成員,使得重排程成為可能(詳見本書8.3節)。
▲相容更多的容器後端模型、網路及儲存方案。從Docker到rkt,Kubernetes展示了對容器後端開放姿態,同時它還準備以C/S模式實現對其他容器的支撐。在網路方面,Kubernetes引用了網路外掛程式,其中最為矚目的當屬CNI;儲存上的解決方案更是層出不窮,flocker、Cinder、CephFS不一而足,還增加了許多特殊用途的volume,如secret、configmap等(詳見本書8.4節、8.5節)。
▲增加了OpenID、Keystone等認證機制、Webhook等授權機制,以及更為豐富的多維資源管理機制admission controller(詳見本書8.6節)。
▲另外,作為Kubernetes社區的積極參與者,我們還專門增加了8.8節,討論目前社區正在醞釀中的一些新特性,如Ubernetes、petSet、rescheduler。我們還討論了Kubernetes效能最佳化,以及Kubernetes 與OCI的關係等話題。
除了全面更新這兩個重點章節之外,我們還在第1 章中更新了Docker近期的「大事記」並重新整理了容器生態圈,加入了許多重要的容器雲技術開放原始碼專案,以及OCI、CNCF等國際標準組織;在第2章中,我們將Docker命令列工具的基礎用法更新到了Docker 1.10版;在第4章中增強了對時下火熱的「容器化思維」和「微服務」的討論;在第6章中更新了對Docker「三劍客」——Compose、Swarm和Machine的討論;在附錄中以Docker 1.10版為標準更新了附錄A的Docker安裝指南,以Kubernetes 1.2為標準,更新了附錄F中Kubernetes的安裝指南。
✤ 致謝
對於能夠撰寫第一本中文化在原始程式碼層面深度解析Docker和Kubernetes,並揭秘以Docker容器為基礎的雲端運算生態圈底層技術的圖書,我們感到非常榮幸。浙江大學SEL實驗室雲端運算團隊在此向所有支援幫助我們的朋友表達最誠摯的謝意,沒有大家的支援,我們很可能無法順利地完成這項工作。
感謝浙江大學軟體學院楊小虎院長對雲端運算團隊一直以來的關懷和支援,楊院長的遠見卓識和誨人不倦令人欽佩。
感謝以相當大熱情參與到本撰寫作中的浙江大學電腦學院、軟體學院的各位博士、碩士所究所學生:張磊、何思玫、高相林、張浩、孫健波、王哲、馮明振、喬剛、杜軍、仇臣、周宇哲、葉瑞浩、賴春彬、孫巨集亮、陳星宇。他們的熱情是我們團隊活力的源泉,他們使那些分散在各個領域的技術得以整合。在本書撰寫過程中,他們不計個人得失地精誠合作,這是本書得以成書的基礎。
特別要感謝不辭辛勞為本書出謀劃策、日以繼夜不斷審稿修改的圖靈公司的編輯們。在整個寫作過程中,我們團隊獲得了出版方的大力支持。他們認真負責的態度是本書順利出版的保障。
感謝InfoQ主編郭蕾一直以來對浙江大學SEL實驗室技術分享工作所做出的支援和推廣,他和InfoQ同事們的鼓勵是推動本書發起的一大動力。
感謝《第一本Docker書》的譯者劉斌為本書進行了細緻的審讀,並為我們提出了寶貴的修訂建議。
感謝浙江大學SEL實驗室雲端運算團隊的其他所有人,他們認真負責的工作態度和令人滿意的工作成果是本書不可或缺的支援力量。
感謝大家的共同努力,讓我們的成果得以面世,在Docker佈道之路上貢獻出了自己的光和熱,傳播惠及當下的雲端運算前端技術。
丁軼群
於浙江大學玉泉校區