149 期 - Docker Swarm 容器管理規畫部署一次傾囊相授


網管人雜誌

本文刊載於 網管人雜誌第 149 期 - 2018 年 6 月 1 日出刊,NetAdmin 網管人雜誌 為一本介紹 Trend Learning 趨勢觀念、Solution Learning 解決方案、Technology Learning 技術應用的雜誌,下列筆記為本站投稿網管人雜誌獲得刊登的文章,網管人雜誌於每月份 1 日出刊您可於各大書店中看到它或透過下列圖示連結至博客來網路書店訂閱它。





文章目錄

前言
Docker Swarm 是什麼?
          Docker Swarm 叢集運作架構
          Docker Swarm 叢集最佳建議作法
實戰 – Docker Swarm on Windows
          Windows Server 2016 安裝 Docker 環境
          建置 Docker Swarm 叢集
          加入其它 Docker Swarm 叢集節點主機
          轉換 Docker Swarm 節點主機角色
          部署 Docker Swarm 叢集服務
          支援 Routing Mesh 負載平衡機制
結語





前言

根據知名市調機構 RightScale,在最新一期的 2018 State of the Cloud Report 調查報告中指出,目前在企業及組織當中使用的容器技術,主要是以 Docker 做為主要的容器管理技術,至於在容器「調度」(Orchestration)方面,則是以 K8S(Kubernetes)為首要同時 K8S 也是成長最快速的容器調度平台(如圖 1 所示)。
雖然 Docker 公司創辦人 Solomon 已經於 2018 年 3 月 28 日,在 Docker Blog 中正式發佈離開 Docker 並辭去 CEO/CTO 職位的消息,但是並不影響 Docker 容器管理技術的發展。

圖 1、RightScale 市調統計結果,企業用於管理容器技術的優先順序





Docker Swarm 是什麼?

簡單來說,當企業及組織的 IT 管理人員要使用容器技術時,只要透過 Docker 容器管理技術即可使用,然而隨著企業及組織使用容器的數量逐漸變多時,便需要有個能夠管理及調度眾多容器的平台,而 Docker Swarm 就是 Docker 公司所推出原生的容器調度管理平台。

雖然,在目前市場上主流的容器調度平台為 Google 推出的 K8S(Kubernetes),但是 Docker Swarm 擁有 Docker 原生及組態設定較為簡單的優勢,所以在市場上的容器調度管理平台中仍佔有一席之地,下列便是 Docker Swarm 容器調度管理平台的特色功能:

  • 原生內建: 從 Docker 1.12 版本之後,在 Docker Engine 中便直接原生內建 Docker Swarm Mode(免費使用的 Docker CE 社群版本也支援)。只要透過 Docker Engine CLI / API 即可建立及管理Docker Swarm 叢集,無須額外安裝及組態設定才能建立容器叢集。
  • 分散式設計: 在小架構規模中可以在 1 台 Docker Host 上,同時運作 Docker Swarm Services 及 Standalone Container 角色。在中大型架構及規模當中,可以在 Docker Swarm 叢集中規劃 Manager / Worker 角色,即便運作環境中沒有共享儲存資源也沒有問題。
  • 宣告式服務模組: 在 Docker Swarm 叢集運作架構中,Docker Engine 將會透過此方式來定義應用程式堆疊。
  • 容器規模縮放機制: 管理人員可以透過 Swarm Managers 管理機制,視容器的工作負載需求隨時調整容器的運作規模大小(增加或減少運作中的容器數量)。
  • 預期狀態調節: 在 Docker Swarm 叢集運作架構中,將會透過 Docker Host 上的 Swarm Managers 管理機制,持續監控叢集的運作狀態並調度容器。舉例來說,在 Swarm Worker 角色中總共運作 10 個容器,但其中有 2 個容器因為 Swarm Worker 主機發生故障而停止服務,此時 Swarm Managers 管理機制,將會在其它「存活」的 Swarm Worker 主機上再啟動 2 個容器。
  • 跨主機網路環境: 透過內建的 Docker Overlay Network 網路機制,在 Docker Swarm 叢集運作架構中,達成跨多台 Docker Host 主機互相溝通的網路機制。
  • 自動探索服務機制: 在 Docker Swarm 叢集運作架構中,內建會為「每項服務」分配唯一的 Unique DNS Name,以便將使用者的服務請求工作負載平均分配至每個容器。管理人員也可以視工作負載需求,搭配外部負載平衡機制將服務請求工作負載平均分配給每個容器。
  • 預設啟用 TLS 安全機制: 在預設情況下,每台 Docker Swarm 節點主機之間會採用 TLS 相互認證及加密(如圖 2 所示),管理人員也可以搭配 --external-ca 參數指定採用公開 Root CA 或自簽 CA 。同時,當 Docker Swarm 叢集初始化完成後,系統將會自動產生 Manager Token 及 Worker Token 以便後續新加入的 Docker Swarm 節點主機使用。值得注意的是,採用預設的 TLS 憑證將會「每3個月」更新憑證,管理人員可以透過參數「docker swarm update --cert-expiry <TIME PERIOD>」調整更新憑證的時間週期,或使用「swarm join-token --rotate」指令產生新的 Token,以避免 Token 洩漏產生安全性疑慮。
  • 滾動式更新: 透過滾動式更新機制,管理人員可以輕鬆的更新容器映像檔版本,並且在發生問題時能夠恢復到先前運作良好的版本。

