在上一篇文章中我們介紹瞭如何通過compose來定義並執行一組service(容器),如果是在分散式的應用場景中,通常會有一個叢集的概念,即在叢集中部署並管理我們的應用程式。同樣的Docker也提供了相應的模式來管理我們的一組容器,即Swarm Mode。
從Docker 1.12開始Swarm mode已經內嵌入了Docker引擎中,成為了docker的子命令docker swarm,不再需要我們單獨去安裝Docker Swarm。Swarm使用SwarmKit構建,是Docker引擎內建(原生)的叢集管理和編排工具。提供了對Docker容器叢集的管理服務。在開始動手實踐之前讓我們先來了解幾個概念。
節點(Node)
之前做過分散式開發和部署的小夥伴對節點的概念一定不會陌生。在分散式開發和部署中我們管一臺伺服器稱為一個節點。同樣的在Docker Swarm Mode中也有節點的概念。執行Docker的主機可以主動初始化一個Swarm叢集或者加入一個已存在的Swarm叢集,這樣這個執行Docker的主機就成為一個Swarm叢集的節點(node)。
節點分為管理(manager)節點和工作(worker)節點。
管理節點用於Swarm叢集的管理,工作節點是任務執行節點,管理節點將服務(service)以任務(task)的形式下發至工作節點執行。管理節點預設也作為工作節點。引用docker官網的圖片來展示叢集中管理節點與工作節點的關係,如下圖所示:
服務(Service)和任務(Task)
任務(Task): 是Swarm中最小的排程單位,可以把他理解成一個單一的容器。
服務(Services): 是一組任務的集合,服務定義了任務的屬性。服務有兩種模式:
replicated services: 按照一定規則在各個工作節點上執行指定個數的任務。
global services: 每個工作節點上執行一個任務。
下方來自Docker官網的圖片形象的展示了容器,任務,服務的關係, 如圖所示:
開啟Swarm叢集
docker內建了docker swarm的相關指令,我們可以通過docker swarm init來開啟swarm叢集,如下圖所示:
執行docker swarm init命令的節點會自動成為管理節點。
注意: 如果你的docker主機有多個網路卡,擁有多個IP,需要在docker swarm init後面加入
--advertise--addr,以指定被監聽的ip和port,以便其他節點可以加入到叢集中。
這樣就建立了一個單節點的叢集,我們可以通過指令docker node ls來檢視叢集中的節點資訊,如圖所示:
向叢集中部署服務
單節點叢集已經建立好,接下來我們來看如何向叢集中部署服務,上篇文章中我們講到通過compose file部署啟動多個容器,同樣在Swarm中我們也可以使用compose檔案來配置,啟動多個服務。我們繼續使用上節課的docker-compose.yml檔案,並在檔案中加入一些部署相關的資訊,新的檔案內容如下圖所示:
紅色框中是我們新新增的節點資訊:
deploy節點定義了service(包含某個業務功能的映象或docker容器)的部署策略,replicas表示在每一個節點中執行2個服務例項(容器例項),limits限制了每個例項所使用的最大cpus為10%,最大memory為50MB RAM,並設定服務例項的重啟機制為一旦某個容器發生故障,則立即重啟容器。
現在讓我們在建立的單節點叢集中部署這組服務。docker提供了docker stack deploy指令來利用compose檔案部署服務,讓我們進入到docker-compose.yml所在的資料夾,並執行如下指令:docker stack deploy -c docker-compose.yml servicestacklab ,結果如圖所示:
該指令所表達的意思是通過執行docker-compose.yml檔案中的指令碼來建立一個名為servicestacklab的stack的服務組。我們可以通過指令docker stack ls來檢視當前swarm中有哪些stack服務組,結果如圖所示:
我們可以看到在當前的swarm中只有一個名為servicestacklab的服務組,並且這個服務組中只有一個service。
我們可以通過執行docker stack services 指令來檢視stack中有哪些服務,執行指令docker stack services servicestacklab,結果如圖所示:
service的命名規則為:stackname_servicename, stackname為我們docker stack deploy中定義的servicestacklab,servicename是我們compose檔案中定義的每一個service的name,在該例項的compose檔案中我們只定義了一個名為weblab的service,因此最終的服務名稱為servicestacklab_weblab, 可以參照上方compose file內容的截圖。
上面我們提到過,管理節點將服務(service)以任務(task)的形式下發至工作節點執行,在我們的部署策略中我們設定的在每個node中部署一個服務的兩個task,那麼我們可以通過指令docker service ps servicename來檢視一個服務的task情況,指令為docker service ps servicestacklab_weblab, 結果如圖所示:
我們可以看到在node名為linuxkit-00155d6f91aa的節點上以task的形式執行了兩個servicestacklab_weblab服務的例項,task的名為servicestacklab_weblab.1和servicestacklab_weblab.2。
我們通過docker ps -a指令來檢視當前執行的容器例項資訊,結果如圖所示:
可以看到當前有兩個正在執行的容器,大家記住這兩個容器例項的ContainerID分別為:
037776ed23d3和9f3fcf0ba7d9
接下來,我們通過在檔案中暴露的5000埠來訪問這個服務:http://localhost:5000,在頁面中我列印出了當前machine的name(即container的id),我們多重新整理幾次頁面檢視MachineName的變化,得到如下兩張圖:
可以發現Swarm為我們實現了服務訪問的負載均衡。除了負載均衡之外,Swarm mode還內建了服務發現,路由網格,動態伸縮,滾動更新,安全傳輸等功能。大家在聽說docker的同時也一定聽說過Kubernetes,Swarm Mode與Kubernetes類似,K8S也提供了對docker叢集管理的相關功能,後期會找時間為大家介紹一下如何通過K8S來管理Docker叢集。
本篇文章我們就介紹到這裡,希望能讓大家對Docker的Swarm Mode有一定的瞭解,下一篇文章會為大家講解如何在單臺機器上實現包含多docker主機的叢集,以實現模擬在多docker主機之間的分散式部署。
相關資料:
yeasy.gitbooks.io/docker_prac…