Galley - 為基于Docker架構本地開發與測試提速

jopen 9年前發布 | 5K 次閱讀 Galley

來自: http://blog.leapoahead.com/2015/10/23/intro-to-galley/

現如今,Docker已經成為了很多公司部署應用、服務的首選方案。依靠容器技術,我們能在不同的體系結構之上輕松部署幾乎任何種類的應用。在洛杉 磯時間2015年10月21日于舊金山展開的推ter Flight開發者大會上,來自Fabric的工程師Joan Smith再次談到了這一點。

她提到,盡管我們在部署應用的時候將容器技術應用得淋漓盡致,但是在開發和測試的時候還是面臨著很多問題。在從前,她所在的團隊的本地開發方案是用 Vagrant和Chef來支撐的。Vagrant是基于虛擬機的一套本地開發方案,而Chef是一套IT架構自動化部署方案。

Joan認為,使用類似Vagrant、Chef的方案來部署本地開發方案會很浪費開發時間(Engineering Time)。她的理由主要有三點。

第一:微服務盛行。這一趨勢的直接影響之一就是,每個服務自身的配置會不斷變動,互相之間的依賴關系也會不斷變動。今天的一個服務,明天就可能被拆分成三個服務。那么,如果你要在本地啟動開發環境,那么你就需要知道所有服務之間架構的信息才能夠讓應用在本地跑起來。

然而大部分時候,我們在開發一個服務的時候是不需要知道整個架構的。例如,當我們在測試下圖中www和www-db之間的一些功能的時候,我們其實根本可以不用關心crash service是怎么樣的。

 Galley - 為基于Docker架構本地開發與測試提速

所以,更多時候在微服務的世界里,我們只關心我們應該關心的部分。對于不關心的部分,例如crash service,我們有一種方案就是可以用Mock來代替它。

 Galley - 為基于Docker架構本地開發與測試提速

第二:Chef之類的架構自動化部署方案是疊加式(additive)的。往你的現有架構上面加東西很容易,但是想要拿掉一些東西的時候就很困難。

第三:在持續集成的環境中,Vagrant不具備可擴展性(Vagrant on CI just doesn’t scale)。由于Vagrant是基于虛擬機的,在運行過一次CI上的Pipeline任務之后,虛擬機就會被污染(polluted),無法用于下一 次的任務執行。

基于對現有本地開發普遍方案的這些問題,Joan提出了她的看法:我們為什么不利用好Docker這個平臺,讓它在本地開發、測試的時候也能跟線上 保持一致呢?但是如果直接用Docker命令行來啟動應用,手動管理依賴,那么時間成本也很大。Docker Compose確實能夠勝任一次性啟動多個容器的任務,但是它依然不夠靈活。

隨后,Joan介紹了Galley,一個為本地開發、測試而設計的組合并協調(orchestrating)Docker容器的命令行工具。

她還風趣地提到,Vagrant的意思漂泊的,Chef的意思是廚師,而Galley的意思就是漂泊的廚師(原意是船上的廚房)。

Galley最大的優點就是能讓工程師在本地基于自己的代碼構建鏡像并運行,這些本地構建的代碼是他們當前在完成的特性所關心的部分;而對于他們不 關心的部分,例如上面提到的crash service,Galley則自動改用Docker Hub(或者私有的Hub)中已經構建好了的鏡像來直接運行。

Galley采用一個集中的Galleyfile描述整個應用的架構。Galleyfile是一個JavaScript文件,它的module.exports對象即為你所有服務容器的描述。例如下面就是一個合法的Galleyfile的例子。

module.exports = {
  CONFIG: {
    registry: 'docker-registry.your-biz.com'
  },

'config-files': {}, 'beanstalk': {},

'www-mysql': { image: 'mysql', stateful: true },

'www': { env: { RAILS_ENV: { 'dev': 'development', 'test': 'test' } }, links: { 'dev': ['www-mysql:mysql', 'beanstalk'], 'test': ['www-mysql'] }, ports: { 'dev': ['3000:3000'] }, source: '/code/www', volumesFrom: ['config-files'] } };</pre>

在上面,我們定義了所有容器來源的Registry。一般情況下,這會是你自己公司內部的私有Registry。另外,我們還定義了四個容器 config-files、beanstalk、www-mysql和www。這四個容器都是在上面指定的Registry可以下載到的。

假設www容器是我們正在開發的服務,那么我們一般會用”galley run www.dev –rsync -s .” 命令啟動www容器,并且是在dev環境。在Galley里有兩個環境,一個是dev,一個是test。這時候Galley會為我們做幾件事情:

將source屬性指定的文件夾(在容器內)和當前galley run指定的目錄同步。Galley的支持使用rsync將源碼拷貝到Docker所在的機器中。這對于在Mac下開發的人們來說是個很好的特性,因為 Docker的volume支持默認采用VirtualBox的Shared Folder功能,而這一功能的效率很低。
links屬性中的 dev屬性指明了在dev環境下www應用的依賴項。Galley會為我們將這些依賴的容器全部pull到本地并且啟動,并自動和www鏈接在一起。在這 里,Galley就會pull并link兩個容器,一個是www-mysql:mysql,一個是beanstalk。對于在volumesFrom(對 應Docker的volumes-from)指定的容器,Galley也會自動pull并部署。
應用環境變量。在這里,www是一個小型Rails應用,于是我們可以應用一些Rails應用的環境變量。
進行端口映射

更完整的配置方法可以參考Galley的官方文檔

我們可以注意到,在第二點中,Galley只會幫我們獲取我們當前開發所關心的服務,其他不相關的服務,Galley不會獲取并部署它們。

默認情況下,galley run每次都會重新創建我們當前正在開發的應用的容器。對于依賴項,在滿足一定條件的時候也會重新創建(見文檔)。我們注意到www-mysql容器是 stateful(有狀態的)的,因為它是一個數據庫容器。對于stateful的容器,Galley不會自動重新創建它們,保證開發用的數據不會因為重 新創建容器而丟失。

Galley另外一點很有趣的地方是可以創建附加項(Addons)。所謂附加項就是允許開發者通過命令行來手動指定一些容器的行為。這樣說很抽象,我們來看一個例子。下面是一段Addons的配置。

module.exports = {
  …
  ADDONS: {
    'beta': {
      'www': {
        env: {
          'USE_BETA_SERVICE': '1'
        },
        links: ['beta', 'uploader']
      },
      'uploader': {
        env: {
          'USE_BETA_SERVICE': '1'
        }
      }
    }
  }
  …
};

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!