圖 2、Docker Swarm 叢集架構中 Manager / Worker 透過 TLS 加密機制通訊示意圖



Docker Swarm 叢集運作架構

首先,在 Docker Swarm 容器叢集運作架構中,將有 2 種角色分別是「Manager」「Worker」(如圖 3 所示),其中擔任 Manager 角色的 Docker Swarm 節點主機,將會透過 Raft Consensus Algorithm 機制在節點主機之間互相通訊,同時負責維護 Orchestration Service、Cluster Management、Service Swarm Mode HTTP API Endpoints……等資源調度服務。
至於擔任 Worker 角色的 Docker Swarm 節點主機,最主要的工作任務就是負責「運作容器」,而不會參與上述 Manager 角色所負責的資源調度工作任務。
管理人員,可以隨時透過「docker node promote」指令,將擔任 Worker 角色的 Docker Swarm 節點主機提升為 Manager 角色,或者透過「docker node demote」指令,將擔任 Manager 角色的 Docker Swarm 節點主機降級為 Worker 角色,或者讓 Docker Swarm 節點主機「同時」擔任 2 種角色。
值得注意的是,當企業及組織在規劃建置 Docker Swarm 容器叢集環境時,在 Docker Swarm 節點主機之間必須開啟相關防火牆連接埠及通訊協定(如下列所示),否則屆時 Docker Swarm 節點主機之間將因為無法順利通訊,導致 Docker Swarm 容器叢集環境發生不可預期的錯誤:

  • TCP Port 2377 : 用於 Docker Swarm 叢集管理服務。
  • UDP Port 4789 : 用於 Docker Swarm 叢集 Overlay Network 跨主機網路流量。
  • TCP/UDP Port 7946 : 用於 Docker Swarm 叢集節點主機互相通訊。
  • IP Protocol 50(ESP): 用於 Docker Swarm 叢集 Overlay Network 跨主機網路流量進行加密時使用。

圖 3、Docker Swarm 叢集運作架構示意圖



Docker Swarm 叢集最佳建議作法

那麼,當企業及組織的 IT 管理人員在規劃 Docker Swarm 叢集架構時該如何規劃呢? 應該要多少台 Docker Swarm 節點主機擔任 Manager 及 Worker 角色呢? 原則上,在 Docker Swarm 叢集架構中,對於 Manager 及 Worker 角色的 Docker Swarm 節點主機數量並沒有限制,那麼到底要建立多少台數量的 Docker Swarm 節點主機才是適當,便是我們接下來所要討論的重點。

