代碼級乾貨 | 進階Docker 1.12,全新的分佈式應用捆綁包

在Docker 1.12版本中,全新的Swarm捆綁包相較於原有編排及調度機制作出了巨大改進。它再也不須要運行一組獨立的Swarm容器,這部分容器已經被直接捆綁在Docker Engine當中,故障轉移策略更爲可靠,服務發現機制實現內置,新的網絡功能極爲順暢……看起來很棒是否是? 數人云這就帶你們一塊兒去探索一二。node

在以前的文章中,咱們已經介紹瞭如何利用命令在Swarm集羣當中運行Docker服務。相信Docker Compose所實現的簡化效果會令你們印象深入。相較於強行記憶命令後的所有參考以實現服務運行,如今你們只須要將一切設置指定爲Docker Compose文件,然後利用簡單的docker-compose up –d命令運行容器便可。毫無疑問,這樣的處理方式比在docker service create命令以後添加一大堆參數要簡單得多。git

而在上手新的Swarm時,我我的的第一印象是「太棒了」,接下來則是「我不想硬背與服務相關的一大堆參數」。Compose文件的迴歸簡直使人熱淚盈眶。github

新版本的一大顯著變化在於,容器管理已經由客戶端(Docker Compose)轉移至服務器端(Docker Serivce)。如此一來,Docker Compose就顯得有些過期了(至少在使用由Docker Serivce部署的容器時是如此)。固然,你們仍是能夠在單一服務器環境下利用Docker Compose運行容器,但其做用恐怕也就僅限於此了。所以,咱們到底要如何處理已經建立完成的這一大堆docker-compose.yml文件?docker

好消息是,咱們能夠分佈式應用捆綁包或者簡稱dab文件替代docker service命令行中的參數。壞消息是……我們仍是先探索好的這部份內容吧。後端

咱們這裏首先構建一套由Docker設備構成的演示Swarm集羣。服務器

環境設置

在本示例中,咱們假定你們已經擁有包含有Docker Engine v1.12+的Docker Machine v0.8+版本。最簡單的獲取方式就是使用Docker Toolbox。網絡

若是你們身爲Windows用戶,則可利用Git Bash(一樣經過Docker Toolbox進行安裝)運行所有示例。app

這裏將再也不贅述環境的設置步驟。咱們將建立三個節點,並利用其構建起一套Swarm集羣。運維

docker-machine create -d virtualbox node-1
 docker-machine create -d virtualbox node-2
 docker-machine create -d virtualbox node-3
 eval $(docker-machine env node-1)
 docker swarm init \
    --advertise-addr $(docker-machine ip node-1) \
    --listen-addr $(docker-machine ip node-1):2377
 TOKEN=$(docker swarm join-token -q worker)
 eval $(docker-machine env node-2)
 docker swarm join --token $TOKEN $(docker-machine ip node-1):2377
 eval $(docker-machine env node-3)
 docker swarm join --token $TOKEN $(docker-machine ip node-1):2377

圖片描述
包含三個節點的Docker Swarm集羣tcp

如今咱們已經擁有了Swarm集羣,下面利用一個dab文件部署一項服務。

利用分佈式應用捆綁包(簡稱DAB)部署服務

相較於利用大量參數建立網絡及Docker服務,這裏咱們選擇使用一個dab文件。你們能夠將其做爲Swarm當中的Docker Compose。至於Swarm,我指的是docker swarm、docker service以及其它來自1.12+版本的新機制(而非以往做爲獨立容器運行的Swarm)。

相較於指定新格式的具體細節以創建服務,這裏咱們直接使用docker-compose.yml文件完成設置。

讓咱們首先檢查演示服務的代碼。

git clone https://github.com/vfarcic/go-demo.git
 cd go-demo
 cat docker-compose.yml

最後一項命令會輸出Docker Compose項目定義,其具體內容以下。

version: '2'
 services:
  app:
    image: vfarcic/go-demo
    ports:
      - 8080
  db:
    image: mongo

如你們所見,這個項目很是簡單。其中只包含兩項服務,app服務爲後端並公開一個API,其利用第二項服務(db)進行數據存儲與檢索。app服務公開端口8080,並將其做爲API的入口點。

將此Docker Compose定義轉化爲捆綁包須要進行兩步操做。首先,咱們須要提取相關鏡像。該bundle的建立會首先進行鏡像評估,然後將docker-compose.yml文件的內容與之相合,最終輸出爲dab文件。

下面進行嘗試。

eval $(docker-machine env node-1) 
docker-compose pull
docker-compose bundle

如今這一流程已經完成,看看結果如何。

cat godemo.dab

其輸出結果以下所示:

