Docker 的現狀與未來
![](https://linuxstory.org/wp-content/uploads/2024/06/020425uvryrgvkrvhnwlxg-389x400.png)
Docker 技術簡要綜述
Docker 利用 Linux 的一些內核機制例如 cGroups、命名空間和 SElinux 來實現容器之間的隔離。起初 Docker 只是 LXC 容器管理器子系統的前端,但是在 0.9 版本中引入了 libcontainer,這是一個原生的 go 語言庫,提供了用戶空間和內核之間的介面。
容器是基於 AUFS 這樣的聯合文件系統的,它允許跨多個容器共享組件,如操作系統鏡像和已安裝的相關庫。這種文件系統的分層方法也被 Dockerfile 的 DevOps 工具所利用,這些工具能夠緩存成功完成的操作。這就省下了安裝操作系統和相關應用程序依賴包的時間,極大地加速測試周期。另外,在容器之間的共享庫也能夠減少內存的佔用。
一個容器是從一個鏡像開始運行的,它可以來自本地創建,本地緩存,或者從一個註冊庫(registry)下載。Docker 公司運營的 Docker Hub 公有註冊庫,為各種操作系統、中間件和資料庫提供了官方倉庫存儲。各個組織和個人都可以在 docker Hub 上發布的鏡像的公有庫,也可以註冊成私有倉庫。由於上傳的鏡像可以包含幾乎任何內容,所以 Docker 提供了一種自動構建工具(以往稱為「可信構建」),鏡像可以從一種稱之為 Dockerfile 的鏡像內容清單構建而成。
容器 vs. 虛擬機
容器會比虛擬機更高效,因為它們能夠分享一個內核和分享應用程序庫。相比虛擬機系統,這也將使得 Docker 使用的內存更小,即便虛擬機利用了內存超量使用的技術。部署容器時共享底層的鏡像層也可以減少存儲佔用。IBM 的 Boden Russel 已經做了一些基準測試來說明兩者之間的不同。
相比虛擬機系統,容器具有較低系統開銷的優勢,所以在容器中,應用程序的運行效率將會等效於在同樣的應用程序在虛擬機中運行,甚至效果更佳。IBM 的一個研究團隊已經發表了一本名為[虛擬機與 Linux 容器的性能比較]的文章11。
容器只是在隔離特性上要比虛擬機遜色。虛擬機可以利用如 Intel 的 VT-d 和 VT-x 技術的 ring-1 硬體隔離技術。這種隔離可以防止虛擬機突破和彼此交互。而容器至今還沒有任何形式的硬體隔離,這使它容易受到攻擊。一個稱為 Shocker 的概念攻擊驗證表明,在 Docker 1.0 之前的版本是存在這種脆弱性的。儘管 Docker 1.0 修復了許多由 Shocker 漏洞帶來的較為嚴重的問題,Docker 的 CTO Solomon Hykes 仍然說,「當我們可以放心宣稱 Docker 的開箱即用是安全的,即便是不可信的 uid0 程序(超級用戶許可權程序),我們將會很明確地告訴大家。」Hykes 的聲明承認,其漏洞及相關的風險依舊存在,所以在容器成為受信任的工具之前將有更多的工作要做。
對於許多用戶案例而言,在容器和虛擬機之間二者選擇其一是種錯誤的二分法。Docker 同樣可以在虛擬機中工作的很好,這讓它可以用在現有的虛擬基礎措施、私有雲或者公有雲中。同樣也可以在容器里跑虛擬機,這也類似於谷歌在其雲平台的使用方式。像 IaaS 服務這樣普遍可用的基礎設施,能夠即時提供所需的虛擬機,可以預期容器與虛擬機一起使用的情景將會在數年後出現。容器管理和虛擬機技術也有可能被集成到一起提供一個兩全其美的方案;這樣,一個硬體信任錨微虛擬化所支撐的 libcontainer 容器,可與前端 Docker 工具鏈和生態系統整合,而使用提供更好隔離性的不同後端。微虛擬化(例如 Bromium 的 vSentry 和 VMware 的 Project Fargo)已經用於在桌面環境中以提供基於硬體的應用程序隔離,所以類似的方法也可以用於 libcontainer,作為 Linux內核中的容器機制的替代技術。
『容器化』 的應用程序
幾乎所有 Linux 應用程序都可以在 Docker 容器中運行,並沒有編程語言或框架的限制。唯一的實際限制是以操作系統的角度來允許容器做什麼。即使如此,也可以在特權模式下運行容器,從而大大減少了限制(與之對應的是容器中的應用程序的風險增加,可能導致損壞主機操作系統)。
容器都是從鏡像開始運行的,而鏡像也可以從運行中的容器獲取。本質上說,有兩種方法可以將應用程序放到容器中,分別是手動構建和 Dockerfile。
手動構建
手動構建從啟動一個基礎的操作系統鏡像開始,然後在互動式終端中用你所選的 Linux 提供的包管理器安裝應用程序及其依賴項。Zef Hemel 在『使用 Linux 容器來支持攜帶型應用程序部署』的文章中講述了他部署的過程。一旦應用程序被安裝之後,容器就可以被推送至註冊庫(例如Docker Hub)或者導出為一個tar文件。
Dockerfile
Dockerfile 是一個用於構建 Docker 容器的腳本化系統。每一個 Dockerfile 定義了開始的基礎鏡像,以及一系列在容器中運行的命令或者一些被添加到容器中的文件。Dockerfile 也可以指定對外的埠和當前工作目錄,以及容器啟動時默認執行的命令。用 Dockerfile 構建的容器可以像手工構建的鏡像一樣推送或導出。Dockerfile 也可以用於 Docker Hub 的自動構建系統,即在 Docker 公司的控制下從頭構建,並且該鏡像的源代碼是任何需要使用它的人可見的。
單進程?
無論鏡像是手動構建還是通過 Dockerfile 構建,有一個要考慮的關鍵因素是當容器啟動時僅啟動一個進程。對於一個單一用途的容器,例如運行一個應用伺服器,運行一個單一的進程不是一個問題(有些關於容器應該只有一個單獨的進程的爭議)。對於一些容器需要啟動多個進程的情況,必須先啟動 supervisor 進程,才能生成其它內部所需的進程。由於容器內沒有初始化系統,所以任何依賴於 systemd、upstart 或類似初始化系統的東西不修改是無法工作的。
容器和微服務
全面介紹使用微服務結構體系的原理和好處已經超出了這篇文章的範疇(在 InfoQ eMag: Microservices 有全面闡述)。然而容器是綁定和部署微服務實例的捷徑。
大規模微服務部署的多數案例都是部署在虛擬機上,容器只是用於較小規模的部署上。容器具有共享操作系統和公用庫的的內存和硬碟存儲的能力,這也意味著它可以非常有效的並行部署多個版本的服務。
連接容器
一些小的應用程序適合放在單獨的容器中,但在許多案例中應用程序需要分布在多個容器中。Docker 的成功包括催生了一連串新的應用程序組合工具、編製工具及平台作為服務(PaaS)的實現。在這些努力的背後,是希望簡化從一組相互連接的容器來創建應用的過程。很多工具也在擴展、容錯、性能管理以及對已部署資產進行版本控制方面提供了幫助。
連通性
Docker 的網路功能是相當原始的。在同一主機,容器內的服務可以互相訪問,而且 Docker 也可以通過埠映射到主機操作系統,使服務可以通過網路訪問。官方支持的提供連接能力的庫叫做 libchan,這是一個提供給 Go 語言的網路服務庫,類似於channels。在 libchan 找到進入應用的方法之前,第三方應用仍然有很大空間可提供配套的網路服務。例如,Flocker 已經採取了基於代理的方法使服務實現跨主機(以及底層存儲)的移植。
合成
Docker 本身擁有把容器連接在一起的機制,與元數據相關的依賴項可以被傳遞到相依賴的容器中,並用於環境變數和主機入口。如 Fig 和 geard 這樣的應用合成工具可以在單一文件中展示出這種依賴關係圖,這樣多個容器就可以匯聚成一個連貫的系統。CenturyLink 公司的 Panamax 合成工具類似 Fig 和 geard 的底層實現方法,但新增了一些基於 web 的用戶介面,並直接與 GitHub 相結合,以便於應用程序分享。
編製
像 Decking、New Relic 公司的 Centurion 和谷歌公司的 Kubernetes 這樣的編製系統都是旨在協助容器的部署和管理其生命周期系統。也有許多 Apache Mesos (特別是 [Marathon(馬拉松式)持續運行很久的框架])的案例(例如Mesosphere)已經被用於配合 Docker 一起使用。通過為應用程序與底層基礎架構之間(例如傳遞 CPU 核數和內存的需求)提供一個抽象的模型,編製工具提供了兩者的解耦,簡化了應用程序開發和數據中心操作。有很多各種各樣的編製系統,因為許多來自內部系統的以前開發的用於大規模容器部署的工具浮現出來了;如 Kubernetes 是基於谷歌的 Omega 系統的,Omega 是用於管理遍布穀歌雲環境中容器的系統。
雖然從某種程度上來說合成工具和編製工具的功能存在重疊,但這也是它們之間互補的一種方式。例如 Fig 可以被用於描述容器間如何實現功能交互,而 Kubernetes pods(容器組)可用於提供監控和擴展。
平台(即服務)
有一些 Docker 原生的 PaaS 服務實現,例如 Deis 和 Flynn 已經顯現出 Linux 容器在開發上的的靈活性(而不是那些「自以為是」的給出一套語言和框架)。其它平台,例如 CloudFoundry、OpenShift 和 Apcera Continuum 都已經採取將 Docker 基礎功能融入其現有的系統的技術路線,這樣基於 Docker 鏡像(或者基於 Dockerfile)的應用程序也可以與之前用支持的語言和框架的開發的應用一同部署和管理。
所有的雲
由於 Docker 能夠運行在任何正常更新內核的 Linux 虛擬機中,它幾乎可以用在所有提供 IaaS 服務的雲上。大多數的主流雲廠商已經宣布提供對 Docker 及其生態系統的支持。
亞馬遜已經把 Docker 引入它們的 Elastic Beanstalk 系統(這是在底層 IaaS 上的一個編製系統)。谷歌使 Docker 成為了「可管理的 VM」,它提供了GAE PaaS 和GCE IaaS 之間的中轉站。微軟和 IBM 也都已經宣布了基於 Kubernetes 的服務,這樣可以在它們的雲上部署和管理多容器應用程序。
為了給現有種類繁多的後端提供可用的一致介面,Docker 團隊已經引進 libswarm, 它可以集成於眾多的雲和資源管理系統。Libswarm 所闡明的目標之一是「通過切換服務來源避免被特定供應商套牢」。這是通過呈現一組一致的服務(與API相關聯的)來完成的,該服務會通過特定的後端服務所實現。例如 Docker 伺服器將支持本地 Docker 命令行工具的 Docker 遠程 API 調用,這樣就可以管理一組服務供應商的容器了。
基於 Docker 的新服務類型仍在起步階段。總部位於倫敦的 Orchard 實驗室提供了 Docker 的託管服務,但是 Docker 公司表示,收購 Orchard 後,其相關服務不會置於優先位置。Docker 公司也出售了之前 DotCloud 的PaaS 業務給 cloudControl。基於更早的容器管理系統的服務例如 OpenVZ 已經司空見慣了,所以在一定程度上 Docker 需要向主機託管商們證明其價值。
Docker 及其發行版
Docker 已經成為大多數 Linux 發行版例如 Ubuntu、Red Hat 企業版(RHEL)和 CentOS 的一個標準功能。遺憾的是這些發行版的步調和 Docker 項目並不一致,所以在發布版中找到的版本總是遠遠落後於最新版本。例如 Ubuntu 14.04 版本中的版本是 Docker 0.9.1,而當 Ubuntu 升級至 14.04.1 時 Docker 版本並沒有隨之升級(此時 Docker 已經升至 1.1.2 版本)。在發行版的軟體倉庫中還有一個名字空間的衝突,因為 「Docker」 也是 KDE 系統托盤的名字;所以在 Ubuntu 14.04 版本中相關安裝包的名字和命令行工具都是使用「Docker.io」的名字。
在企業級 Linux 的世界中,情況也並沒有因此而不同。CentOS 7 中的 Docker 版本是 0.11.1,這是 Docker 公司宣布準備發行 Docker 1.0 產品版本之前的開發版。Linux 發行版用戶如果希望使用最新版本以保障其穩定、性能和安全,那麼最好地按照 Docker 的安裝說明進行,使用 Docker 公司的所提供的軟體庫而不是採用發行版的。
Docker 的到來也催生了新的 Linux 發行版,如 CoreOS 和紅帽的 Project Atomic,它們被設計為能運行容器的最小環境。這些發布版相比傳統的發行版,帶著更新的內核及 Docker 版本,對內存的使用和硬碟佔用率也更低。新發行版也配備了用於大型部署的新工具,例如 fleet(一個分散式初始化系統)和etcd(用於元數據管理)。這些發行版也有新的自我更新機制,以便可以使用最新的內核和 Docker。這也意味著使用 Docker 的影響之一是它拋開了對發行版和相關的包管理解決方案的關注,而對 Linux 內核(及使用它的 Docker 子系統)更加關注。
這些新發行版也許是運行 Docker 的最好方式,但是傳統的發行版和它們的包管理器對容器來說仍然是非常重要的。Docker Hub 託管的官方鏡像有 Debian、Ubuntu 和 CentOS,以及一個『半官方』的 Fedora 鏡像庫。RHEL 鏡像在Docker Hub 中不可用,因為它是 Red Hat 直接發布的。這意味著在 Docker Hub 的自動構建機制僅僅用於那些純開源發行版下(並願意信任那些源於 Docker 公司團隊提供的基礎鏡像)。
Docker Hub 集成了如 Git Hub 和 Bitbucket 這樣源代碼控制系統來自動構建包管理器,用於管理構建過程中創建的構建規範(在Dockerfile中)和生成的鏡像之間的複雜關係。構建過程的不確定結果並非是 Docker 的特定問題——而與軟體包管理器如何工作有關。今天構建完成的是一個版本,明天構建的可能就是更新的版本,這就是為什麼軟體包管理器需要升級的原因。容器抽象(較少關注容器中的內容)以及容器擴展(因為輕量級資源利用率)有可能讓這種不確定性成為 Docker 的痛點。
Docker 的未來
Docker 公司對核心功能(libcontainer),跨服務管理(libswarm) 和容器間的信息傳遞(libchan)的發展上提出了明確的路線。與此同時,該公司已經表明願意收購 Orchard 實驗室,將其納入自身生態系統。然而 Docker 不僅僅是 Docker 公司的,這個項目的貢獻者也來自許多大牌貢獻者,其中不乏像谷歌、IBM 和 Red Hat 這樣的大公司。在仁慈獨裁者、CTO Solomon Hykes 掌舵的形勢下,為公司和項目明確了技術領導關係。在前18個月的項目中通過成果輸出展現了其快速行動的能力,而且這種趨勢並沒有減弱的跡象。
許多投資者正在尋找10年前 VMware 公司的 ESX/vSphere 平台的特徵矩陣,並試圖找出虛擬機的普及而帶動的企業預期和當前 Docker 生態系統兩者的距離(和機會)。目前 Docker 生態系統正缺乏類似網路、存儲和(對於容器的內容的)細粒度版本管理,這些都為初創企業和創業者提供了機會。
隨著時間的推移,在虛擬機和容器(Docker 的「運行」部分)之間的區別將變得沒那麼重要了,而關注點將會轉移到「構建」和「交付」方面。這些變化將會使「Docker發生什麼?」變得不如「Docker將會給IT產業帶來什麼?」那麼重要了。
via: http://www.infoq.com/articles/docker-future
作者:Chris Swan 譯者:disylee 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive