Docker系列—簡介概述
一、起源
Docker 最初是 dotCloud 公司創(chuàng)始人 Solomon Hykes 在法國期間發(fā)起的一個公司內(nèi)部項目,它是基于 dotCloud 公司多年云服務(wù)技術(shù)的一次革新,并于 2013 年 3 月以 Apache 2.0 授權(quán)協(xié)議開源,主要項目代碼在 GitHub 上進行維護。Docker 項目后來還加入了 Linux 基金會,并成立推動 開放容器聯(lián)盟(OCI)。
Docker 自開源后受到廣泛的關(guān)注和討論,至今其 GitHub 項目 已經(jīng)超過 5 萬 7 千個星標和一萬多個 fork。甚至由于 Docker 項目的火爆,在 2013 年底,dotCloud 公司決定改名為 Docker。Docker 最初是在 Ubuntu 12.04 上開發(fā)實現(xiàn)的;Red Hat 則從 RHEL 6.5 開始對 Docker 進行支持;Google 也在其 PaaS 產(chǎn)品中廣泛應(yīng)用 Docker。
Docker 使用 Google 公司推出的 Go 語言 進行開發(fā)實現(xiàn),基于 Linux 內(nèi)核的 cgroup,namespace,以及 OverlayFS 類的 Union FS 等技術(shù),對進程進行封裝隔離,屬于 操作系統(tǒng)層面的虛擬化技術(shù)。由于隔離的進程獨立于宿主和其它的隔離的進程,因此也稱其為容器。最初實現(xiàn)是基于 LXC,從 0.7 版本以后開始去除 LXC,轉(zhuǎn)而使用自行開發(fā)的 libcontainer,從 1.11 版本開始,則進一步演進為使用 runC 和 containerd。
- runc 是一個 Linux 命令行工具,用于根據(jù) OCI容器運行時規(guī)范 創(chuàng)建和運行容器。
- containerd 是一個守護程序,它管理容器生命周期,提供了在一個節(jié)點上執(zhí)行容器和管理鏡像的最小功能集。
一款開源軟件能否在商業(yè)上成功,很大程度上依賴三件事 - 成功的 user case(用例), 活躍的社區(qū)和一個好故事。 dotCloud 之家的 PaaS 產(chǎn)品建立在docker之上,長期維護且有大量的用戶,社區(qū)也十分活躍,接下來我們看看docker的故事。
- 環(huán)境管理復(fù)雜 - 從各種OS到各種中間件到各種app, 一款產(chǎn)品能夠成功作為開發(fā)者需要關(guān)心的東西太多,且難于管理,這個問題幾乎在所有現(xiàn)代IT相關(guān)行業(yè)都需要面對。
- 云計算時代的到來 - AWS的成功, 引導(dǎo)開發(fā)者將應(yīng)用轉(zhuǎn)移到 cloud 上, 解決了硬件管理的問題,然而中間件相關(guān)的問題依然存在 (所以openstack HEAT和 AWS cloudformation 都著力解決這個問題)。開發(fā)者思路變化提供了可能性。
- 虛擬化手段的變化 - cloud 時代采用標配硬件來降低成本,采用虛擬化手段來滿足用戶按需使用的需求以及保證可用性和隔離性。然而無論是KVM還是Xen在 docker 看來,都在浪費資源,因為用戶需要的是高效運行環(huán)境而非OS, GuestOS既浪費資源又難于管理, 更加輕量級的LXC更加靈活和快速
- LXC的移動性 - LXC在 linux 2.6 的 kernel 里就已經(jīng)存在了,但是其設(shè)計之初并非為云計算考慮的,缺少標準化的描述手段和容器的可遷移性,決定其構(gòu)建出的環(huán)境難于遷移和標準化管理(相對于KVM之類image和snapshot的概念)。docker 就在這個問題上做出實質(zhì)性的革新。這是docker最獨特的地方。
面對上述幾個問題,docker設(shè)想是交付運行環(huán)境如同海運,OS如同一個貨輪,每一個在OS基礎(chǔ)上的軟件都如同一個集裝箱,用戶可以通過標準化手段自由組裝運行環(huán)境,同時集裝箱的內(nèi)容可以由用戶自定義,也可以由專業(yè)人員制造。這樣,交付一個軟件,就是一系列標準化組件的集合的交付,如同樂高積木,用戶只需要選擇合適的積木組合,并且在最頂端署上自己的名字(最后一個標準化組件是用戶的app)。這也就是基于docker的PaaS產(chǎn)品的原型。
二、概述
Docker 是一個用于開發(fā)、傳送和運行應(yīng)用程序的開放平臺。Docker 使您能夠?qū)?yīng)用程序與基礎(chǔ)設(shè)施分開,以便您可以快速交付軟件。使用 Docker,您可以像管理應(yīng)用程序一樣管理基礎(chǔ)設(shè)施。通過利用 Docker 的快速交付、測試和部署代碼的方法,您可以顯著減少編寫代碼和在生產(chǎn)中運行代碼之間的延遲。
Docker 提供了在稱為容器的松散隔離環(huán)境中打包和運行應(yīng)用程序的能力。隔離和安全性允許您在給定主機上同時運行多個容器。容器是輕量級的,包含運行應(yīng)用程序所需的一切,因此您無需依賴主機上當(dāng)前安裝的內(nèi)容。您可以在工作時輕松共享容器,并確保與您共享的每個人都獲得以相同方式工作的相同容器。
Docker 提供工具和平臺來管理容器的生命周期:
- 使用容器開發(fā)您的應(yīng)用程序及其支持組件。
- 容器成為分發(fā)和測試應(yīng)用程序的單元。
- 準備就緒后,將應(yīng)用程序作為容器或編排服務(wù)部署到生產(chǎn)環(huán)境中。無論您的生產(chǎn)環(huán)境是本地數(shù)據(jù)中心、云提供商還是兩者的混合,這都是一樣的。
一個完整的Docker有以下幾個部分組成:
- Docker Client客戶端
- Docker Daemon守護進程
- Docker Image鏡像
- Docker Container容器
三、架構(gòu)
Docker 包括三個基本概念:
- 鏡像(Image):Docker 鏡像(Image),就相當(dāng)于是一個 root 文件系統(tǒng)。比如官方鏡像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系統(tǒng)的 root 文件系統(tǒng)。
- 容器(Container):鏡像(Image)和容器(Container)的關(guān)系,就像是面向?qū)ο蟪绦蛟O(shè)計中的類和實例一樣,鏡像是靜態(tài)的定義,容器是鏡像運行時的實體。容器可以被創(chuàng)建、啟動、停止、刪除、暫停等。
- 倉庫(Repository):倉庫可看成一個代碼控制中心,用來保存鏡像。
Docker 使用客戶端-服務(wù)器架構(gòu)。Docker客戶端與 Docker守護進程對話,后者負責(zé)構(gòu)建、運行和分發(fā) Docker 容器的繁重工作。Docker 客戶端和守護程序可以 在同一系統(tǒng)上運行,或者您可以將 Docker 客戶端連接到遠程 Docker 守護程序。Docker 客戶端和守護進程使用 REST API、UNIX 套接字或網(wǎng)絡(luò)接口進行通信。另一個 Docker 客戶端是 Docker Compose,它允許您使用由一組容器組成的應(yīng)用程序。
四、底層實現(xiàn)
Docker 底層的核心技術(shù)包括 Linux 上的命名空間(Namespaces)、控制組(Control groups)、Union 文件系統(tǒng)(Union file systems)和容器格式(Container format)。
我們知道,傳統(tǒng)的虛擬機通過在宿主主機中運行 hypervisor 來模擬一整套完整的硬件環(huán)境提供給虛擬機的操作系統(tǒng)。虛擬機系統(tǒng)看到的環(huán)境是可限制的,也是彼此隔離的。 這種直接的做法實現(xiàn)了對資源最完整的封裝,但很多時候往往意味著系統(tǒng)資源的浪費。 例如,以宿主機和虛擬機系統(tǒng)都為 Linux 系統(tǒng)為例,虛擬機中運行的應(yīng)用其實可以利用宿主機系統(tǒng)中的運行環(huán)境。
我們知道,在操作系統(tǒng)中,包括內(nèi)核、文件系統(tǒng)、網(wǎng)絡(luò)、PID、UID、IPC、內(nèi)存、硬盤、CPU 等等,所有的資源都是應(yīng)用進程直接共享的。 要想實現(xiàn)虛擬化,除了要實現(xiàn)對內(nèi)存、CPU、網(wǎng)絡(luò)IO、硬盤IO、存儲空間等的限制外,還要實現(xiàn)文件系統(tǒng)、網(wǎng)絡(luò)、PID、UID、IPC等等的相互隔離。 前者相對容易實現(xiàn)一些,后者則需要宿主機系統(tǒng)的深入支持。
隨著 Linux 系統(tǒng)對于命名空間功能的完善實現(xiàn),程序員已經(jīng)可以實現(xiàn)上面的所有需求,讓某些進程在彼此隔離的命名空間中運行。大家雖然都共用一個內(nèi)核和某些運行時環(huán)境(例如一些系統(tǒng)命令和系統(tǒng)庫),但是彼此卻看不到,都以為系統(tǒng)中只有自己的存在。這種機制就是容器(Container),利用命名空間來做權(quán)限的隔離控制,利用 cgroups 來做資源分配。
五、Docker 和傳統(tǒng)虛擬化方式的比較
Docker 項目的目標是實現(xiàn)輕量級的操作系統(tǒng)虛擬化解決方案。 Docker 的基礎(chǔ)是 Linux 容器(LXC)等技術(shù)。在 LXC 的基礎(chǔ)上 Docker 進行了進一步的封裝,讓用戶不需要去關(guān)心容器的管理,使得操作更為簡便。用戶操作 Docker 的容器就像操作一個快速輕量級的虛擬機一樣簡單。下面的圖片比較了 Docker 和傳統(tǒng)虛擬化方式的不同之處,可見容器是在操作系統(tǒng)層面上實現(xiàn)虛擬化,直接復(fù)用本地主機的操作系統(tǒng),而傳統(tǒng)方式則是在硬件層面實現(xiàn)。
Docker 在容器的基礎(chǔ)上,進行了進一步的封裝,從文件系統(tǒng)、網(wǎng)絡(luò)互聯(lián)到進程隔離等等,極大地簡化了容器的創(chuàng)建和維護。使得 Docker 技術(shù)比虛擬機技術(shù)更為輕便、快捷。
傳統(tǒng)虛擬化
Docker容器化
六、為什么要用 Docker
Docker 跟傳統(tǒng)的虛擬化方式相比具有眾多的優(yōu)勢。
- 更高效的利用系統(tǒng)資源
由于容器不需要進行硬件虛擬以及運行完整操作系統(tǒng)等額外開銷,Docker 對系統(tǒng)資源的利用率更高。無論是應(yīng)用執(zhí)行速度、內(nèi)存損耗或者文件存儲速度,都要比傳統(tǒng)虛擬機技術(shù)更高效。因此,相比虛擬機技術(shù),一個相同配置的主機,往往可以運行更多數(shù)量的應(yīng)用。
- 更快速的啟動時間
傳統(tǒng)的虛擬機技術(shù)啟動應(yīng)用服務(wù)往往需要數(shù)分鐘,而 Docker 容器應(yīng)用,由于直接運行于宿主內(nèi)核,無需啟動完整的操作系統(tǒng),因此可以做到秒級、甚至毫秒級的啟動時間。大大的節(jié)約了開發(fā)、測試、部署的時間。
- 一致的運行環(huán)境
開發(fā)過程中一個常見的問題是環(huán)境一致性問題。由于開發(fā)環(huán)境、測試環(huán)境、生產(chǎn)環(huán)境不一致,導(dǎo)致有些 bug 并未在開發(fā)過程中被發(fā)現(xiàn)。而 Docker 的鏡像提供了除內(nèi)核外完整的運行時環(huán)境,確保了應(yīng)用運行環(huán)境一致性,從而不會再出現(xiàn) 「這段代碼在我機器上沒問題啊」 這類問題。
- 持續(xù)交付和部署
對開發(fā)和運維(DevOps)人員來說,最希望的就是一次創(chuàng)建或配置,可以在任意地方正常運行。
使用 Docker 可以通過定制應(yīng)用鏡像來實現(xiàn)持續(xù)集成、持續(xù)交付、部署。開發(fā)人員可以通過 Dockerfile 來進行鏡像構(gòu)建,并結(jié)合 持續(xù)集成(Continuous Integration) 系統(tǒng)進行集成測試,而運維人員則可以直接在生產(chǎn)環(huán)境中快速部署該鏡像,甚至結(jié)合 持續(xù)部署(Continuous Delivery/Deployment) 系統(tǒng)進行自動部署。
而且使用 Dockerfile 使鏡像構(gòu)建透明化,不僅僅開發(fā)團隊可以理解應(yīng)用運行環(huán)境,也方便運維團隊理解應(yīng)用運行所需條件,幫助更好的生產(chǎn)環(huán)境中部署該鏡像。
- 更輕松的遷移
由于 Docker 確保了執(zhí)行環(huán)境的一致性,使得應(yīng)用的遷移更加容易。Docker 可以在很多平臺上運行,無論是物理機、虛擬機、公有云、私有云,甚至是筆記本,其運行結(jié)果是一致的。因此用戶可以很輕易的將在一個平臺上運行的應(yīng)用,遷移到另一個平臺上,而不用擔(dān)心運行環(huán)境的變化導(dǎo)致應(yīng)用無法正常運行的情況。
- 更輕松的維護和擴展
Docker 使用的分層存儲以及鏡像的技術(shù),使得應(yīng)用重復(fù)部分的復(fù)用更為容易,也使得應(yīng)用的維護更新更加簡單,基于基礎(chǔ)鏡像進一步擴展鏡像也變得非常簡單。此外,Docker 團隊同各個開源項目團隊一起維護了一大批高質(zhì)量的 官方鏡像,既可以直接在生產(chǎn)環(huán)境使用,又可以作為基礎(chǔ)進一步定制,大大的降低了應(yīng)用服務(wù)的鏡像制作成本。
七、特性及局限
1.特性
在docker的網(wǎng)站上提到了docker的典型場景:
- Automating the packaging and deployment of applications(使應(yīng)用的打包與部署自動化)
- Creation of lightweight, private PAAS environments(創(chuàng)建輕量、私密的PAAS環(huán)境)
- Automated testing and continuous integration/deployment(實現(xiàn)自動化測試和持續(xù)的集成/部署)
- Deploying and scaling web apps, databases and backend services(部署與擴展webapp、數(shù)據(jù)庫和后臺服務(wù))
由于其基于LXC的輕量級虛擬化的特點,docker相比KVM之類最明顯的特點就是啟動快,資源占用小。因此對于構(gòu)建隔離的標準化的運行環(huán)境,輕量級的PaaS(如dokku), 構(gòu)建自動化測試和持續(xù)集成環(huán)境,以及一切可以橫向擴展的應(yīng)用(尤其是需要快速啟停來應(yīng)對峰谷的web應(yīng)用)。
①構(gòu)建標準化的運行環(huán)境,現(xiàn)有的方案大多是在一個baseOS上運行一套puppet/chef,或者一個image文件,其缺點是前者需要base OS許多前提條件,后者幾乎不可以修改(因為copy on write 的文件格式在運行時rootfs是read only的)。并且后者文件體積大,環(huán)境管理和版本控制本身也是一個問題。
②PaaS環(huán)境是不言而喻的,其設(shè)計之初和dotcloud的案例都是將其作為PaaS產(chǎn)品的環(huán)境基礎(chǔ)
③因為其標準化構(gòu)建方法(buildfile)和良好的REST API,自動化測試和持續(xù)集成/部署能夠很好的集成進來
③因為LXC輕量級的特點,其啟動快,而且docker能夠只加載每個container變化的部分,這樣資源占用小,能夠在單機環(huán)境下與KVM之類的虛擬化方案相比能夠更加快速和占用更少資源
2.局限
Docker并不是全能的,設(shè)計之初也不是KVM之類虛擬化手段的替代品,簡單總結(jié)幾點:
- Docker是基于Linux 64bit的,無法在32bit的linux/Windows/unix環(huán)境下使用
- LXC是基于cgroup等linux kernel功能的,因此container的guest系統(tǒng)只能是linux base的
- 隔離性相比KVM之類的虛擬化方案還是有些欠缺,所有container公用一部分的運行庫
- 網(wǎng)絡(luò)管理相對簡單,主要是基于namespace隔離
- cgroup的cpu和cpuset提供的cpu功能相比KVM的等虛擬化方案相比難以度量(所以dotcloud主要是按內(nèi)存收費)
- Docker對disk的管理比較有限
- container隨著用戶進程的停止而銷毀,container中的log等用戶數(shù)據(jù)不便收集