首先,在 Docker Swarm 叢集運作架構中,因為擔任 Manager 角色的 Docker Swarm 節點主機,主要是透過 Raft 一致性演算法來管理 Docker Swarm 叢集運作狀態。因此,當新增的 Docker Swarm 節點主機加入 Docker Swarm 叢集時,或是有 Docker Swarm 節點主機退出 Docker Swarm 叢集時,所有擔任 Manager 角色的 Docker Swarm 節點主機,便需要執行同步、確認、更新、複寫……等 Docker Swarm 叢集運作狀態的工作任務。

但是,當擔任 Manager 角色的 Docker Swarm 節點主機數量「過少」時,有可能因為 Manager 主機故障損壞,進而導致 Docker Swarm 叢集崩潰,然而 Manager 角色 Docker Swarm 節點主機數量「過多」時,則會因為叢集維運工作任務的往返網路流量過大而導致同步及更新狀態的寫入效能降低。
在 Docker Swarm 叢集架構中,即便所有 Manager 角色主機全數故障損壞無法運作,仍然不影響在 Worker 角色主機上運作的容器。但是,整個 Docker Swarm 叢集將無法進行新增 / 更新 / 移除……等維運及資源調度的工作任務。
簡單來說,在 Docker 官方的最佳建議作法當中,擔任 Manager 角色的 Docker Swarm 節點主機數量應為「奇數」,最主要是考量 Docker Swarm 叢集中「仲裁」(Quorum)「容錯」(Fault Tolerance)機制。

因此,整個 Docker Swarm 叢集的最佳建議作法中,最小規模應建置「3 台」擔任 Manager 角色的 Docker Swarm 節點主機,此時可以容許「1 台」Manager 角色主機發生故障損壞事件,並且不影響 Docker Swarm 叢集的運作(如圖 4 所示)。

同理,倘若 Docker Swarm 叢集中,建置「5 台」擔任 Manager 角色的 Docker Swarm 節點主機時,將能容許「2 台」Manager 角色主機發生故障且不影響 Docker Swarm 叢集的運作。
倘若建置「偶數」Manager 角色主機,則容錯數量則與奇數主機相同。舉例來說,建置「4 台」Manager 角色主機,仍只能允許「1 台」Manager 角色主機發生故障,建置「6 台」仍只能允許「2 台」Manager 角色主機發生故障。
圖 4、Docker Swarm 叢集 Manager 角色節點主機數量建議表



實戰 – Docker Swarm on Windows

在本文實作環境中,我們將準備「3 台」Windows Server 2016 主機,在下載及安裝 Docker 容器環境後,接著建置 Docker Swarm 叢集環境,而這 3 台 Windows Server 2016 Docker 主機,將會「同時擔任」Docker Swarm 叢集環境中 Manager 及 Worker 角色。這 3 台主機的基礎設定資訊如下:

 主機名稱
IP 位址
Docker Swarm 角色
SwarmHost01
10.10.75.21
Manager / Worker
SwarmHost02
10.10.75.22
Manager / Worker
SwarmHost03
10.10.75.23
Manager / Worker



Windows Server 2016 安裝 Docker 環境

管理人員只要透過 OneGet Provider 機制,即可輕鬆安裝 PowerShell 中的 Docker 模組,順利讓 Windows Server 2016 主機運作 Docker 容器環境。

請開啟 PowerShell 指令視窗,依序鍵入「Install-Module -Name DockerMsftProvider -Repository PSGallery -Force」「Install-Package -Name docker -ProviderName DockerMsftProvider -Force」指令後,最後鍵入「Restart-Computer -Force」指令重新啟動Windows Server 2016主機。
有關 Windows Server 2016 安裝 Docker 容器環境的詳細資訊,請參考本刊《第 139 期-共用系統核心資源,玩轉 Windows Server 容器》
待 3 台 Windows Server 2016 主機重新啟動後,確認是否已經順利運作 Docker 環境,請在 PowerShell 指令視窗中執行「docker version」指令,可以看到在本文實作環境中所安裝的 Docker引擎及 Docker 用戶端版本為「17.06.2-ee-7」(如圖 5 所示)。

