開發者的 Linux 容器之旅
我告訴你一個秘密:使得我的應用程序進入到全世界的所有云計算的東西,對我來說仍然有一點神秘。但隨著時間流逝,我意識到理解大規模機器配置和應 用程序部署的來龍去脈對一個開發者來說是非常重要的知識。這類似于成為一個專業的音樂家。你當然需要知道如何使用你的樂器。但是,如果你不知道一個錄音室 是如何工作的,或者你如何適應一個交響樂團,你在這樣的環境中工作會變得非常困難。
在軟件開發的世界里,使你的代碼進入我們更大的世界正如寫出它來一樣重要。開發重要,而且是很重要。
因此,為了彌合開發和部署之間的間隔,我會從頭開始介紹容器技術。為什么是容器?因為有強有力的證據表明,容器是機器抽象的下一步:使計算機成為場所而不再是一個東西。理解容器是我們共同的旅程。
在這篇文章中,我會介紹容器化背后的概念。容器和虛擬機的區別。以及容器構建背后的邏輯以及它是如何適應應用程序架構的。我會探討輕量級的 Linux 操作系統是如何適應容器生態系統。我還會討論使用鏡像創建可重用的容器。最后我會介紹容器集群如何使你的應用程序可以快速擴展。
在后面的文章中,我會一步一步向你介紹容器化一個事例應用程序的過程,以及如何為你的應用程序容器創建一個托管集群。同時,我會向你展示如何使用 Deis 將你的事例應用程序部署到你本地系統以及多種云供應商的虛擬機上。
讓我們開始吧。
虛擬機的好處
為了理解容器如何適應事物發展,你首先要了解容器的前者:虛擬機
虛擬機 是運行在物理宿主機上的軟件抽象。配置一個虛擬機就像是購買一臺計算機:你需要定義你想要的 CPU 數目,RAM 和磁盤存儲容量。配置好了機器后,你把它加載到操作系統,然后是你想讓虛擬機支持的任何服務器或者應用程序。
虛擬機允許你在一臺硬件主機上運行多個模擬計算機。這是一個簡單的示意圖:
虛擬機使得能充分利用你的硬件資源。你可以購買一臺大型機然后在上面運行多個虛擬機。你可以有一個數據庫虛擬機以及很多運行相同版本定制應用程序 的虛擬機構成的集群。你可以在有限的硬件資源獲得很多的擴展能力。如果你覺得你需要更多的虛擬機而且你的宿主硬件還有容量,你可以添加任何你想要的。或 者,如果你不再需要一個虛擬機,你可以關閉該虛擬機并刪除虛擬機鏡像。
虛擬機的局限
但是,虛擬機確實有局限。
如上面所示,假如你在一個主機上創建了三個虛擬機。主機有 12 個 CPU,48 GB 內存和 3TB 的存儲空間。每個虛擬機配置為有 4 個 CPU,16 GB 內存和 1TB 存儲空間。到現在為止,一切都還好。主機有這個容量。
但這里有個缺陷。所有分配給一個虛擬機的資源,無論是什么,都是專有的。每臺機器都分配了 16 GB 的內存。但是,如果第一個虛擬機永不會使用超過 1GB 分配的內存,剩余的 15 GB 就會被浪費在那里。如果第三天虛擬機只使用分配的 1TB 存儲空間中的 100GB,其余的 900GB 就成為浪費空間。
這里沒有資源的流動。每臺虛擬機擁有分配給它的所有資源。因此,在某種方式上我們又回到了虛擬機之前,把大部分金錢花費在未使用的資源上。
虛擬機還有 另一個 缺陷。擴展他們需要很長時間。如果你處于基礎設施需要快速增長的情形,即使虛擬機配置是自動的,你仍然會發現你的很多時間都浪費在等待機器上線。
來到:容器
概念上來說,容器是 Linux 中認為只有它自己的一個進程。該進程只知道告訴它的東西。另外,在容器化方面,該容器進程也分配了它自己的 IP 地址。這點很重要,我會再次重復。 在容器化方面,容器進程有它自己的 IP 地址 。一旦給予了一個 IP 地址,該進程就是宿主網絡中可識別的資源。然后,你可以在容器管理器上運行命令,使容器 IP 映射到主機中能訪問公網的 IP 地址。該映射發生時,對于任何意圖和目的,一個容器就是網絡上一個可訪問的獨立機器,概念上類似于虛擬機。
再次說明,容器是擁有不同 IP 地址從而使其成為網絡上可識別的獨立 Linux 進程。下面是一個示意圖:
容器/進程以動態合作的方式共享主機上的資源。如果容器只需要 1GB 內存,它就只會使用 1GB。如果它需要 4GB,就會使用 4GB。CPU 和存儲空間利用也是如此。CPU,內存和存儲空間的分配是動態的,和典型虛擬機的靜態方式不同。所有這些資源的共享都由容器管理器管理。
最后,容器能快速啟動。
因此,容器的好處是: 你獲得了虛擬機獨立和封裝的好處而拋棄了專有靜態資源的缺陷 。另外,由于容器能快速加載到內存,在擴展到多個容器時你能獲得更好的性能。
容器托管、配置和管理
托管容器的計算機運行著被剝離的只剩下主要部分的 Linux 版本。現在,宿主計算機流行的底層操作系統是上面提到的 CoreOS 。當然還有其它,例如 Red Hat Atomic Host 和 Ubuntu Snappy 。
所有容器之間共享Linux 操作系統,減少了容器足跡的重復和冗余。每個容器只包括該容器唯一的部分。下面是一個示意圖:
你用它所需的組件配置容器。一個容器組件被稱為 層 。一層是一個容器鏡像,(你會在后面的部分看到更多關于容器鏡像的介紹)。你從一個基本層開始,這通常是你想在容器中使用的操作系統。(容器管理器只提供 你想要的操作系統在宿主操作系統中不存在的部分。)當你構建配置你的容器時,你會添加層,例如你想要添加網絡服務器 Apache,如果容器要運行腳本,則需要添加 PHP 或 Python 運行時。
分層非常靈活。如果應用程序或者服務容器需要 PHP 5.2 版本,你相應地配置該容器即可。如果你有另一個應用程序或者服務需要 PHP 5.6 版本,沒問題,你可以使用 PHP 5.6 配置該容器。不像虛擬機,更改一個版本的運行時依賴時你需要經過大量的配置和安裝過程;對于容器你只需要在容器配置文件中重新定義層。
所有上面描述的容器多功能性都由一個稱為容器管理器的軟件控制。現在,最流行的容器管理器是 Docker 和 Rocket 。上面的示意圖展示了容器管理器是 Docker,宿主操作系統是 CentOS 的主機情景。
容器由鏡像構成
當你需要將我們的應用程序構建到容器時,你就會編譯鏡像。鏡像代表了需要完成容器工作的容器模板。(容器里的容器)。鏡像被保存在網絡上的注冊表里。
從概念上講,注冊表類似于一個使用 Java 的人眼中的 Maven 倉庫,使用 .NET 的人眼中的 NuGet 服務器。你會創建一個列出了你應用程序所需鏡像的容器配置文件。然后你使用容器管理器創建一個包括了你應用程序代碼以及從注冊表中下載的構成資源的容器。 例如,如果你的應用程序包括了一些 PHP 文件,你的容器配置文件會聲明你會從注冊表中獲取 PHP 運行時。另外,你還要使用容器配置文件聲明需要復制到容器文件系統中的 .php 文件。容器管理器會封裝你應用程序的所有東西為一個獨立容器。該容器將會在容器管理器的管理下運行在宿主計算機上。
這是一個容器創建背后概念的示意圖:
讓我們仔細看看這個示意圖。
(1)表示一個定義了你容器所需東西以及你容器如何構建的容器配置文件。當你在主機上運行容器時,容器管理器會讀取配置文件從云上的注冊表中獲取你需要的容器鏡像,(2)作為層將鏡像添加到你的容器。
另外,如果組成鏡像需要其它鏡像,容器管理器也會獲取這些鏡像并把它們作為層添加進來。(3)容器管理器會將需要的文件復制到容器中。
如果你使用了配置服務,例如 Deis ,你剛剛創建的應用程序容器作為鏡像存在(4)配置服務會將它部署到你選擇的云供應商上。類似 AWS 和 Rackspace 云供應商。
集群中的容器
好了。這里有一個很好的例子說明了容器比虛擬機提供了更好的配置靈活性和資源利用率。但是,這并不是全部。
容器真正靈活是在集群中。記住,每個容器有一個獨立的 IP 地址。因此,能把它放到負載均衡器后面。將容器放到負載均衡器后面,就上升了一個層次。
你可以在一個負載均衡容器后運行容器集群以獲得更高的性能和高可用計算。這是一個例子:
假如你開發了一個進行資源密集型工作的應用程序。例如圖片處理。使用類似 Deis 的容器配置技術,你可以創建一個包括了你圖片處理程序以及你圖片處理程序需要的所有資源的容器鏡像。然后,你可以部署一個或多個容器鏡像到主機上的負載均衡器。一旦創建了容器鏡像,你可以在系統快要刷爆時把它放到一邊,為了滿足手中的工作時添加更多的容器實例。
這里還有更多好消息。你不需要每次添加實例到環境中時手動配置負載均衡器以便接受你的容器鏡像。你可以使用服務發現技術告知均衡器你容器的可用性。然后,一旦獲知,均衡器就會將流量分發到新的結點。
全部放在一起
容器技術完善了虛擬機不包括的部分。類似 CoreOS、RHEL Atomic、和 Ubuntu 的 Snappy 宿主操作系統,和類似 Docker 和 Rocket 的容器管理技術結合起來,使得容器變得日益流行。
盡管容器變得更加越來越普遍,掌握它們還是需要一段時間。但是,一旦你懂得了它們的竅門,你可以使用類似 Deis 的配置技術使容器創建和部署變得更加簡單。
概念上理解容器和進一步實際使用它們完成工作一樣重要。但我認為不實際動手把想法付諸實踐,概念也難以理解。因此,我們該系列的下一階段就是:創建一些容器。
Reference:
https://deis.com/blog/2015/developer-journey-linux-containers