一位開發者的 Linux 容器之旅

Bob Reselman發表於2015-11-17

我告訴你一個秘密:DevOps 雲端計算之類的東西可以把我的程式執行在世界上任何一個地方,這對我來說仍然有一點神秘。但隨著時間流逝,我意識到理解大規模的機器增減和應用程式部署的來龍去脈對一個開發者來說是非常重要的知識。這類似於成為一個專業的音樂家,當然你肯定需要知道如何使用你的樂器,但是,如果你不知道一個錄音棚是如何工作的,或者如何適應一個交響樂團,那麼你在這樣的環境中工作會變得非常困難。

在軟體開發的世界裡,使你的程式碼進入我們的更大的世界如同把它編寫出來一樣重要。DevOps 重要,而且是很重要。

因此,為了彌合開發Dev部署Ops之間的空隙,我會從頭開始介紹容器技術。為什麼是容器?因為有強力的證據表明,容器是機器抽象的下一步:使計算機成為場所而不再是一個東西。理解容器是我們共同的旅程。

在這篇文章中,我會介紹容器化containerization背後的概念。包括容器和虛擬機器的區別,以及容器構建背後的邏輯以及它是如何適應應用程式架構的。我會探討輕量級的 Linux 作業系統是如何適應容器生態系統。我還會討論使用映象建立可重用的容器。最後我會介紹容器叢集如何使你的應用程式可以快速擴充套件。

在後面的文章中,我會一步一步向你介紹容器化一個示例應用程式的過程,以及如何為你的應用程式容器建立一個託管叢集。同時,我會向你展示如何使用 Deis 將你的示例應用程式部署到你本地系統以及多種雲供應商的虛擬機器上。

讓我們開始吧。

虛擬機器的好處

為了理解容器如何適應事物發展,你首先要了解容器的前任:虛擬機器。

虛擬機器 virtual machine(VM)是執行在物理宿主機上的軟體抽象。配置一個虛擬機器就像是購買一臺計算機:你需要定義你想要的 CPU 數目、RAM 和磁碟儲存容量。配置好了機器後,你為它載入作業系統,以及你想讓虛擬機器支援的任何伺服器或者應用程式。

虛擬機器允許你在一臺硬體主機上執行多個模擬計算機。這是一個簡單的示意圖:

虛擬機器可以讓你能充分利用你的硬體資源。你可以購買一臺巨大的、轟隆作響的機器,然後在上面執行多個虛擬機器。你可以有一個資料庫虛擬機器以及很多執行相同版本的定製應用程式的虛擬機器所構成的叢集。你可以在有限的硬體資源獲得很多的擴充套件能力。如果你覺得你需要更多的虛擬機器而且你的宿主硬體還有容量,你可以新增任何你需要的虛擬機器。或者,如果你不再需要一個虛擬機器,你可以關閉該虛擬機器並刪除虛擬機器映象。

虛擬機器的侷限

但是,虛擬機器確實有侷限。

如上面所示,假如你在一個主機上建立了三個虛擬機器。主機有 12 個 CPU,48 GB 記憶體和 3TB 的儲存空間。每個虛擬機器配置為有 4 個 CPU,16 GB 記憶體和 1TB 儲存空間。到現在為止,一切都還好。主機有這個容量。

但這裡有個缺陷。所有分配給一個虛擬機器的資源,無論是什麼,都是專有的。每臺機器都分配了 16 GB 的記憶體。但是,如果第一個虛擬機器永不會使用超過 1GB 分配的記憶體,剩餘的 15 GB 就會被浪費在那裡。如果第三個虛擬機器只使用分配的 1TB 儲存空間中的 100GB,其餘的 900GB 就成為浪費空間。

這裡沒有資源的流動。每臺虛擬機器擁有分配給它的所有資源。因此,在某種方式上我們又回到了虛擬機器之前,把大部分金錢花費在未使用的資源上。

虛擬機器還有另一個缺陷。讓它們跑起來需要很長時間。如果你處於基礎設施需要快速增長的情形,即使增加虛擬機器是自動的,你仍然會發現你的很多時間都浪費在等待機器上線。

來到:容器

概念上來說,容器是一個 Linux 程序,Linux 認為它只是一個執行中的程序。該程序只知道它被告知的東西。另外,在容器化方面,該容器程序也分配了它自己的 IP 地址。這點很重要,重要的事情講三遍,這是第二遍。在容器化方面,容器程序有它自己的 IP 地址。一旦給予了一個 IP 地址,該程序就是宿主網路中可識別的資源。然後,你可以在容器管理器上執行命令,使容器 IP 對映到主機中能訪問公網的 IP 地址。建立了該對映,無論出於什麼意圖和目的,容器就是網路上一個可訪問的獨立機器,從概念上類似於虛擬機器。

這是第三遍,容器是擁有不同 IP 地址從而使其成為網路上可識別的獨立 Linux 程序。下面是一個示意圖:

容器/程序以動態、合作的方式共享主機上的資源。如果容器只需要 1GB 記憶體,它就只會使用 1GB。如果它需要 4GB,就會使用 4GB。CPU 和儲存空間利用也是如此。CPU、記憶體和儲存空間的分配是動態的,和典型虛擬機器的靜態方式不同。所有這些資源的共享都由容器管理器來管理。

最後,容器能非常快速地啟動。

