Container:Docker、Windows 以及趨勢

最近,談論到雲端運算時絕對少不了 container 這個話題。從銀行、主要金融服務機構到電子商務網站等等的所有相關產業,大家都想要瞭解什麼是 container、對雲端應用程式有何意義、如何才能在其特定開發與 IT 相關作業中發揮最大作用。

這篇文章介紹了,從 container 基本概念和運作方式,以及現在最廣泛使用的方式,再到支援「containerization」的新興趨勢,期望能協助大家瞭解如何以最佳方式掌握這個重要雲端發展,並進一步完美的建構、測試、部署及管理您的雲端應用程式。

Container 概述

以抽象概念來說,運算的本身是指一些「功能」在處理器、記憶體、磁碟、網路等組合的「實體資源」上執行的這一個動作,不論是簡單的1+1數學計算,或是如「Exchange」般橫跨多部機器的複雜應用程式,都在運算的範圍內。

隨著科技的進步,實體資源越趨強大,然而應用程式通常僅僅是運用到實體機器所提供的一小部分資源。因此創造出「虛擬」資源用來模擬本體的實體硬體,並且使多個應用程式能夠同時執行 – 分別使用同一部實體機器的小部分實體資源。

我們通常將這些模擬技術稱為「虛擬化」。許多人一聽到虛擬化就會立刻想到虛擬機器 (VM),不過那只是虛擬化之中的一種實現方式。虛擬記憶體,是一種所有一般用途作業系統 (OS) 採用的機制,可以讓應用程式「以為」是其專屬的電腦記憶體,甚至讓應用程式能夠存取的記憶體遠高於電腦本身所配備的記憶體。

Container 是另一種類型的虛擬化,也可稱為作業系統虛擬化。現在,Linux 上的 container 已經能夠完全隔離,並且使作業系統與應用程式各自獨立。對執行中的 container 而言,本機磁碟就如同是作業系統檔案的原始副本,記憶體的作用僅在保留新進啟動的作業系統,而唯一在執行的就是作業系統。為達此目的,用於建立 container 的「主機」機器需要具備新穎的執行機制。

第一項技術是命名空間隔離。命名空間包含應用程式可與之互動的所有資源,例如:檔案、網路連接埠以及執行程序清單。命名空間隔離可供主機給予各 container 一個虛擬化命名空間,其中僅包含該 container 內可見的資源。

在此有限的能見度之下,無論 container 本身的權限為何,也無法存取不屬於其虛擬化命名空間的檔案,因為根本看不見,當然也無法列出或處理不屬於此 container 的應用程式,如此一來,即使系統內有數十個或數百個其他應用程式正在執行,container 會使應用程式「認為」自己是系統中唯一執行的應用程式。

為了追求效率,許多的作業系統檔案、目錄及執行中服務會共享於各 container 之間,並投射到各 container 的命名空間。只有在應用程式對其 container 進行變更時,例如修改現有檔案或建立新檔案時,container 才會衍生出和本體主機作業系統不同的副本 – 但僅限於變更的部分,使用 Docker 的「寫入時複製」最佳化功能。

第二,主機將控制可供 container 使用的主機資源量。亦即管理如 CPU、RAM、網路頻寬等資源,以確保container可獲得所需的資源且不致影響主機上其他正在執行的 container 的效能。

例如,可限制某一 container 不得使用超過 CPU 10% 的資源。也就是說,應用程式無論如何也不會越界使用到另外 90% 的資源,因為這些資源是由主機指派給其他 container 使用或是供主機本身使用。Linux 是採用名為「cgroups」的技術管理資源。若位於同一主機內的 container 相互合作,且容許標準作業系統動態資源指派可適應應用程式碼的變更需求,則不需要管理資源。

來自作業系統的迅速啟動加上來自命名空間隔離與資源管理的可靠執行,使 container 成為應用程式開發及測試最佳的環境。開發流程期間,開發人員能夠快速的反覆執行。由於環境與資源運用在各系統內均一致,能在開發人員系統內執行的 container 應用程式,也能在不同系統中運作。