{
  "Services": {
    "app": {
      "Image": "vfarcic/go-demo@sha256:f7436796b1cd6812ba63ea82c6523a5164ae7f8a3c05daa9e4ac4bd78341d709",
      "Networks": [
        "default"
      ],
      "Ports": [
        {
          "Port": 8080,
          "Protocol": "tcp"
        }
      ]
    },
    "db": {
      "Image": "mongo@sha256:e599c71179c2bbe0eab56a7809d4a8d42ddcb625b32a7a665dc35bf5d3b0f7c4",
      "Networks": [
        "default"
      ]
    }
  },
  "Version": "0.1"
}

咱們剛剛建立的godemo.dab文件很是簡單。其中包含的兩項服務與docker-compose.yml文件相匹配。每項服務都指定了與提取的哈希值相符合的鏡像。鏡像部分以後爲默認網絡,包括相關服務以及須要開啓的端口。

這部分輸出結果中至少包含兩個問題。第一,咱們不須要開啓任何端口。相反,咱們應當使用反向代理將所有請求從新定向至該服務。新的Docker Swarm網絡功能已經整合了一項代理,咱們應當直接加以利用。

第二個問題在於,咱們並無指定任何約束條件。將不受約束的服務部署至集羣當中無疑會引起嚴重的問題。

你們能夠參閱此docker-compose-swarm.yml文件以獲取一項更好但一樣很是簡單的Compose定義。其內容以下所示:

version: '2' 
services: 
  app:
    image: vfarcic/go-demo
    mem_limit: 250m 
  db:
    image: mongo
    mem_limit: 500m

能夠看到,咱們移除了端口部份內容並添加了一項mem_limit約束。這個Compose文件仍然很是簡單。

下面建立新的捆綁包輸出結果。

docker-compose -f docker-compose-swarm.yml bundle

運行bundle命令後的輸出結果以下所示:

WARNING: Unsupported key 'mem_limit' in services.app - ignoring
WARNING: Unsupported key 'mem_limit' in services.db - ignoring
Wrote bundle to godemo.dab

如今咱們來談第一條壞消息。目前的bundle格式還存在諸多侷限。咱們能夠利用其處理很是簡單的場景,然而一旦指定任何複雜的內容,系統即會給出警告。在本示例中,咱們忽略內存限制警告。

如今咱們暫時不理這一限制警告,嘗試部署剛剛建立的新捆綁包。

docker deploy godemo

運行deploy命令後的輸出結果以下所示:

Loading bundle from godemo.dab
Creating network godemo_default
Creating service godemo_app
Creating service godemo_db

如今網絡與服務都已經建立完成。咱們能夠列出所有服務進行確認。

docker stack ps godemo

能夠看到由兩項服務構成的堆棧,每項服務都被部署在咱們的這套三節點集羣中的某個位置,並且當前狀態爲running。若是顯示的狀態與此不符,則請等待一下子讓容器完成提取,再從新運行此命令。

不過其中仍存在功能缺失的問題。咱們的內存限制被忽略了,並且尚未建立外部網絡proxy並將app服務附加至該代理處。

要解決這個問題,咱們能夠執行service update命令。舉例來講,咱們能夠手動建立proxy網絡並將其中添加容器。咱們也可使用service update命令設置內存限制。然而,若是咱們進行這樣的操做,那麼一開始就不該該使用捆綁包機制。

接下來該作些什麼?

在你們決定放棄bundle以前,請注意這套方案尚處於實驗階段。本篇教程只是爲了讓你們先嚐嚐鮮。咱們預計其將來將迎來巨大改進,且可以全面支持Swarm提供的各項功能。

如今的問題是,咱們當前可以作些什麼。這裏建議你們選擇如下幾種做法:其一,等待bundle完成實驗階段並支持Docker Swarm可以提供的所有功能; 其二,使用Whaleprint項目,其基本上至關於dab文件與其它功能(例如約束)以及Terraform方案的結合體。此項目頗有前途,不過與bundle同樣,其一樣處於起步階段。

但願本篇文章可以幫助你們瞭解全新Swarm的發展方向。目前bundle還在開發當中,咱們預計其將來將成爲一種向集羣部署服務的可靠備選方案。總而言之,立足於當下期待將來纔是最重要的,千萬別被其簡陋的現狀所嚇退。

所以,我建議你們對頒式應用捆綁包加以關注並靜待其發展成熟。在此期間,經過命令或者嘗試Wahleprint項目則是最好的選擇。


PS,數人云新一期的活動報名開始啦,聽大牛們談談容器的情懷,如何助力敏捷開發,高效運維,讓產品迭代力MAX!點擊下方連接快快報名吧!
數人云Meetup|容器助力產品迭代力MAX

相關文章
相關標籤/搜索