1. 程式人生 > >Docker該如何得到開發者和系統管理員的共同認可

Docker該如何得到開發者和系統管理員的共同認可

將Docker作為應用程式容器管理系統已經在最近兩年當中成為眾多開發人員及系統工程師們的標準實踐方式。有一部分朋友甚至表示,容器方案是自 OpenSSH之後最為可觀且值得肯定的技術飛躍。Docker目前已經成為技術領域當之無愧的新生力量,且被廣泛應用於各類雲系統架構當中。然而除此之 外,Docker還需要了解如何贏得開發人員們的芳心。

下面我們將一起了解Docker的發展歷程,未來將要面對的競爭形勢以及對發展前景的預估。

那麼,Docker到底是什麼?

Docker是一款使用libcontainer的微容器管理工具。作為Solomon Hykes利用Go語言開發而成的專案,Docker於2013年轉入開源並被快速應用在諸多領域當中。這款工具的出色靈活性甚至使其成為遊戲規則的改變者。

在Docker出現之前,建立一套應用程式容器需要掌握多種相對比較先進的概念。LXC已經在這一領域佔據了相當可觀的市場份額,其賣點在於提供 “純虛擬化”解決方案並藉此賺取利潤。OpenVZ與Xen也在市場上擁有一定地位。不過這些系統在設計方面仍然很大程度上面向伺服器解決方案,而且需要 配合相當程度的配置工作。

這裡我們要澄清一點:Docker的作用並不是取代LXC、OpenVZ或者Xen。它也並不是一套像KVM、VirtualBox以及VMware那樣的虛擬化解決方案。Docker擁有屬於自己的定位視角、獨特的運作方式而且具備完全不同的功能出發點。

與OpenVZ、Xen以及LXC一樣,Docker也採用rootfs原則——這實際上就是一套root檔案系統。它採用樹狀結構作為遠端系統的root(類似於chroot的作用),同時提供網路層與設定系統。但它同時也有著自己的一些獨特設計。

首先,它的映象與容器通過union mount檔案系統(例如aufs以及devicemapper等)進行分層。這一方面節約了磁碟儲存空間,另一方面也能夠幫助我們在無需複製整套root的前提下快速構建容器環境。

另一大差異在於,Docker迴避了訪客系統當中的初始化步驟。換句話來說,容器的root只會被用作指定應用程式的執行環境。

最後,Docker擁有對映象版本的註冊與控制能力,這也正是其步入標準化的重要標誌。在預設情況下,Docker會使用公共登錄檔。該登錄檔提供多套現成可用的映象(既包括官方給出的正式映象,亦擁有由社群使用者提交的映象),同時也為後續付費提供了實現空間。從理論層面講,Docker在很大程度 上與Git類似,而其Hub則類似於GitHub這樣的服務方案。Docker同時採用多種常見概念,例如提交、標籤以及遠端註冊伺服器等等。

圍繞Docker專案建立起的技術社群非常活躍,其中提供大量用於自動啟動(fig,也就是現在的Docker Compose)、簡化雲集成及管理流程(CoreOS)以及實現監控任務(cAdvisor)的工具,而且這份工具清單還在不斷拓展。

時至今日,Docker已經席捲了整個IT領域。OpenStack、Amazon、谷歌、CoreOS等等都在高度關注這項技術成果,甚至已經將其整合到了自己的基礎設施當中。

不過激烈的市場競爭也即將到來!

提高系統便捷度

Docker的主要訴求無疑在於簡化容器建立流程,從而更為便捷地實現微服務架構管理。首先需要強調的是,容器本身其實是一種對應用程式進行完全隔 離的手段。歸功於其libcontainer庫,Docker能夠在整個cgroup管理流程當中始終實現記憶體與執行緒的徹底隔離。

除非使用者進行特殊指定,否則Docker不會開啟主機裝置上的任何一個埠。如果兩套容器系統需要通過IP層進行通訊,它們可以彼此連通,從而直接利用容器名稱而非IP地址實現資訊互動(因為IP地址可能隨著容器重啟而發生變化)。

雲規模伸縮

Docker已經在雲環境下獲得極高人氣,這主要是由於其極低的執行資源需求、出色的分卷管理以及能夠顯著降低磁碟儲存空間需求的union mount檔案系統。在研究Docker運作機制的過程當中,大家會發現我們能夠非常輕鬆地利用它創建出一套具備可擴充套件性且/或高可用性的系統方案。