快速啟動及佔用資源小的優點極適合於雲端應用,因為應用程式能夠迅速的向外延展,而且能夠融入一部機器內的應用程式數量會遠高於各在一部虛擬機器內的數量,使資源的運用達到最大化。

一般虛擬機器與使用 container 的虛擬機器兩相比較,就可發現共享所能提供的高效率優點。在下圖範例中,主機機器內擁有三部虛擬機器。為使虛擬機器內應用程式完全隔離,每一部虛擬機器必須擁有自己的作業系統檔案、程式庫及應用程式碼的副本,還要包含作業系統的完整記憶體內儲例項。建立新的虛擬機器時需要啟動另一個作業系統例項 – 即使主機或現有虛擬主機已執行相同版本的例項,同時還需將應用程式庫載入記憶體內。每一部應用程式虛擬機器都需要為自用的副本負擔作業系統啟動及記憶體內儲的資源,因而限制了主機上能夠執行的應用程式 (虛擬機器) 數量。

下圖是使用 container 的範例。在這邊,container 可以簡單的共享主機作業系統,包括核心及程式庫,因此不需要再另外啟動一套作業系統、載入程式庫或為這些檔案負擔記憶體的資源,佔用的空間也僅限於 container 內執行的應用程式所需要的記憶體與磁碟空間。由於應用程式的環境如同專用的作業系統,使得應用程式的部署也如同於專用的主機上部署一般。Containerization 的應用程式能迅速啟動,一部機器上能容納的應用程式例項也遠高於一般虛擬機器。

Docker 的訴求

關於作業系統的命名空間隔離及資源管理已是老生常談,可以追溯至 BSD Jails、Solaris Zones 甚至是最基本的 UNIX chroot 機制。然而,透過建立共同工具組、封裝模型及部署機制,Docker 大幅簡化了 containerization 及應用程式的分配,使應用程式能在任何 Linux 主機的任何地方執行。這項隨處分佈的技術不僅透過任何主機均相同的管理指令簡化了管理作業,更為完美的 DevOps 創造了獨特的機會。

從開發人員的桌面到一部測試機器再到一組生產機器,建立的 Docker 映像亦可迅速完整部署至任何作業環境。此一作法已經為 Dockercontainer 內所封裝應用程式建立起龐大、持續成長的生態系統,透過 DockerHub,由 Docker 維持的公共 containerization 應用程式登錄,目前在公共社群資料庫中已發佈 180,000 項以上的應用程式。此外,為維持保障封裝格式的通用性,Docker 最近組織了「開放式 container 聯盟」(OCI),目的在於確保 container 封裝維持其開放性與基層導引型格式,Microsoft 就是其中之一的創立成員。

Windows Server 及 Containers

為將強大的 container 提供給所有開發人員,去年 10 月微軟發佈了將 container 技術納入 Windows Server 的計畫。同時,為了使用 Linux Dockercontainer 的開發人員能夠在 Windows Server 上擁有相同體驗,我們也宣佈與 Docker 成為合作夥伴以延伸 Docker API 及工具組來支援 Windows Server Containers。對我們而言,這是一個服務所有 Linux 及 Windows 客戶的絕佳機會。最近於 DockerCon 展示時,我們非常高興能建立開發人員與系統管理人員的一致性、開放性體驗,共同部署由 Windows Server 及 Linux 所組成的 container 化應用程式。我們正在開放性 Docker GitHub 資料庫中發展這項作業。

在 Windows Server 2016 中,我們將釋出兩款均可使用 Docker API 及 Docker 用戶端部署的 container:Windows Server Containers 及 Hyper-V Containers。由於 Linuxcontainer 需要來自主機核心的 Linux API,Windows Server Containers 需要主機 Windows 核心的 Windows API,因此無法於 Windows Server 主機上執行 Linuxcontainer,也無法於 Linux 主機上執行 Windows Server Container。

