Swarm是Docker原生的集群管理軟件,與Kubernetes比起來比較簡單。Swarm這個項目名稱特別貼切。在Wiki的解釋中,Swarm behavior是指動物的群集行為。比如我們常見的蜂群,魚群,秋天往南飛的雁群都可以稱作Swarm behavior。
Swarm項目正是這樣,通過把多個Docker Engine聚集在一起,形成一個大的docker-engine,對外提供容器的集群服務。同時這個集群對外提供Swarm API,用戶可以像使用Docker Engine一樣使用Docker集群。
Swarm是Docker公司在2014年12月初發布的容器管理工具,和Swarm一起發布的Docker管理工具還有Machine以及Compose。Swarm是一套較為簡單的工具,用以管理Docker集群,使得Docker集群暴露給用戶時相當於一個虛擬的整體。Swarm將一群Docker宿主機變成一個單一的,虛擬的主機。Swarm使用標准的Docker API接口作為其前端訪問入口,換言之,各種形式的Docker Client(docker client in Go, docker_py, docker等)均可以直接與Swarm通信。Swarm幾乎全部用Go語言來完成開發,Swarm0.2版本增加了一個新的策略來調度集群中的容器,使得在可用的節點上傳播它們,以及支持更多的Docker命令以及集群驅動。Swarm deamon只是一個調度器(Scheduler)加路由器(router),Swarm自己不運行容器,它只是接受docker客戶端發送過來的請求,調度適合的節點來運行容器,這意味着,即使Swarm由於某些原因掛掉了,集群中的節點也會照常運行,當Swarm重新恢復運行之后,它會收集重建集群信息。
Docker的Swarm (集群) 模式,集成很多工具和特性,比如:跨主機上快速部署服務,服務的快速擴展,集群的管理整合到docker引擎,分散設計,聲明式的服務模型,可擴展,狀態協調處理,多主機網絡,分布式的服務發現,負載均衡,滾動更新,安全(通信的加密)。
Swarm 特點
1) 對外以Docker API接口呈現,這樣帶來的好處是,如果現有系統使用Docker Engine,則可以平滑將Docker Engine切到Swarm上,無需改動現有系統。
2) Swarm對用戶來說,之前使用Docker的經驗可以繼承過來。非常容易上手,學習成本和二次開發成本都比較低。同時Swarm本身專注於Docker集群管理,非常輕量,占用資源也非常少。簡單說,就是插件化機制,Swarm中的各個模塊都抽象出了API,可以根據自己一些特點進行定制實現。
3) Swarm自身對Docker命令參數支持的比較完善,Swarm目前與Docker是同步發布的。Docker的新功能,都會第一時間在Swarm中體現。
Docker自誕生以來,其容器特性以及鏡像特性給DevOps愛好者帶來了諸多方便。然而在很長的一段時間內,Docker只能在單host上運行,其跨host的部署、運行與管理能力頗受外界詬病。跨host能力的薄弱,直接導致Docker容器與host的緊耦合,這種情況下,Docker容器的靈活性很難令人滿意,容器的遷移、分組等都成為很難實現的功能點。
Swarm架構
Swarm作為一個管理Docker集群的工具,首先需要將其部署起來,可以單獨將Swarm部署於一個節點。另外,自然需要一個Docker集群,集群上每一個節點均安裝有Docker。具體的Swarm架構圖可以參照下圖:
Swarm架構中最主要的處理部分自然是Swarm節點,Swarm管理的對象自然是Docker Cluster,Docker Cluster由多個Docker Node組成,而負責給Swarm發送請求的是Docker Client。
Swarm關鍵概念
1)Swarm
集群的管理和編排是使用嵌入到docker引擎的SwarmKit,可以在docker初始化時啟動swarm模式或者加入已存在的swarm
2)Node
一個節點(node)是已加入到swarm的Docker引擎的實例 當部署應用到集群,你將會提交服務定義到管理節點,接着Manager管理節點調度任務到worker節點,manager節點還執行維護集群的狀態的編排和群集管理功能,worker節點接收並執行來自manager節點的任務。通常,manager節點也可以是worker節點,worker節點會報告當前狀態給manager節點.
3)服務(Service)
服務是要在worker節點上要執行任務的定義,它在工作者節點上執行,當你創建服務的時,你需要指定容器鏡像
4)任務(Task)
任務是在docekr容器中執行的命令,Manager節點根據指定數量的任務副本分配任務給worker節點
docker swarm:集群管理,子命令有init, join, leave, update。(docker swarm --help查看幫助)
docker service:服務創建,子命令有create, inspect, update, remove, tasks。(docker service--help查看幫助)
docker node:節點管理,子命令有accept, promote, demote, inspect, update, tasks, ls, rm。(docker node --help查看幫助)
node是加入到swarm集群中的一個docker引擎實體,可以在一台物理機上運行多個node,node分為manager nodes 也就是管理節點; worker nodes 也就是工作節點.
-> manager node管理節點:執行集群的管理功能,維護集群的狀態,選舉一個leader節點去執行調度任務。
-> worker node工作節點:接收和執行任務。參與容器集群負載調度,僅用於承載task。
-> service服務:一個服務是工作節點上執行任務的定義。創建一個服務,指定了容器所使用的鏡像和容器運行的命令。service是運行在worker nodes上的task的描述,service的描述包括使用哪個docker 鏡像,以及在使用該鏡像的容器中執行什么命令。
-> task任務:一個任務包含了一個容器及其運行的命令。task是service的執行實體,task啟動docker容器並在容器中執行任務。
Swarm工作方式
1)Node
2)Service(服務, 任務, 容器)
3)任務與調度
4)服務副本與全局服務
Swarm調度策略
Swarm在scheduler節點(leader節點)運行容器的時候,會根據指定的策略來計算最適合運行容器的節點,目前支持的策略有:spread, binpack, random.
1)Random
顧名思義,就是隨機選擇一個Node來運行容器,一般用作調試用,spread和binpack策略會根據各個節點可用的CPU, RAM以及正在運行的容器數量來計算應該運行容器的節點。
2)Spread
在同等條件下,Spread策略會選擇運行容器最少的那台節點來運行新的容器,binpack策略會選擇運行容器最集中的那台機器來運行新的節點。使用Spread策略會使得容器會均衡的分布在集群中的各個節點上運行,一旦一個節點掛掉了只會損失少部分的容器。
3)Binpack
Binpack策略最大化的避免容器碎片化,就是說binpack策略盡可能的把還未使用的節點留給需要更大空間的容器運行,盡可能的把容器運行在一個節點上面。
Swarm Cluster模式的特性
1)批量創建服務
建立容器之前先創建一個overlay的網絡,用來保證在不同主機上的容器網絡互通的網絡模式
2)強大的集群的容錯性
當容器副本中的其中某一個或某幾個節點宕機后,cluster會根據自己的服務注冊發現機制,以及之前設定的值--replicas n,在集群中剩余的空閑節點上,重新拉起容器副本。整個副本遷移的過程無需人工干預,遷移后原本的集群的load balance依舊好使!不難看出,docker service其實不僅僅是批量啟動服務這么簡單,而是在集群中定義了一種狀態。Cluster會持續檢測服務的健康狀態並維護集群的高可用性。
3)服務節點的可擴展性
Swarm Cluster不光只是提供了優秀的高可用性,同時也提供了節點彈性擴展或縮減的功能。當容器組想動態擴展時,只需通過scale參數即可復制出新的副本出來。仔細觀察的話,可以發現所有擴展出來的容器副本都run在原先的節點下面,如果有需求想在每台節點上都run一個相同的副本,方法其實很簡單,只需要在命令中將"--replicas n"更換成"--mode=global"即可!其中:
復制服務(--replicas n)將一系列復制任務分發至各節點當中,具體取決於您所需要的設置狀態,例如“--replicas 3”。
全局服務(--mode=global)適用於集群內全部可用節點上的服務任務,例如“--mode global”。如果在 Swarm 集群中設有 7 台 Docker 節點,則全部節點之上都將存在對應容器。
4) 調度機制
所謂的調度其主要功能是cluster的server端去選擇在哪個服務器節點上創建並啟動一個容器實例的動作。它是由一個裝箱算法和過濾器組合而成。每次通過過濾器(constraint)啟動容器的時候,swarm cluster 都會調用調度機制篩選出匹配約束條件的服務器,並在這上面運行容器。
Swarm cluster的創建過程包含以下三個步驟
1)發現Docker集群中的各個節點,收集節點狀態、角色信息,並監視節點狀態的變化
2)初始化內部調度(scheduler)模塊
3)創建並啟動API監聽服務模塊
一旦創建好這個cluster,就可以用命令docker service批量對集群內的容器進行操作,非常方便!
在啟動容器后,docker 會根據當前每個swarm節點的負載判斷,在負載最優的節點運行這個task任務,用"docker service ls" 和"docker service ps + taskID"
可以看到任務運行在哪個節點上。容器啟動后,有時需要等待一段時間才能完成容器創建。
Swarm集群部署實例(Swarm Cluster)
1)機器環境(均是centos7.2)
182.48.115.237 swarm的manager節點 manager-node 182.48.115.238 swarm的node節點 node1 182.48.115.239 swarm的node節點 node2 設置主機名 在manager節點上 [root@manager-node ~]# hostnamectl --static set-hostname manager-node 在node1節點上 [root@node1 ~]# hostnamectl --static set-hostname node1 在node2節點上 [root@node2 ~]# hostnamectl --static set-hostname node2 在三台機器上都要設置hosts,均執行如下命令: [root@manager-node ~]# vim /etc/hosts ...... 182.48.115.237 manager-node 182.48.115.238 node1 182.48.115.239 node2 關閉三台機器上的防火牆。如果開啟防火牆,則需要在所有節點的防火牆上依次放行2377/tcp(管理端口)、7946/udp(節點間通信端口)、4789/udp(overlay 網絡端口)端口。 [root@manager-node ~]# systemctl disable firewalld.service [root@manager-node ~]# systemctl stop firewalld.service
2)分別在manager節點和node節點上安裝docker,並下載swarm鏡像
[root@manager-node ~]# yum install -y docker 配置docker [root@manager-node ~]# vim /etc/sysconfig/docker ...... OPTIONS='-H 0.0.0.0:2375 -H unix:///var/run/docker.sock' //在OPTIONS參數項后面的''里添加內容. 或者使用'-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock' [root@manager-node ~]# systemctl restart docker 下載swarm鏡像 [root@manager-node ~]# docker pull swarm [root@manager-node ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/swarm latest 36b1e23becab 4 months ago 15.85 MB
3)創建swarm(要保存初始化后token,因為在節點加入時要使用token作為通訊的密鑰)
[root@manager-node ~]# docker swarm init --advertise-addr 182.48.115.237 Swarm initialized: current node (1gi8utvhu4rxy8oxar2g7h6gr) is now a manager. To add a worker to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-4roc8fx10cyfgj1w1td8m0pkyim08mve578wvl03eqcg5ll3ig-f0apd81qfdwv27rnx4a4y9jej \ 182.48.115.237:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions. 上面命令執行后,該機器自動加入到swarm集群。這個會創建一個集群token,獲取全球唯一的 token,作為集群唯一標識。后續將其他節點加入集群都會用到這個token值。 其中,--advertise-addr參數表示其它swarm中的worker節點使用此ip地址與manager聯系。命令的輸出包含了其它節點如何加入集群的命令。 ------------------------------------------------------------------------------------------------------------------- 溫馨提示: 如果再次執行上面啟動swarm集群的命令,會報錯說這個節點已經在集群中了 Error response from daemon: This node is already part of a swarm. Use "docker swarm leave" to leave this swarm and join another one. 解決辦法: [root@manager-node ~]# docker swarm leave --help //查看幫助 [root@manager-node ~]# docker swarm leave --force ------------------------------------------------------------------------------------------------------------------- 使用docker info 或 docker node ls 查看集群中的相關信息 [root@manager-node ~]# docker info ....... Swarm: active NodeID: 1gi8utvhu4rxy8oxar2g7h6gr Is Manager: true ClusterID: a88a9j6nwcbn31oz6zp9oc0f7 Managers: 1 Nodes: 1 Orchestration: Task History Retention Limit: 5 ....... [root@manager-node ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 1gi8utvhu4rxy8oxar2g7h6gr * manager-node Ready Active Leader 注意上面node ID旁邊那個*號表示現在連接到這個節點上。
4)添加節點到swarm集群中
在docker swarm init 完了之后,會提示如何加入新機器到集群,如果當時沒有注意到,也可以通過下面的命令來獲知 如何加入新機器到集群。 登錄到node1節點上,執行前面創建swarm集群時輸出的命令: [root@node1 ~]# docker swarm join --token SWMTKN-1-4roc8fx10cyfgj1w1td8m0pkyim08mve578wvl03eqcg5ll3ig-f0apd81qfdwv27rnx4a4y9jej 182.48.115.237:2377 This node joined a swarm as a worker. 同理在node2節點上,也執行這個命令 [root@node2 ~]# docker swarm join --token SWMTKN-1-4roc8fx10cyfgj1w1td8m0pkyim08mve578wvl03eqcg5ll3ig-f0apd81qfdwv27rnx4a4y9jej 182.48.115.237:2377 This node joined a swarm as a worker. 如果想要將其他更多的節點添加到這個swarm集群中,添加方法如上一致! 然后在manager-node管理節點上看一下集群節點的狀態: [root@manager-node ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 1gi8utvhu4rxy8oxar2g7h6gr * manager-node Ready Active Leader ei53e7o7jf0g36329r3szu4fi node1 Ready Active f1obgtudnykg51xzyj5fs1aev node2 Ready Active -------------------------------------------------------------------------------------------------------------------- 溫馨提示:更改節點的availablity狀態 swarm集群中node的availability狀態可以為 active或者drain,其中: active狀態下,node可以接受來自manager節點的任務分派; drain狀態下,node節點會結束task,且不再接受來自manager節點的任務分派(也就是下線節點)。 [root@manager-node ~]# docker node update --availability drain node1 //將node1節點下線。如果要刪除node1節點,命令是"docker node rm --force node1" [root@manager-node ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 1gi8utvhu4rxy8oxar2g7h6gr * manager-node Ready Active Leader ei53e7o7jf0g36329r3szu4fi node1 Ready drain f1obgtudnykg51xzyj5fs1aev node2 Ready Active 如上,當node1的狀態改為drain后,那么該節點就不會接受task任務分發,就算之前已經接受的任務也會轉移到別的節點上。 再次修改為active狀態(及將下線的節點再次上線) [root@manager-node ~]# docker node update --availability active node1
5)在Swarm中部署服務(這里以nginx服務為例)
Docker 1.12版本提供服務的Scaling、health check、滾動升級等功能,並提供了內置的dns、vip機制,實現service的服務發現和負載均衡能力。 在啟動容器之前,先來創建一個覆蓋網絡,用來保證在不同主機上的容器網絡互通的網絡模式 [root@manager-node ~]# docker network create -d overlay ngx_net [root@manager-node ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 8bbd1b7302a3 bridge bridge local 9e637a97a3b9 docker_gwbridge bridge local b5a41c8c71e7 host host local 1x45zepuysip ingress overlay swarm 3ye6vfp996i6 ngx_net overlay swarm 0808a5c72a0a none null local 在manager-node節點上使用上面這個覆蓋網絡創建nginx服務: 其中,--replicas 參數指定服務由幾個實例組成。 注意:不需要提前在節點上下載nginx鏡像,這個命令執行后會自動下載這個容器鏡像(比如此處創建tomcat容器,就將下面命令中的鏡像改為tomcat鏡像)。 [root@manager-node ~]# docker service create --replicas 1 --network ngx_net --name my-test -p 80:80 nginx 就創建了一個具有一個副本(--replicas 1 )的nginx服務,使用鏡像nginx 使用 docker service ls 查看正在運行服務的列表 [root@manager-node ~]# docker service ls ID NAME REPLICAS IMAGE COMMAND 0jb5eebo8j9q my-test 1/1 nginx 查詢Swarm中服務的信息 -pretty 使命令輸出格式化為可讀的格式,不加 --pretty 可以輸出更詳細的信息: [root@manager-node ~]# docker service inspect --pretty my-test ID: 0jb5eebo8j9qb1zc795vx3py3 Name: my-test Mode: Replicated Replicas: 1 Placement: UpdateConfig: Parallelism: 1 On failure: pause ContainerSpec: Image: nginx Resources: Networks: 3ye6vfp996i6eq17tue0c2jv9 Ports: Protocol = tcp TargetPort = 80 PublishedPort = 80 查詢到哪個節點正在運行該服務。如下該容器被調度到manager-node節點上啟動了,然后訪問http://182.48.115.237即可訪問這個容器應用(如果調度到其他節點,訪問也是如此) [root@manager-node ~]# docker service ps my-test ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 2m8qqpoa0dpeua5jbgz1infuy my-test.1 nginx manager-node Running Running 3 minutes ago 注意,如果上面命令執行后,上面的 STATE 字段中剛開始的服務狀態為 Preparing,需要等一會才能變為 Running 狀態,其中最費時間的應該是下載鏡像的過程。 有上面命令可知,該服務在manager-node節點上運行。登陸該節點,可以查看到nginx容器在運行中 [root@manager-node ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1ea1d72007da nginx:latest "nginx -g 'daemon off" 4 minutes ago Up 4 minutes 80/tcp my-test.1.2m8qqpoa0dpeua5jbgz1infuy -----------------------------------------------------------在Swarm中動態擴展服務(scale)----------------------------------------------------------- 當然,如果只是通過service啟動容器,swarm也算不上什么新鮮東西了。Service還提供了復制(類似kubernetes里的副本)功能。可以通過 docker service scale 命令來設置服務中容器的副本數: 比如將上面的my-test容器動態擴展到5個,命令如下: [root@manager-node ~]# docker service scale my-test=5 和創建服務一樣,增加scale數之后,將會創建新的容器,這些新啟動的容器也會經歷從准備到運行的過程,過一分鍾左右,服務應該就會啟動完成,這時候可以再來看一下 nginx 服務中的容器 [root@manager-node ~]# docker service ps my-test ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 2m8qqpoa0dpeua5jbgz1infuy my-test.1 nginx manager-node Running Running 9 minutes ago aqko8yhmdj53gmzs8gqhoylc2 my-test.2 nginx node2 Running Running 2 minutes ago erqk394hd4ay7nfwgaz4zp3s0 my-test.3 nginx node1 Running Running 2 minutes ago 2dslg6w16wzcgboa2hxw1c6k1 my-test.4 nginx node1 Running Running 2 minutes ago bmyddndlx6xi18hx4yinpakf3 my-test.5 nginx manager-node Running Running 2 minutes ago 可以看到,之前my-test容器只在manager-node節點上有一個實例,而現在又增加了4個實例。 這5個副本的my-test容器分別運行在這三個節點上,登陸這三個節點,就會發現已經存在運行着的my-test容器。 ----------------------------------------------------------------------------------------------------- 特別需要清楚的一點: 如果一個節點宕機了(即該節點就會從swarm集群中被踢出),則Docker應該會將在該節點運行的容器,調度到其他節點,以滿足指定數量的副本保持運行狀態。 比如: 將node1宕機后或將node1的docker服務關閉,那么它上面的task實例就會轉移到別的節點上。當node1節點恢復后,它轉移出去的task實例不會主動轉移回來, 只能等別的節點出現故障后轉移task實例到它的上面。使用命令"docker node ls",發現node1節點已不在swarm集群中了。 然后過一會查詢服務的狀態列表 [root@manager-node ~]# docker service ps my-test ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 2m8qqpoa0dpeua5jbgz1infuy my-test.1 docker.io/nginx manager-node Running Running 33 minutes ago aqko8yhmdj53gmzs8gqhoylc2 my-test.2 docker.io/nginx node2 Running Running 26 minutes ago di99oj7l9x6firw1ai25sewwc my-test.3 docker.io/nginx node2 Running Running 6 minutes ago erqk394hd4ay7nfwgaz4zp3s0 \_ my-test.3 docker.io/nginx node1 Shutdown Complete 5 minutes ago aibl3u3pph3fartub0mhwxvzr my-test.4 docker.io/nginx node2 Running Running 6 minutes ago 2dslg6w16wzcgboa2hxw1c6k1 \_ my-test.4 docker.io/nginx node1 Shutdown Complete 5 minutes ago bmyddndlx6xi18hx4yinpakf3 my-test.5 docker.io/nginx manager-node Running Running 26 minutes ago 發現,node1節點出現故障后,它上面之前的兩個task任務已經轉移到node2節點上了。 登陸到node2節點上,可以看到這兩個運行的task任務。當訪問182.48.115.239節點的80端口,swarm的負載均衡會把請求路由到一個任意節點的可用的容器上。 [root@node2 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 216abf6bebea docker.io/nginx:latest "nginx -g 'daemon off" 7 minutes ago Up 7 minutes 80/tcp my-test.3.di99oj7l9x6firw1ai25sewwc 1afd12cc9140 docker.io/nginx:latest "nginx -g 'daemon off" 7 minutes ago Up 7 minutes 80/tcp my-test.4.aibl3u3pph3fartub0mhwxvzr cc90da57c25e docker.io/nginx:latest "nginx -g 'daemon off" 27 minutes ago Up 27 minutes 80/tcp my-test.2.aqko8yhmdj53gmzs8gqhoylc2 再次在node2節點上將從node1上轉移過來的兩個task關閉 [root@node2 ~]# docker stop my-test.3.di99oj7l9x6firw1ai25sewwc my-test.4.aibl3u3pph3fartub0mhwxvzr my-test.3.di99oj7l9x6firw1ai25sewwc my-test.4.aibl3u3pph3fartub0mhwxvzr 再次查詢服務的狀態列表,發現這兩個task又轉移到node1上了(即在swarm cluster集群中啟動的容器,在worker node節點上刪除或停用后,該容器會自動轉移到其他的worker node節點上) [root@manager-node ~]# docker service ps my-test ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 2m8qqpoa0dpeua5jbgz1infuy my-test.1 docker.io/nginx manager-node Running Running 38 minutes ago aqko8yhmdj53gmzs8gqhoylc2 my-test.2 docker.io/nginx node2 Running Running 31 minutes ago 7dhmc63rk0bc8ngt59ix38l44 my-test.3 docker.io/nginx node1 Running Running about a minute ago di99oj7l9x6firw1ai25sewwc \_ my-test.3 docker.io/nginx node2 Shutdown Complete about a minute ago erqk394hd4ay7nfwgaz4zp3s0 \_ my-test.3 docker.io/nginx node1 Shutdown Complete 9 minutes ago 607tyjv6foc0ztjjvdo3l3lge my-test.4 docker.io/nginx node1 Running Running about a minute ago aibl3u3pph3fartub0mhwxvzr \_ my-test.4 docker.io/nginx node2 Shutdown Complete about a minute ago 2dslg6w16wzcgboa2hxw1c6k1 \_ my-test.4 docker.io/nginx node1 Shutdown Complete 9 minutes ago bmyddndlx6xi18hx4yinpakf3 my-test.5 docker.io/nginx manager-node Running Running 31 minutes ago ---------------------------------------------------------------------------------------------------- 同理,swarm還可以縮容,如下,將my-test容器變為1個。 [root@manager-node ~]# docker service scale my-test=1 [root@manager-node ~]# docker service ps my-test ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 2m8qqpoa0dpeuasdfsdfdfsdf my-test.1 nginx manager-node Running Running 3 minutes ago 登錄node2節點,使用docker ps查看,會發現容器被stop而非rm --------------------------------------------------------------------------------------------------- 刪除容器服務 [root@manager-node ~]# docker service --help //查看幫助 [root@manager-node ~]# docker service rm my-test //這樣就會把所有節點上的所有容器(task任務實例)全部刪除了 my-nginx --------------------------------------------------------------------------------------------------- 除了上面使用scale進行容器的擴容或縮容之外,還可以使用docker service update 命令。 可對 服務的啟動 參數 進行 更新/修改。 [root@manager-node ~]# docker service update --replicas 3 my-test my-test 更新完畢以后,可以查看到REPLICAS已經變成3/3 [root@manager-node ~]# docker service ls ID NAME REPLICAS IMAGE COMMAND d7cygmer0yy5 my-test 3/3 nginx /bin/bash [root@manager-node ~]# docker service ps my-test ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR ddkidkz0jgor751ffst55kvx4 my-test.1 nginx node1 Running Preparing 4 seconds ago 1aucul1b3qwlmu6ocu312nyst \_ my-test.1 nginx manager-node Shutdown Complete 5 seconds ago 4w9xof53f0falej9nqgq064jz \_ my-test.1 nginx manager-node Shutdown Complete 19 seconds ago 0e9szyfbimaow9tffxfeymci2 \_ my-test.1 nginx manager-node Shutdown Complete 30 seconds ago 27aqnlclp0capnp1us1wuiaxm my-test.2 nginx manager-node Running Preparing 1 seconds ago 7dmmmle29uuiz8ey3tq06ebb8 my-test.3 nginx manager-node Running Preparing 1 seconds ago docker service update 命令,也可用於直接 升級 鏡像等。 [root@manager-node ~]# docker service update --image nginx:new my-test [root@manager-node ~]# docker service ls ID NAME REPLICAS IMAGE COMMAND d7cygmer0yy5 my-test 3/3 nginx:new /bin/bash
6)Swarm中使用Volume(掛在目錄: --mount type=volume 或者 --mount type=bind )
查看docker volume的幫助信息 [root@manager-node ~]# docker volume --help Usage: docker volume COMMAND Manage Docker volumes Options: --help Print usage Commands: create Create a volume inspect Display detailed information on one or more volumes ls List volumes rm Remove one or more volumes Run 'docker volume COMMAND --help' for more information on a command. [root@manager-node ~]# docker volume create --name myvolume myvolume [root@manager-node ~]# docker volume ls DRIVER VOLUME NAME local 11b68dce3fff0d57172e18bc4e4cfc252b984354485d747bf24abc9b11688171 local 1cd106ed7416f52d6c77ed19ee7e954df4fa810493bb7e6cf01775da8f9c475f local myvolume 參數src寫成source也可以;dst表示容器內的路徑,也可以寫成destination [root@manager-node ~]# docker service create --replicas 2 --network ngx_net --mount type=volume,src=myvolume,dst=/wangshibo --name test-nginx nginx ==================================================== 溫馨提示: 必須確保各節點服務器的selinux永久關閉,即: [root@manager-node ~]# cat /etc/sysconfig/selinux SELINUX=disabled [root@manager-node ~]# reboot [root@manager-node ~]# getenforce Disabled 必須是永久關閉,臨時關閉可能都不行,否則上面創建命令后,可能會出現如下報錯: [root@manager-node ~]# docker service ps test-nginx "SELinux relabeling of is not allowed" ==================================================== [root@manager-node ~]# docker service ls ID NAME REPLICAS IMAGE COMMAND 8s9m0okwlhvl test-nginx 2/2 nginx [root@manager-node ~]# docker service ps test-nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 32bqjjhqcl1k5z74ijjli35z3 test-nginx.1 nginx node1 Running Running 23 seconds ago 48xoypunb3g401jkn690lx7xt test-nginx.2 nginx node2 Running Running 23 seconds ago 登錄node1節點的test-nginx容器查看 [root@node1 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d471569629b2 nginx:latest "nginx -g 'daemon off" 2 minutes ago Up 2 minutes 80/tcp test-nginx.1.32bqjjhqcl1k5z74ijjli35z3 [root@node1 ~]# docker exec -ti d471569629b2 /bin/bash root@d471569629b2:/# cd /wangshibo/ root@d471569629b2:/wangshibo# ls root@d471569629b2:/wangshibo# echo "ahahha" > test root@d471569629b2:/wangshibo# ls test [root@node1 ~]# docker volume inspect myvolume [ { "Name": "myvolume", "Driver": "local", "Mountpoint": "/var/lib/docker/volumes/myvolume/_data", "Labels": null, "Scope": "local" } ] [root@node1 ~]# cd /var/lib/docker/volumes/myvolume/_data/ [root@node1 _data]# ls test [root@node1 _data]# cat test ahahha [root@node1 _data]# echo "12313" > 123 [root@node1 _data]# ls 123 test root@d471569629b2:/wangshibo# ls 123 test root@d471569629b2:/wangshibo# cat test ahahha 需要注意: 1) 掛載volume后,宿主機和容器之間就可以通過volume進行雙向實時同步. 2) 如果replicas是多份,則每個節點宿主機上都會有一個volume路徑,即每個節點宿主機的/var/lib/docker/volumes/myvolume/_data和分布到它上面的 容器里的/wangshibo進行實時同步. ============================================================ 第二種方法: 命令格式: docker service create --mount type=bind,source=/host_data/,destination=/container_data/ 其中,參數target表示容器里面的路徑,source表示本地硬盤路徑 [root@manager-node ~]# docker service create --replicas 1 --mount type=bind,source=/opt/web/,destination=/usr/share/nginx/html/ --network ngx_net --name haha-nginx -p 8880:80 nginx [root@manager-node ~]# docker service ls ID NAME REPLICAS IMAGE COMMAND 9t9d58b5bq4u haha-nginx 1/1 nginx [root@manager-node ~]# docker service ps haha-nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR bji4f5tikhvm7nf5ief3jk2is haha-nginx.1 nginx node2 Running Running 18 seconds ago 登錄node2節點,在掛載目錄/opt/web下寫測試數據 [root@node2 _data]# cd /opt/web/ [root@node2 web]# ls [root@node2 web]# cat wang.html sdfasdf 登錄容器查看,發現已經實現數據同步 [root@node2 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3618e3d1b966 nginx:latest "nginx -g 'daemon off" 28 seconds ago Up 24 seconds 80/tcp haha-nginx.1.bji4f5tikhvm7nf5ief3jk2is [root@node2 ~]# docker exec -ti 3618e3d1b966 /bin/bash root@3618e3d1b966:/# cd /usr/share/nginx/html root@3618e3d1b966:/usr/share/nginx/html# ls wang.html root@3618e3d1b966:/usr/share/nginx/html# cat wang.html sdfasdf root@3618e3d1b966:/usr/share/nginx/html# touch test touch: cannot touch 'test': Permission denied 由此可見,以上設置后,在容器里的同步目錄下沒有寫權限,更新內容時只要放到宿主機的掛在目錄下即可!
總之,Swarm上手很簡單,Docker swarm可以非常方便的創建類似kubernetes那樣帶有副本的服務,確保一定數量的容器運行,保證服務的高可用。
然而,光從官方文檔來說,功能似乎又有些簡單;
swarm、kubernetes、messos總體比較而言:
1)Swarm的優點和缺點都是使用標准的Docker接口,使用簡單,容易集成到現有系統,但是更困難支持更復雜的調度,比如以定制接口方式定義的調度。
2)Kubernetes 是自成體系的管理工具,有自己的服務發現和復制,需要對現有應用的重新設計,但是能支持失敗冗余和擴展系統。
3)Mesos是低級別 battle-hardened調度器,支持幾種容器管理框架如Marathon, Kubernetes, and Swarm,現在Kubernetes和Mesos穩定性超過Swarm,在擴展性方面,Mesos已經被證明支持超大規模的系統,比如數百數千台主機,但是,如果你需要小的集群,比如少於一打數量的節點服務器數量,Mesos也許過於復雜了。