“docker”命令實際上是一種簡單的REST客戶端,旨在同daemon進行通訊。在預設情況下,該服務(daemon)會建立一個unix socket(位置為/var/run/docker.sock)來提供該API。而“docker”命令將僅僅使用該API。

該API可以被用於監聽各類事件,包括容器何時建立、啟用或者停止。利用該API所提供的資訊,大家能夠輕鬆掌握哪套容器系統目前正在執行哪種服務並使用哪個埠等等。

如果大家不打算或者沒有能力使用CoreOS、OpenStack等所要求的架構,那麼也完全可以建立自己的架構及工具——而且整個過程並不困難。該API相當易於訪問且效率極高。

下面請大家一起來看我們當前專案中的一個架構示例:

Docker如何得到開發者和系統管理員的共同認可

我們採取以下規劃方式:

  • 每臺物理從伺服器都配備有一項發現服務,用於監聽該Dockers socket。
  • 當某套容器系統啟用或者停止時,該服務會將資訊傳送至主伺服器。

該主伺服器隨後能夠採納適當的措施,例如修改nginx伺服器配置或者刪除/移除一臺上流伺服器等。

另一種選項則是對Docker的配置進行修改,從而保證該API能夠在TCP模式下接受訪問(即使其擁有網路可訪問能力)。在這種特定情況下,小型 客戶端能夠與所有從伺服器相對接,並監聽其中發生的全部事件。不過這種方式的基本原則仍然相同:每個事件都將允許管理員在nginx當中(假設使用 nginx)對一臺上游伺服器進行新增或者刪除。

Docker如何得到開發者和系統管理員的共同認可

二者的差別在於,這裡主伺服器必須處理全部指向所有從伺服器的連線。而前一種方式的執行成本更低,因為所有從伺服器都接入到主伺服器中。

在這兩類情況下,主伺服器能夠在每一套容器系統啟用或者停止時得到通知,並可以修改主nginx伺服器、重啟容器或者規避事故發生。

當然,我們也可以同時設定兩臺主伺服器來實現故障轉移管理。這種解決方案完全可行而且易於維護。

為開發人員行方便

毫無疑問,Docker非常適合系統管理員使用。但除此之外,它也能夠在生產流程當中扮演重要角色,也就是面向開發人員。我們曾經為客戶提供的一套解決方案就將Dockerfile與docker-compose檔案結合在了一起(由Docker進行fig專案的檢索)。

這一思路是首先定義開發人員的工作站在執行專案時需要哪些必備要素,而後建立Dockerfile(如果需要)以建立有針對性的映象方案,同時將一個docker-compose.yml檔案與這些容器相對接。

在此之後,當使用版本控制伺服器(例如Git、Mercurial以及SVN等等)時,大家可以輕鬆設定該專案目錄,從而將這些檔案以及專案原始碼 新增到其中,併為容器指定所要使用的儲存分卷。接下來,技術團隊可以檢索該專案,而且只需要使用“docker-compose up”這一條命令即可啟用該服務。

讓我們以一個Drupal專案為例,在這裡我們要使用兩套容器系統:

  • 一套MySQL容器
  • 一套包含有Apache加PHP模組的容器

Drupal的原始碼被旋轉在“/src”之下,並會被髮送至Apache容器當中。而這也正是分卷的基本原則:主機上的一個本地目錄或者檔案可以 被連線到特定目錄下的一套或者多套容器處。在此之後,大家可以利用同樣的方法處理MySQL儲存目錄,從而避免被儲存在資料庫內的記錄發生丟失。

下面是Dockerfile內容示例:

  1. FROM debian:7 
  2. MAINTAINER [email protected] 
  3. # Install software 
  4. RUN apt-get update && apt-get install apache2 php5 php5-mysql libapache2-mod-php5 
  5. # Start Apache 
  6. CMD /usr/sbin/apache2ctl -D FOREGROUND 

接下來是docker-compose.yml檔案內容示例:

  1. web: 
  2.      dockerfile: . 
  3.      volumes: 
  4.      - "./src:/ var/www/drupal 
  5.      ports: 
  6.       -  "8080:80" 
  7.      links: 
  8.       -  "db" 
  9. db: 
  10.      image: mysql 
  11.      volumes: 
  12.      -  "./data:/var/lib/mysql" 