但是,相同的 Docker 用戶端可以管理所有的這些 container,雖不能在 Linux 上執行套裝的 Windowscontainer,Windowscontainer 套件卻可於 Windows Server Containers 及 Hyper-V Containers 上運作,因為兩款 container 都是使用 Windows 核心。

也有人提到 Windows Server Container 和 Hyper-V Container 使用時機的這個問題。由於核心的共享可提供快速啟動及高效率封裝,Windows Server Containers 可以和主機與其他 container 共享作業系統。共享資料及 API 代表著可能有數種途徑,可以是利用設計或因為命名空間隔離或資源管理中出現的瑕疵,使應用程式跳出其 container 或拒絕服務至主機或其他 container。而作業系統供應商所發佈用於加強本機權限弱點的修補程式,就是一個應用程式可以利用的瑕疵。

因此,當作業系統信任在其中執行的應用程式且所有應用程式彼此信任時,Windows Server Containers 是最佳選擇。換句話說,主機作業系統及應用程式均在相同的信任範疇之中。對於許多多重 container 應用程式、組成大型應用程式共享服務的應用程式、部分來自相同組織的應用程式而言,確是如此。

然而在某些狀況下,可能需要在同一部主機上執行來自不同信任範疇的應用程式。舉例來說,如果您正在實施多組織用戶共享的 PaaS 或 SaaS,以利客戶們供應其本身的程式碼來擴充您的服務的功能性。您不會希望一位客戶的程式碼干擾到您的服務或取得其他客戶資料的存取權,但是您會需要一個比虛擬機器更彈性且能擁有 Docker 生態系統優點的 container。

在 Azure 中我們有多個這樣的例子,像是 Azure Automation 及 Machine Learning。我們稱此執行環境為「惡意多重租用」,因為我們必須假設有客戶是刻意的尋找著破壞隔離的方法。在這些類型的環境中,Windows Server Containers 可能無法提供足夠的保障,因而促使了我們開發 Hyper-V Containers。

Hyper-V Containers 採用了作法稍有不同的 containerization。為建立更完善的隔離,每一個 Hyper-V Containers 均擁有自己的 Windows 核心副本,也擁有直接分配的記憶體 – 強力隔離的關鍵需求。我們在 CPU、記憶體、IO 隔離上使用 Hyper-V (如同網路及儲存設備),提供和虛擬機器相同程度的隔離。如同用於虛擬機器,主機僅釋出小量、受限制的介面給 container,用於通訊及共享主資資源。高限制的共享表示 Hyper-V Containers 的啟動時間效率及分佈密度會稍低於 Windows Server Containers,但能提供允許非信任及「惡意多重租用」應用程式於同一部主機上執行時所需的隔離。

那麼 Hyper-V Containers 不是和虛擬機器一樣嗎?除了已知的作業系統最佳化之外,請注意 Hyper-V Containers 是 container 而不是實體機器,不僅可以透過 Docker 的強大功能部署,而且使用的套件和 Windows Server Containers 所使用的套件完全相同。因此,隔離程度與效率 / 彈性的取捨是部署時間決策而非開發時間決策 – 由主機擁有人所決定。

協調流程

在採納 container 之後,客戶們發現了一項難題。當他們部署數十、數百或數千應用程式的 container 時,追蹤及管理部署需要先進的管理與協調流程。

Container 協調流程已成為多重選項及解決方案創新的新興領域。Container 協調流程程式接受指派一群伺服器 (虛擬機器或裸機伺服器),通常稱為「叢集」,並將 container 的「排程」部署在這些伺服器上。

部分協調流程程式更進一步的用於設定不同伺服器上 container 之間的網路作業,其他也用於負載平衡、container 名稱解析、輪替更新等等。部分協調流程程式可擴充並啟用應用程式架構帶入這些額外的功能。

