Docker原理解讀
862
2025-03-31
點擊上方“民工哥技術之路”選擇“星標”
每天10點為你分享不一樣的干貨
Docker Swarm具有如下基本特性:
集群管理集成進Docker Engine
使用內置的集群管理功能,我們可以直接通過Docker CLI命令來創建Swarm集群,然后去部署應用服務,而不再需要其它外部的軟件來創建和管理一個Swarm集群。
去中心化設計
Swarm集群中包含Manager和Worker兩類Node,我們可以直接基于Docker Engine來部署任何類型的Node。而且,在Swarm集群運行期間,我們既可以對其作出任何改變,實現對集群的擴容和縮容等,如添加Manager Node,如刪除Worker Node,而做這些操作不需要暫停或重啟當前的Swarm集群服務。
聲明式服務模型(Declarative Service Model)
在我們實現的應用棧中,Docker Engine使用了一種聲明的方式,讓我們可以定義我們所期望的各種服務的狀態,例如,我們創建了一個應用服務棧:一個Web前端服務、一個后端數據庫服務、Web前端服務又依賴于一個消息隊列服務。
服務擴容縮容
對于我們部署的每一個應用服務,我們可以通過命令行的方式,設置啟動多少個Docker容器去運行它。已經部署完成的應用,如果有擴容或縮容的需求,只需要通過命令行指定需要幾個Docker容器即可,Swarm集群運行時便能自動地、靈活地進行調整。
協調預期狀態與實際狀態的一致性
Swarm集群Manager Node會不斷地監控集群的狀態,協調集群狀態使得我們預期狀態和實際狀態保持一致。例如我們啟動了一個應用服務,指定服務副本為10,則會啟動10個Docker容器去運行,如果某個Worker Node上面運行的2個Docker容器掛掉了,則Swarm Manager會選擇集群中其它可用的Worker Node,并創建2個服務副本,使實際運行的Docker容器數仍然保持與預期的10個一致。
多主機網絡
我們可以為待部署應用服務指定一個Overlay網絡,當應用服務初始化或者進行更新時,Swarm Manager在給定的Overlay網絡中為Docker容器自動地分配IP地址,實際是一個虛擬IP地址(VIP)。
服務發現
Swarm Manager會給集群中每一個服務分配一個唯一的DNS名稱,對運行中的Docker容器進行負載均衡。我們可以通過Swarm內置的DNS Server,查詢Swarm集群中運行的Docker容器狀態。
負載均衡
在Swarm內部,可以指定如何在各個Node之間分發服務容器(Service Container),實現負載均衡。如果想要使用Swarm集群外部的負載均衡器,可以將服務容器的端口暴露到外部。
安全策略
在Swarm集群內部的Node,強制使用基于TLS的雙向認證,并且在單個Node上以及在集群中的Node之間,都進行安全的加密通信。我們可以選擇使用自簽名的根證書,或者使用自定義的根CA(Root CA)證書。
滾動更新(Rolling Update)
對于服務需要更新的場景,我們可以在多個Node上進行增量部署更新,Swarm Manager支持通過使用Docker CLI設置一個delay時間間隔,實現多個服務在多個Node上依次進行部署。這樣可以非常靈活地控制,如果有一個服務更新失敗,則暫停后面的更新操作,重新回滾到更新之前的版本。
Docker Swarm提供了基本的集群能力,能夠使多個Docker Engine組合成一個group,提供多容器服務。Swarm使用標準的Docker API,啟動容器可以直接使用docker run命令。Swarm更核心的則是關注如何選擇一個主機并在其上啟動容器,最終運行服務。
Docker Swarm基本架構,如下圖所示(來自網絡,詳見后面參考鏈接):
如上圖所示,Swarm Node表示加入Swarm集群中的一個Docker Engine實例,基于該Docker Engine可以創建并管理多個Docker容器。其中,最開始創建Swarm集群的時候,Swarm Manager便是集群中的第一個Swarm Node。在所有的Node中,又根據其職能劃分為Manager Node和Worker Node,具體分別如下所示:
Manager Node
Manager Node負責調度Task,一個Task表示要在Swarm集群中的某個Node上啟動Docker容器,一個或多個Docker容器運行在Swarm集群中的某個Worker Node上。同時,Manager Node還負責編排容器和集群管理功能(或者更準確地說,是具有Manager管理職能的Node),維護集群的狀態。需要注意的是,默認情況下,Manager Node也作為一個Worker Node來執行Task。Swarm支持配置Manager只作為一個專用的管理Node,后面我們會詳細說明。
Worker Node
Worker Node接收由Manager Node調度并指派的Task,啟動一個Docker容器來運行指定的服務,并且Worker Node需要向Manager Node匯報被指派的Task的執行狀態。
我們實踐Swarm集群,包括三個節Node,對應的主機名和IP地址分別如下所示:
首先,需要保證各個Node上,docker daemon進程已經正常啟動,如果沒有則執行如下命令啟動:
接下來就可以創建Swarm集群,創建Swarm的命令,格式如下所示:
docker swarm init --advertise-addr
我們在準備好的manager Node上,登錄到該Node,創建一個Swarm,執行如下命令:
上面–advertise-addr選項指定Manager Node會publish它的地址為192.168.1.107,后續Worker Node加入到該Swarm集群,必須要能夠訪問到Manager的該IP地址。可以看到,上述命令執行結果,如下所示:
該結果中給出了后續操作引導信息,告訴我們如何將一個Worker Node加入到Swarm集群中。也可以通過如下命令,來獲取該提示信息:
在任何時候,如果我們需要向已經創建的Swarm集群中增加Worker Node,只要新增一個主機(物理機、云主機等都可以),并在其上安裝好Docker Engine并啟動,然后執行上述docker swarm join命令,就可以加入到Swarm集群中。
這時,我們也可以查看當前Manager Node的基本信息,執行docker info命令,輸出信息中可以看到,包含如下關于Swarm的狀態信息:
Swarm: active NodeID: qc42f6myqfpoevfkrzmx08n0r
Is Manager: true ClusterID: qi4i0vh7lgb60qxy3mdygb27f Managers: 1
Nodes: 1
可以看出,目前Swarm集群只有Manager一個Node,而且狀態是active。也可以在Manager Node上執行docker node ls命令查看Node狀態,如下所示:
接下來,我們可以根據上面提示信息,我們分別在worker1、worker2兩個Worker Node 上,執行命令將Worker Node加入到Swarm集群中,命令如下所示:
如果成功,可以看到成功加入Swarm集群的信息。這時,也可以在Manager Node上,查看Swarm集群的信息,示例如下所示:
想要查看Swarm集群中全部Node的詳細狀態信息,可以執行如下所示命令:
Swarm集群Node的狀態信息,如下所示:
上面信息中,AVAILABILITY表示Swarm Scheduler是否可以向集群中的某個Node指派Task,對應有如下三種狀態:
Active:集群中該Node可以被指派Task
Pause:集群中該Node不可以被指派新的Task,但是其他已經存在的Task保持運行
Drain:集群中該Node不可以被指派新的Task,Swarm Scheduler停掉已經存在的Task,并將它們調度到可用的Node上
查看某一個Node的狀態信息,可以在該Node上執行如下命令:
docker node inspect self
我們在Manager Node上執行上述命令,查看的狀態信息如下所示:
管理Swarm Node
Swarm支持設置一組Manager Node,通過支持多Manager Node實現HA。那么這些Manager Node之間的狀態的一致性就非常重要了,多Manager Node的Warm集群架構,如下圖所示(出自Docker官網):
通過上圖可以看到,Swarm使用了Raft協議來保證多個Manager之間狀態的一致性。基于Raft協議,Manager Node具有一定的容錯功能,假設Swarm集群中有個N個Manager Node,那么整個集群可以容忍最多有(N-1)/2個節點失效。如果是一個三Manager Node的Swarm集群,則最多只能容忍一個Manager Node掛掉。
下面,我們按照對Node的不同操作,通過命令的方式來詳細說明:
前面我們已經提到過,Node的AVAILABILITY有三種狀態:Active、Pause、Drain,對某個Node進行變更,可以將其AVAILABILITY值通過Docker CLI修改為對應的狀態即可,下面是常見的變更操作:
設置Manager Node只具有管理功能
對服務進行停機維護,可以修改AVAILABILITY為Drain狀態
暫停一個Node,然后該Node就不再接收新的Task
恢復一個不可用或者暫停的Node
例如,將Manager Node的AVAILABILITY值修改為Drain狀態,使其只具備管理功能,執行如下命令:
這樣,Manager Node不能被指派Task,也就是不能部署實際的Docker容器來運行服務,而只是作為管理Node的角色。
每個Node的主機配置情況可能不同,比如有的適合運行CPU密集型應用,有的適合運行IO密集型應用,Swarm支持給每個Node添加標簽元數據,這樣可以根據Node的標簽,來選擇性地調度某個服務部署到期望的一組Node上。
給SWarm集群中的某個Worker Node添加標簽,執行如下命令格式如下:
改變Node的角色,Worker Node可以變為Manager Node,這樣實際Worker Node有工作Node變成了管理Node,對應提權操作,例如將worker1和worker2都升級為Manager Node,執行如下命令:
如果Manager想要退出Swarm集群, 在Manager Node上執行如下命令:
即使Manager已經退出SWarm集群,執行上述命令也可以使得Worker Node退出集群,然后又可以加入到其它新建的Swarm集群中。
在Swarm集群上部署服務,必須在Manager Node上進行操作。先說明一下Service、Task、Container(容器)這個三個概念的關系,如下圖(出自Docker官網)非常清晰地描述了這個三個概念的含義:
在Swarm mode下使用Docker,可以實現部署運行服務、服務擴容縮容、刪除服務、滾動升級等功能,下面我們詳細說明。
創建Docker服務,可以使用docker service create命令實現,例如,我們要創建如下兩個服務,執行如下命令:
第一個命令行,從Docker鏡像alpine創建了一個名稱為myapp的服務,其中指定服務副本數為1,也就是啟動一個Docker容器來運行該服務。第二個命令行, 創建一個Redis服務,服務副本數為2,那么會啟動兩個Docker容器來運行myredis服務。查看當前,已經部署啟動的全部應用服務,執行如下命令:
執行結果,如下所示:
也可以查詢指定服務的詳細信息,執行如下命令:
查看結果信息,如下所示:
上面信息中,在manager和worker1這兩個Node上部署了myredis這個應用服務,也包含了它們對應的當前狀態信息。此時,也可以通過執行docker ps命令,在Manager Node上查看當前啟動的Docker容器:
上面,通過?--env 選項來設置環境變量,通過?--workdir 選項來設置工作目錄,通過?--user選項來設置用戶信息。
Docker Swarm支持服務的擴容縮容,Swarm通過?--mode 選項設置服務類型,提供了兩種模式:一種是replicated,我們可以指定服務Task的個數(也就是需要創建幾個冗余副本),這也是Swarm默認使用的服務類型;另一種是global,這樣會在Swarm集群的每個Node上都創建一個服務。如下圖所示(出自Docker官網),是一個包含replicated和global模式的Swarm集群:
上圖中,黃色表示的replicated模式下的Service Replicas,灰色表示global模式下Service的分布。
服務擴容縮容,在Manager Node上執行命令的格式,如下所示:
例如,將前面我們部署的2個副本的myredis服務,擴容到3個副本,執行如下命令:
通過命令docker service ls 查看,擴容操作結果如下所示:
可以看到,我們目前3個Node的Swarm集群,每個Node上都有一個myredis應用服務的副本,可見也實現了很好的負載均衡。
縮容服務,只需要將副本數小于當前應用服務擁有的副本數即可實現,大于指定縮容副本數的副本會被刪除。
刪除服務,只需要在Manager Node上執行如下命令即可:
例如,刪除myredis應用服務,執行docker service rm myredis,則應用服務myredis的全部副本都會被刪除。
服務的滾動更新,這里我參考官網文檔的例子說明。在Manager Node上執行如下命令:
上面通過指定?--update-delay 選項,表示需要進行更新的服務,每次成功部署一個,延遲10秒鐘,然后再更新下一個服務。如果某個服務更新失敗,則Swarm的調度器就會暫停本次服務的部署更新。
另外,也可以更新已經部署的服務所在容器中使用的Image的版本,例如執行如下命令:
將Redis服務對應的Image版本有3.0.6更新為3.0.7,同樣,如果更新失敗,則暫停本次更新。
在Swarm集群中可以使用Overlay網絡來連接到一個或多個服務。具體添加Overlay網絡,首先,我們需要創建在Manager Node上創建一個Overlay網絡,執行如下命令:
這樣,如果Swarm集群中其他Node上的Docker容器也使用my-network這個網絡,那么處于該Overlay網絡中的所有容器之間,通過網絡可以連通。
原文:http://shiyanjun.cn/archives/1625.html
關注?民工哥技術之路?微信公眾號對話框回復關鍵字:1024?可以獲取一份最新整理的技術干貨。
點擊【閱讀原文】和民工哥一起聊技術、搞事情~~
不管怎樣
點“在看”一定不能放棄啊!
Docker 容器
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。