其中“web”服務被連結至“db”中(參閱以上示例中的‘links’命令),因此它能夠讀取用於提供MySQL地址及埠(由Dockerfile負責提供)的各環境變數。

舉例來說,以下變數皆可在“web”容器當中接受訪問:

  • DB_PORT_3306_TCP_ADDR=172.17.1.24
  • DB_PORT_3306_TCP_PORT=3306
  • 其它種種

大家當然也可以使用其它容器稱,示例當中的“web”與“db”代表的是兩套容器當中的裝置名稱。

換句話來說,“mysql://db”這一地址也可以變更。接下來,大家需要修改Drupal配置檔案來訪問該資料庫,完成後工作到此結束。該專案將具備以下結構:

  • ”data/”用於儲存MySQL資料
  • ”src/”用於容納Drupal原始碼
  •  ”Dockerfile”用於建立Apache/PHP映象
  • ”docker-compose.yml”用於描述容器的啟動方式

為了保證示例的簡單性,我們並沒有提到Apache配置檔案以及各容器如何共享各個分卷。總結來講,就是這套Web伺服器的配置可以隨意進行修改。

大家可能還注意到,繫結的埠也已經得到處理。由於開發人員用不著獲得使用埠80的許可權,因此我們利用本地埠8080來對映Apache容器的埠80。開發人員只需要訪問127.0.0.1:8080即可檢視當前處於運作狀態的Drupal例項。

為了理解這套對接體系,請大家參閱以下圖表。

競爭關係

就目前的形勢看,Docker似乎成了世界上惟一一項沐浴在讚美當中的容器技術成果。然而請記住,Docker使用libcontainer與cgroups,這意味著為了能夠使用這些核心的功能,該服務必須以root方式執行。而這很可能招致安全問題。

這實際正是CoreOS以及其它同類方案批評Docker的主要著眼點——但值得一提的是,這項技術確實極具吸引力,也支撐著CoreOS創建出了 當下最具知名度的雲系統方案之一。Docker需要root許可權來接入cgroups,但以root角色執行的服務確實很可能給系統造成安全漏洞。

Docker的開發團隊就此給出過禮貌的迴應。很明顯,他們將在未來的版本升級當中考慮這一問題,而且歡迎大家提出任何能夠解決這些缺陷的建議(不 過迄今為止,Docker還沒真正惹出過任何麻煩)。不過各位讀者朋友別慌:這項漏洞被真正利用的可能性非常之低。截至目前,惟一一次安全問題出現在 2014年的1.0版本當中,而且現在問題已經得到解決。

總而言之,CoreOS決定建立自己的一套容器系統(能夠使用Docker映象),名為Rkt(發音同火箭,即‘rocket’)。但就目前的情況看,大多數使用者將繼續在CoreOS解決方案的基礎之上使用Docker。就在Rkt剛剛釋出之時,LinuxContainers(LXC背後的大型項 目)亦宣稱計劃與Cannonical公司合作開發LXD。

如大家所見,容器管理領域的一舉一動都在儘可能向核心靠攏,而由此帶來的結果就是其效能水平將不斷提升。

時間逐漸推移,容器的必要性也變得愈發凸顯。

但Windows與OS X又會如何?對於OS X來說,目前還沒有相關宣告出爐,更不存在任何產品可供選擇。因此,使用boot2docker(一套專門用於執行Docker的虛擬機器)也就成了惟一的出路。Windows目前同樣需要依賴於boot2docker,不過微軟公司最近在宣告中指出,未來的微軟作業系統將直接納入容器機制。具體如何,我們 將拭目以待……

總結陳詞

很明顯,Docker是一項適用於開發及系統管理工作的技術成果。它能夠不斷提供精簡效果並改善效能水平,同時具備良好的可行性,這一切使得使用者能夠以前所未有的方式輕鬆建立服務。無論您的基礎設施到底處於何種規模,相信Docker都能助大家一臂之力。

除此之外,它的亮點也完全能夠體現在生產流程當中。如今開發工作正變得日趨標準化,而開發人員與系統之間的界線也變得越來越精細。我們期待著Docker下個版本的正式降臨,希望到時候它能夠提供更具吸引力的競爭優勢。

就目前來看,Docker仍然是容器領域的惟一王者。