協調流程解決方案可能會需要更深入的討論,在此僅快速瀏覽其中部分用於支援 Azure 的技術:

  1. Docker Compose 用於定義簡單的多 container 應用程式。Docker Swarm 則透過單一 Docker 主機所使用的同一 API 管理及組織橫跨多部主機的 Dockercontainer。Swarm 及 Compose 的組合可提供由 Docker 所建構的完整協調流程技術
  2. Mesos 是一套可實際預先更新 Docker 的協調流程及管理解決方案,最近更新增支援 Docker 功能至其內建的應用程式架構 Marathon。這是一套由 Mesosphere 所建構的開放式、社群推動型解決方案。我們最近展示了 Mesos and DCOS on Azure 的整合作業。
  3. Kubernetes 是一套由 Google 建構的開放原始碼解決方案,提供 container 群組為用於管理多部主機的「Pods」。Azure 上也支援此技術
  4. Deis 是一個開放原始碼 PaaS 平台,用於部署及管理 Docker 所整合的應用程式。我們已經有了在 Azure 上輕鬆部署 Deis 叢集的方式

對於大多數受歡迎的協調流程解決方案能夠支援 Azure,我們感到非常高興,也期望在大家越加關注及使用率提升之際能多多結合這些社群。

Microservices

Container 更切身的用法已聚焦於簡化 DevOps,使開發人員能更輕鬆的測試雲端或內部部署的各項服務生產流程。但是另一股不斷成長的趨勢使得 container 越發引人注目。

Microservices 是一種應用程式開發的途徑,其中應用程式每一部分均以完全自足組件的方式部署,稱為能夠個別擴充及更新的 Microservices。例如,由公共網路接收要求的應用程式子系統,可能不同於將要求置入佇列以供後端子系統讀取並放入資料庫的子系統。當應用程式使用 Microservices 建構時,各子系統即是一項 Microservices。

在單一區塊開發 / 測試環境中,Microservices 可能各自擁有一例項,但在生產執行時則能各自向外延展至一伺服器叢集內不同數量的例項,視客戶要求程度起伏的資源需求而定。若是由不同的序列產生,則該序列也獨立負責給予更新。

Microservices 既不是新的程式規劃方法,也不是 container 專屬,但在應用至 Microservices 應用程式時卻能突顯出 Dockercontainer 的優點。

彈性,代表 Microservices 能迅速向外延展以因應提高的負載,container 的命名空間及資源隔離則可防止一個 Microservices 例項干擾其他例項,並使用 Docker 封裝格式及API為 Microservices 開發人員及應用程式操作人員解鎖 Docker 生態系統。

在擁有良好 Microservices 架構之下,客戶能解決 container 型服務的管理、部署、協調流程與修補作業需求,同時也降低可用性流失的風險並維持高度的彈性。

現在有許多使用 Microservices 建構應用程式模型的解決方案,我們也在 Azure 上建立不少合作對象。Docker Compose 和 Mesosphere Marathon 就是兩個最好的例子。在開始建構的不久前,我們宣佈並釋出 Service Fabric 的開發人員預覽,Service Fabric 是我們自有的 Microservices 應用程式平台。其中包含豐富的 Microservices 生命週期管理功能,更包括有復原功能的輪替更新、分割、附加限制等等。

值得注意的是,除了無狀態的 Microservices 之外,也支援可設定狀態的 Microservices,區分的方式是利用 Microservices 管理同是共處於同一伺服器上的資料。事實上,Service Fabric 是唯一提供可設定狀態 Microservices 的 PaaS 平台,採用的狀態管理及複製架構已直接內建於其叢集管理之中。

我們開發此應用程式模型是為了使內部服務能夠擴充至超大規模,並提供可設定狀態複製及 Cortana、Azure SQL Database、Skype for Business 等服務建構於其上。我們計畫於今年內釋出 Service Fabric 的公開預覽,在那之前,歡迎登入 Service Fabric 專屬網站瞭解詳情。

希望這篇文章能協助大家描繪出 Microsoft 的 container 願景、最常見的 container 應用案例以及與 container 相關的新興產業趨勢。如同以往,我們非常歡迎您提供意見,尤其是提出您想瞭解更多的部分。

原文出處:https://azure.microsoft.com/blog/2015/08/17/containers-docker-windows-and-trends/