圖 5、確認 Windows Server 2016 主機 Docker 運作環境版本資訊



建置 Docker Swarm 叢集

順利為 3 台 Windows Server 2016 安裝好 Docker 運作環境後,在開始建置 Docker Swarm 叢集之前,請確保 3 台 Windowsd Server 2016 主機,已經開啟好 Docker Swarm 叢集相關防火牆連接埠,管理人員可以透過 PowerShell 指令,「New-NetFirewallRule -DisplayName 'Docker Swarm' -Profile @('Domain','Private','Public')-Direction Inbound -Action Allow -Protocol TCP -LocalPort @('2377','7946')」「New-NetFirewallRule -DisplayName 'Docker Swarm' -Profile @('Domain','Private','Public')-Direction Inbound -Action Allow -Protocol UDP -LocalPort @('4789','7946')」,快速開啟相關防火牆連接埠(如圖 6 所示)。

圖 6、透過 PowerShell 開啟 Docker Swarm 叢集相關防火牆連接埠

由於在本文實作環境中,並沒有建置 DNS 名稱解析伺服器,所以請修改 3 台 Docker Swarm 節點主機的 hosts 名稱解析設定檔,檔案路徑為「C:\Windows\System32\drivers\etc\hosts」,在 hosts 名稱解析設定檔內容中加上 3 筆 Docker Swarm 節點主機解析記錄。完成組態設定修改的動作後,請執行 ping 指令確認 DNS 名稱解析動作正確無誤(如圖 7 所示)。

圖 7、組態設定 3 台 Docker Swarm 節點主機的 hosts 名稱解析設定檔

在本文實作環境中,我們將採用「SwarmHost01(10.10.75.21)」主機,當成 Docker Swarm 叢集中「第 1 台」初始化的 Docker Swarm 節點主機。請在 PowerShell 指令視窗中,鍵入「docker swarm init --advertise-addr=10.10.75.21 --listen-addr 10.10.75.21:2377」指令,讓 SwarmHost01 主機執行 Docker Swarm 叢集初始化工作任務。

當 Docker Swarm 叢集初始化的動作完成後,可以執行「docker node ls」指令進行確認,可以看到目前在 Docker Swarm 叢集中只有 1 台主機,也就是剛才執行初始化動作的 SwarmHost01 主機(如圖 8 所示)。
管理人員也可以執行「docker info」指令,查看有關 Docker Swarm 叢集相關運作資訊。
圖 8、SwarmHost01 主機執行 Docker Swarm 叢集初始化工作任務

此時,我們可以觀察到 SwarmHost01 主機,在建立 Docker Swarm 叢集之後主機發生哪些變化。在主機網路方面,將會看到 SwarmHost01 主機原本的「實體網路卡」,也就是剛才指定 10.10.75.21 IP 位址的網路卡,將會轉變成「HNSTransparent」,並且在 Docker 網路環境中將會產生名稱為「ingress」「overlay」網路(如圖 9 所示)。
此時,管理人員使用「netstat -na」指令,將會發現 SwarmHost01 主機開始使用 Docker Swarm 叢集相關連接埠,例如,Port 2377,7946
圖 9、Docker Swarm 叢集初始化完成後 SwarmHost01 主機運作環境的轉變



加入其它 Docker Swarm 叢集節點主機

當 SwarmHost01 執行初始化作業順利建立 Docker Swarm 叢集之後,管理人員應該有發現系統回應後續加入 Docker Swarm 叢集節點主機所使用的「Token」

預設情況下,Docker Swarm 叢集僅會顯示「Worker 角色」所使用的 Token,而不會顯示 Manager 角色所要加入 Docker Swarm 叢集時的 Token 。同時,管理人員倘若忘記將剛才加入的 Token 記錄下來時,也都可以隨時使用 Docker 指令重新顯示 Manager/Worker 角色所使用的 Token。

