阿裡雲容器服務團隊将為大家奉獻一系列深入學習的文章來幫助大家了解docker 1.12的最新動态。
<a href="https://yq.aliyun.com/articles/55973">第一部分:在阿裡雲上體驗docker 1.12内置的編排能力</a>
第二部分:在阿裡雲上體驗docker 1.12的路由能力和容器應用分發部署 (本文)
docker 1.12除了提供内置的編排能力,也提供了服務路由支援 routing mesh,和新的多容器應用分發和部署機制。
這裡我們先介紹兩個概念
分布式應用打包 (distributed application bundle,簡稱dab):dab 是一個用于應用分發的檔案格式,其中可以包含多個容器服務定義。
stack(應用棧):可以從一個dab檔案建立一個應用棧執行個體,一個應用棧中包含多個服務執行個體。
如果你熟悉docker compose,這些概念聽起來是不是很熟悉?一個docker compose模闆中可以包含多個服務的描述,而利用compose模闆可以建立一個完整的應用。但是docker compose本身被設計成為面向單機的開發工具,并不能對分布式應用進行部署、管理。而dab提供了一個标準化的分發格式解決了這個問題。另外docker提供了工具,可以将一個已有docker compose模闆轉換成dab格式,并部署為docker stack執行個體。
本文中,我們會部署一個wordpress dab應用到阿裡雲上的swarm模式docker叢集中,其中包含兩個服務wordpress和mysql。我們還會利用阿裡雲 slb實作wordpress任務容器的路由和負載均衡。
在這個環境中我們将建立一個三個ecs執行個體構成的swarm叢集,其中一個是manager。另外我們會建立一個slb執行個體來實作服務的路由和負載均衡,叢集中三個ecs執行個體都會作為slb的後端伺服器。我們會在叢集上部署應用,并配置服務路由。大概的拓撲示意圖如下:
首先我們建立一個slb執行個體
slb建立成功之後,我們利用docker-machine來建立三個ecs節點來組成docker叢集執行環境。
我們首先在指令行上配置一些共用的環境變量
然後我們可以通過如下指令在阿裡雲上建立3個ecs執行個體,它還會自動更新作業系統核心,安裝配置最新的測試版docker引擎,并将新建立的slb執行個體添加為指定slb的後端伺服器。
等待三個ecs執行個體會建立完成,我們可以通過如下指令登入到 node-1,初始化docker swarm叢集,顯示master節點的ecs内網"eth0"位址
上面的指令會傳回如下内容
之後,我們把node-2和node-3作為worker加入docker swarm叢集,執行<code>docker-machine ssh <node></code> 之後拷貝上文傳回的第一個指令來添加一個worker節點
這樣整個docker叢集就已經建立成功了,現在我們來部署一個wordpress應用。
注:這一節是為了介紹dab的建立過程,心急的同學可以忽略。
這裡我們可以看到它包含兩個服務"wordpress"和"mysql", 我們可以利用 <code>docker-compose bundle</code> 指令生成dab格式檔案。
注:目前dab/docker service/stack的能力還不完備,有很多docker compose聲明還不能被正确處理,比如volume支援等等。
産生的"wordpress.dab"檔案内容如下
我們要登入到叢集的master節點來部署應用,首先我們從github上擷取相應的示例檔案
利用 <code>docker deploy</code>指令來部署"wordpress" stack,docker指令預設會在本目錄尋找同名的.dab檔案作為stack部署描述。
之後,我們可以利用<code>docker service ls</code>和<code>docker stack tasks</code>指令來檢視相應service/task狀态
現在我們通過<code>docker service inspect</code>指令檢查"wordpress_wordpress"服務狀态
我們可以看到這個"wordpress_wordpress"服務釋出了一個tcp端口“30000”來對外提供服務。那麼我們怎麼通路這個服務呢?
阿裡雲的slb提供了對多台ecs伺服器進行流量分發的負載均衡服務。下面我們将利用slb服務來配置對swarm叢集中的服務的路由和負載均衡。
首先添加偵聽端口,我們選擇"http"和"8080"(可以任選)作為前端協定[端口], "http"和"30000"作為後端的協定[端口]。注意 :後端端口必須與服務狀态中的"publishedport"端口值保持一緻。
配置健康檢查配置時,可以把“/license.txt”作為檢查路徑,這樣隻要wordpress服務的apache可以被通路就認為服務是健康的
完成配置
随後,我們就會在slb負載均衡執行個體上看到相應的偵聽端口和健康檢查狀态
通路slb執行個體的公網ip位址,我們就可以看到熟悉的wordpress設定界面了,
我們還可以利用<code>docker service scale</code>指令對服務進行伸縮,也可以試驗一下負載均衡的效果
看完上面的示例,大家一定非常關心相應服務和路由的網絡配置。我們就來簡單分析一下。在"node-1"節點上,我們執行下面的指令
我們可以看到有兩個叢集範圍的overlay網絡"ingress"和"wordpress_default"。其中"ingress"是在叢集建立之後就自動建立的接入路由網絡,而後者是部署"wordpress.dab"的時候自動建立的。
如果沒有手工指定,swarm manager會自動給需要對外通路的服務配置設定一個在30000-32767之内的publishedport。在上文中"wordpress_wordpress"所配置設定的端口為30000。
在swarm叢集内的每個節點上,都偵聽着相同的publishedport來為服務提供接入路由。是以我們可以在slb上配置一個偵聽端口對叢集中節點進行轉發和負載均衡,而不管後端節點是否運作着服務的任務容器。swarm叢集中的所有節點都可以通過ingress網絡連接配接到運作的任務容器,并保證入口流量被引導到正确的容器執行個體上。
關于routing mesh的ingress網絡的負載均衡,其設計如下圖。我們可以看到每個服務實際上都被配置設定了一個虛拟ip,而虛拟ip到服務任務容器端口之間的負載均衡是通過ipvs來實作的。
注意:routing mesh的端口映射機制和bridge網絡下容器publish端口的實作完全不同,不要混淆。
我們可以通過下面的指令來看看iptables中ecs節點主機端口到服務虛拟ip的轉發配置
docker 1.12帶來了新的分布式應用打包格式,可以給在叢集上部署多容器應用帶來很多便利。但是目前dab的能力和成熟度都有待提高,和docker compose的相容性也存在一些問題,希望會在未來版本中逐漸解決。
如果你了解阿裡雲容器服務,會發現很多新swarm模式下的服務概念和我們實作有很多相似性。我們目前是通過對現有開源編排方案上做增強來提供類似的能力。比如我們擴充了docker compose中service的概念,加強生命周期管理,提供服務伸縮和自動恢複支援等。不遠的未來我們也會提供平滑的更新,支援docker最新的編排技術。
在網絡方面,docker swarm模式的routing mesh可以和外部的負載均衡技術結合。在阿裡雲上我們利用slb實作了docker服務路由和負載均衡。目前這個工作還需要一些手動工作來完成的,在稍後我們會推出全自動化的方式自動配置slb監聽端口,讓整個流程完全自動化。
此外,我們可以看到docker swarm模式和阿裡雲容器服務的路由設計原理上是類似的,隻是容器服務中每個節點利用haproxy為服務提供7層或4層的路由實作,而docker engine是每個節點利用ipvs做為4層的路由實作。7層的優勢在于可以支援virtual host、session affinity等較複雜的路由政策,而基于kernel空間的4層路由可以有更好的性能表現。我們計劃會融合這些技術在阿裡雲容器服務中給大家帶來更好的體驗。