因此,容器的好處是:你獲得了虛擬機器獨立和封裝的好處,而拋棄了靜態資源專有的缺陷。另外,由於容器能快速載入到記憶體,在擴充套件到多個容器時你能獲得更好的效能。

容器託管、配置和管理

託管容器的計算機執行著被剝離的只剩下主要部分的某個 Linux 版本。現在,宿主計算機流行的底層作業系統是之前提到的 CoreOS。當然還有其它,例如 Red Hat Atomic HostUbuntu Snappy

該 Linux 作業系統被所有容器所共享,減少了容器足跡的重複和冗餘。每個容器只包括該容器特有的部分。下面是一個示意圖:

你可以用它所需的元件來配置容器。一個容器元件被稱為layer。層是一個容器映象,(你會在後面的部分看到更多關於容器映象的介紹)。你從一個基本層開始,這通常是你想在容器中使用的作業系統。(容器管理器只提供你所要的作業系統在宿主作業系統中不存在的部分。)當你構建你的容器配置時,你需要新增層,例如你想要新增網路伺服器時這個層就是 Apache,如果容器要執行指令碼,則需要新增 PHP 或 Python 執行時環境。

分層非常靈活。如果應用程式或者服務容器需要 PHP 5.2 版本,你相應地配置該容器即可。如果你有另一個應用程式或者服務需要 PHP 5.6 版本,沒問題,你可以使用 PHP 5.6 配置該容器。不像虛擬機器,更改一個版本的執行時依賴時你需要經過大量的配置和安裝過程;對於容器你只需要在容器配置檔案中重新定義層。

所有上面描述的容器的各種功能都由一個稱為容器管理器container manager的軟體控制。現在,最流行的容器管理器是 DockerRocket。上面的示意圖展示了容器管理器是 Docker,宿主作業系統是 CentOS 的主機情景。

容器由映象構成

當你需要將我們的應用程式構建到容器時,你就要編譯映象。映象代表了你的容器需要完成其工作的容器模板。(容器裡可以在容器裡面,如下圖)。映象儲存在註冊庫registry中,註冊庫透過網路訪問。

從概念上講,註冊庫類似於一個使用 Java 的人眼中的 Maven 倉庫、使用 .NET 的人眼中的 NuGet 伺服器。你會建立一個列出了你應用程式所需映象的容器配置檔案。然後你使用容器管理器建立一個包括了你的應用程式程式碼以及從容器註冊庫中下載的部分資源。例如,如果你的應用程式包括了一些 PHP 檔案,你的容器配置檔案會宣告你會從註冊庫中獲取 PHP 執行時環境。另外,你還要使用容器配置檔案宣告需要複製到容器檔案系統中的 .php 檔案。容器管理器會封裝你應用程式的所有東西為一個獨立容器,該容器將會在容器管理器的管理下執行在宿主計算機上。

這是一個容器建立背後概念的示意圖:

讓我們仔細看看這個示意圖。

(1)代表一個定義了你容器所需東西以及你容器如何構建的容器配置檔案。當你在主機上執行容器時,容器管理器會讀取該配置檔案,從雲上的註冊庫中獲取你需要的容器映象,(2)將映象作為層新增到你的容器中。

另外,如果組成映象需要其它映象,容器管理器也會獲取這些映象並把它們作為層新增進來。(3)容器管理器會將需要的檔案複製到容器中。

如果你使用了配置provisioning服務,例如 Deis,你剛剛建立的應用程式容器做成映象,(4)配置服務會將它部署到你選擇的雲供應商上,比如類似 AWS 和 Rackspace 雲供應商。

叢集中的容器

好了。這裡有一個很好的例子說明了容器比虛擬機器提供了更好的配置靈活性和資源利用率。但是,這並不是全部。

容器真正的靈活是在叢集中。記住,每個容器有一個獨立的 IP 地址。因此,能把它放到負載均衡器後面。將容器放到負載均衡器後面,這就上升了一個層面。

你可以在一個負載均衡容器後執行容器叢集以獲得更高的效能和高可用計算。這是一個例子:

假如你開發了一個資源密集型的應用程式,例如圖片處理。使用類似 Deis 的容器配置技術,你可以建立一個包括了你圖片處理程式以及你圖片處理程式需要的所有資源的容器映象。然後,你可以部署一個或多個容器映象到主機上的負載均衡器下。一旦建立了容器映象,你可以隨時使用它。當系統繁忙時可以新增更多的容器例項來滿足手中的工作。

這裡還有更多好訊息。每次新增例項到環境中時,你不需要手動配置負載均衡器以便接受你的容器映象。你可以使用服務發現技術讓容器告知均衡器它可用。然後,一旦獲知,均衡器就會將流量分發到新的結點。

全部放在一起

容器技術完善了虛擬機器缺失的部分。類似 CoreOS、RHEL Atomic、和 Ubuntu 的 Snappy 宿主作業系統,和類似 Docker 和 Rocket 的容器管理技術結合起來,使得容器變得日益流行。

儘管容器變得更加越來越普遍,掌握它們還是需要一段時間。但是,一旦你懂得了它們的竅門,你可以使用類似 Deis 這樣的配置技術使容器建立和部署變得更加簡單。

從概念上理解容器和進一步實際使用它們完成工作一樣重要。但我認為不實際動手把想法付諸實踐,概念也難以理解。因此,我們該系列的下一階段就是:建立一些容器。


via: https://deis.com/blog/2015/developer-journey-linux-containers

作者:Bob Reselman 譯者:ictlyh 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出

相關文章