請在 PowerShell 指令視窗中,執行「docker swarm join-token worker」指令即可顯示,Docker Swarm 節點主機所要加入 Docker Swarm 叢集時,擔任 Worker 角色所使用的指令以及 Token,而執行「docker swarm join-token manager」指令,則是顯示擔任 Manager 角色所使用的指令以及 Token(如圖 10 所示)。
倘若,只希望系統回應使用的 Token 內容而非完整指令時,只要在執行指令結尾加上「--quiet」參數即可。
圖 10、顯示 Docker Swarm 節點主機加入 Docker Swarm 叢集時使用的 Token

在本文實作環境中,整個 Docker Swarm 叢集只有 3 台 Docker Swarm 節點主機,為了確保 Docker Swarm 叢集運作的穩定性,所以另外 2 台加入叢集的 Docker Swarm 節點主機,也會擔任 Manager 的角色。

請登入另外 2 台 Docker Swarm 節點主機(本文實作環境為 SwarmHost02、SwarmHost03),執行加入 Docker Swarm 叢集且擔任 Manager 角色的指令,當 Docker Swarm 節點主機順利加入 Docker Swarm 叢集時,系統將會顯示「This node joined a swarm as a manager」資訊。
倘若,系統顯示「Error response from daemon :Timeout was reached before node was joined.」訊息,請再次確認 Docker Swarm 節點主機的防火牆規則是否已經開啟。
此時,我們可以再次執行「docker node ls」指令,查看目前 Docker Swarm 叢集的節點主機資訊,可以看到目前的 Docker Swarm 叢集中共有 3 台主機,至於 HOSTNAME 欄位前顯示「*」,表示目前執行 Docker 指令的所在主機(如圖 11 所示)。

圖 11、將另外 2 台 Docker Swarm 節點主機加入 Docker Swarm 叢集中



轉換 Docker Swarm 節點主機角色

在前述說明 Docker Swarm 容器叢集運作架構時,我們已經說明叢集中有 2 種角色分別是「Manager」「Worker」。當 Docker Swarm 節點主機加入 Docker Swarm 叢集後,倘若管理人員需要調整 Docker Swarm 節點主機角色時,可以在擔任「Manager」角色的 Docker Swarm 節點主機上,執行 Docker 指令「docker node promote/demote」,即可轉換 Docker Swarm 節點主機的角色。

如圖 12 所示,我們登入 SwarmHost03 主機執行「docker node ls」指令,可以看到目前 3 台 Docker Swarm 節點主機皆為 Manager 角色,接著執行「docker node demote SwarmHost02」指令,將 SwarmHost02 主機角色降級為 Worker 角色,然後再執行「docker node promote SwarmHost02」指令,將 SwarmHost02 主機角色再次升級為 Manager 角色

圖 12、轉換 Docker Swarm 節點主機的叢集角色



部署 Docker Swarm 叢集服務

至此,我們已經順利建置好 Docker Swarm 叢集運作環境,接下來便可以進行部署「服務」(Services)的動作。值得注意的是,在「單機」的 Docker 容器運作環境中,管理人員可以透過「docker run」指令來建立容器,然而在 Docker Swarm 叢集環境中則必須執行「docker service create」指令,那麼建立的容器才會順利部署至 Docker Swarm 叢集高可用性環境中(如圖 13 所示)。

圖 13、Docker Swarm 叢集部署容器服務運作流程示意圖

了解 Docker Swarm 叢集部署容器服務運作流程後,管理人員也必須了解 Docker Swarm 叢集運作的幾個技術名詞,分別是「服務」(Services)、「任務」(Tasks)、「容器」(Containers)代表的意義為何。

首先,當管理人員執行「docker service create」指令後,會在 Docker Swarm 叢集中建立「容器服務」,接著依據 Docker 指令所設定的「複本」(Replica)數量,決定要在 Docker Swarm 叢集中建立多少的「任務及容器」(如圖 14 所示)。

圖 14、Docker Swarm 叢集服務,任務,容器運作示意圖

請在 Docker Swarm 叢集中任意 1 台 Manager 角色主機上,執行「docker service create --name=iis --replicas 3 --publish mode=host,published=80,target=80 --endpoint-mode dnsrr -d microsoft/iis」指令部署 IIS 容器服務(如圖 15 所示),此行 Docker 指令相關參數意義如下:

  • --name=iis: 指定此 Docker Swarm 叢集服務名稱為 iis 。
  • --replicas 3: 指定此 Docker Swarm 叢集服務任務數量為 3,因此將會建立總數為 3 個的 IIS 容器,本文實作環境中共 3 台 Docker Swarm 節點主機,所以屆時每台主機上將會運作 1 個 IIS 容器。
  • --publish mode=host,published=80,target=80: 指定運作後的 IIS 容器及 Docker Swarm 節點主機,互相對應的連接埠關係,本文實作環境中將會採用主機的 Port 80 對應到 IIS 容器的 Port 80 。
  • --endpoint-mode dnsrr: 採用 DNS Round Robin 負載平衡機制,處理 IIS 容器的網路流量。
  • -d microsoft/iis: 下載完 microsoft/iis 容器映像檔後,採用背景執行的方式運作 IIS 容器。

圖 15、在 Docker Swarm 叢集中部署 IIS 容器服務

此時,在使用者端開啟瀏覽器後,不管是連接到哪一台 SwarmHost 主機的 IP 位址,都會重新導向至內部運作的 IIS 容器網頁服務當中。同時,由於 IIS 容器服務是部署至高可用性的 Docker Swarm 叢集中,因此當 IIS 容器因為任何因素而停止運作時(本文實作環境,由管理人員手動執行指令直接停止其中 1 個 IIS 容器),那麼 Docker Swarm 叢集也會「自動」再次產生新的 IIS 容器(如圖 16 所示)。

圖 16、Docker Swarm 叢集高可用性機制,偵測有 IIS 容器停止運作後自動產生新的 IIS 容器

此外,倘若考量 IIS 容器工作負載的關係,管理人員需要擴充或縮減運作的 IIS 容器數量時,那麼透過 Docker Swarm 叢集運作機制也是非常容易達成的。管理人員只要執行「docker service scale < 服務名稱及複本數量 >」指令,舉例來說,在本文實作環境中執行「docker service scale iis=1指令後,那麼 IIS 容器數量將由一開始部署的「3 個」IIS 容器縮減為「1 個」IIS 容器(如圖 17 所示)。

圖 17、透過 Docker Swarm 叢集線上擴充或縮減運作的 IIS 容器數量



支援 Routing Mesh 負載平衡機制

熟悉 Docker Swarm 叢集運作架構的管理人員可能會有個疑問,在 Windows Server 2016 RTM(版本 1609)中所建立的 Docker Swarm 叢集環境,似乎無法順利使用 Docker Swarm 內建的「Routing Mesh 負載平衡」機制 ?

是的,在 Windows Server 2016 RTM(版本 1609中所建立的 Docker Swarm 叢集環境,目前支援採用「DNS Round Robin 負載平衡」機制,必須採用「Windows Server 2016(版本 1709)」建立的 Docker Swarm 叢集環境,才能夠支援 Docker Swarm 內建的「Routing Mesh 負載平衡」機制(如圖 18 所示)。詳細資訊請參考微軟官方部落格文章內容 Virtualization Blog - Docker routing mesh available with Windows Server version 1709

圖 18、Docker Swarm on Windows Server 支援 Routing Mesh 負載平衡機制示意圖





結語

透過本文的說明及實作練習,管理人員應該能夠感受到透過 Windows Server 2016 所建構的 Docker Swarm 叢集環境,能夠很容易的在 Windows Server 容器環境中,線上擴充或縮減容器的運作規模,同時在容器因為任何因素而停止運作時,Docker Swarm 叢集將會自動產生新的容器,確保容器所提供服務具備高可用性,以幫助企業及組織降低維運成本,同時也能降低資料中心維運人員的管理負擔。