一、介紹
docker swarm是創建服務器集群的工具,只需要幾條命令就可以創建一個服務器集群。它內置一些服務器集群需要的工具,比如說:服務查找,網絡,負載均衡等等。
docker swarm
先初始化一個集群(docker swarm init
),然后讓服務器加入到這個集群里面(docker swarm join
),這樣就可以在這個集群服務器上面與創建服務(docker service create
),一個服務可以用一個或多容器來支持,容器之間會通過overlay網絡類型進行通信。每一個服務器節點都知道這個集群里的其他服務器,如果某一個服務器節點出了問題,docker會將出了問題的服務器上面運行的容器,轉移到集群里的其他服務器上面。我們不需要配置容器之間和服務器之間的負載均衡,因為它是docker swarm內置的功能。
二、集群
我在本地使用虛擬機創建了3個Linux系統的虛擬機,模擬三臺服務器(node1[192.168.33.10], node2[192.168.33.11], node3[192.168.33.12])。
1. 創建集群 - swarm init##
首先進入到node1中,初始化一個集群:
docker swarm init --advertise-addr 192.168.33.10:2377
說明:192.168.33.10是node1的ip地址,--advertise-addr選項是設置監聽的IP和端口號。執行完,看到提示「集群已經初始完,當前節點是管理員」表示初始化成功。后面還有添加woker節點的指示和命令。
docker swarm join \\
--token SWMTKN-1-6cqcc65jtfmldojryxg7s4rpljekcdrobz288mycgyu12gfxlf-bg27cxk75qhbgwjngxn500lqg \\
192.168.33.10:2377
初始化完,查看集群上節點的列表,可以執行:
docker node ls
目前只有node1一個節點,狀態為Ready,是個Leader。
2. 添加服務器到集群里 - swarm join##
接著登錄到node2中,執行初始化完成后返回的指令。
這里會提示「這個節點已作為worker加入到集群中」,再登錄到node3,同樣的也把它加入到集群中。
然后回到node1,查看集群的節點列表:
現在這個集群里一共有三個服務器。node1為管理員,node2,node3為worker。
3. 創建集群網絡 - overlay##
在集群節點中運行的容器需要一種overlay類型的網絡,我們可以先去創建一個overlay網絡,然后在創建服務的時候使用這個網絡。
docker network create --driver overlay skynet
可以看到新創建的網絡skynet,類型為overlay。
4. Swarm - 狀態的圖形界面##
為了更好的理解集群,我們可以創建一個visualizer,可以即時的查看集群中服務器的狀態和服務器上面運行容器的狀態。
登錄到manager node1上,執行:
docker run -itd -p 5000:5000 -e HOST=192.168.33.10 -e PORT=5000 -v /var/run/docker.sock:/var/run/docker.sock manomarks/visualizer
(這之前我已經pull過manomarks/visualizer的鏡像)
打開瀏覽器,訪問http://192.168.33.10:5000:
三、服務
1. 創建服務 - service create##
創建好集群服務器以后就可以創建服務了,創建服務可以執行:
docker service create --name web --network skynet --publish 3000:3000 --replicas 1 ninghao/node
創建一個名字叫web,網絡使用剛剛創建的skynet,使用--publish
指定發布的端口號,這里的3000:3000是ninghao/node鏡像里的nodejs應用使用的端口號,--replicas
指定需要的數量。
接著查看一下服務的列表:
docker service ls
剛創建完成的服務web,REPLICASE的值為0/1,表示正處于prepare的狀態,還沒正式運行。
查看服務的狀態可以執行:
docker service ps web
等待狀態變為Running的時候,在瀏覽器打開http://192.168.33.10:5000 就可以查看到新增的服務:
訪問http://192.168.33.10:3000 :
2. 負載均衡 - load balancing##
現在我們已經在集群里創建一個web服務,服務現在只有一個容器,使用docker service ps web
可以查看到容器在node1機器上面。上面我們通過訪問node1的ip:192.168.33.10:3000查看到頁面,那么嘗試訪問node2(192.168.33.11)和node3(192.168.33.12)的3000端口看看。
你會發現雖然在node2和node3上沒有容器運行那個應用,但還是可以打開頁面,觀察頁面顯示的Container ID是一樣的,可見頁面是同一個容器提供的服務。這就docker里面的routing mesh技術,而且還內置了負載均衡的功能。如果訪問的服務器上沒有提供服務的容器,那docker會重定向到有這個服務容器的機器上面。
3. 擴展服務 - service scale##
scale up一下web服務,現在這個服務只有一個容器,在node1上面執行:
docker service scale web=6
web表示服務名稱,= 右邊表示容器的數量,執行完,回到瀏覽器查看,會陸陸續續出現其他的5個容器,分別分布在3臺機器上:
重新訪問一下:http://192.168.33.10:3000 ,留意Container ID會有變化,現在同時使用多個容器提供服務:
scale可以增加容器,也可以減少容器。執行:
docker service scale web=3
現在每臺服務器上都只有一個容器提供服務,總共3個容器。這是我們設置的web的狀態,docker會維護這個狀態,現在我們關閉node3的機器:
node3關閉后,它上面的容器也不見了,但過了一會,少了的容器,會出現在集群里其他機器上面。這里是跑到了node2上面:
更新服務 - service update
如果我們想要更新提供服務的容器中的一些信息,比如:端口、數據卷、鏡像等等,可以使用:
docker service update [OPTIONS]
先scale up 到6個,下面我們更新一下服務使用的鏡像:
docker service update web --image ninghao/node:hola
開始更新:
完成更新:
你會發現docker會使用我們指定的鏡像去逐個逐個更新(舊版本好像會一次全部停掉,再逐個更新),新的容器創建好以后,我們再去瀏覽一下。
已更新,hello會變成hola。這個更新的動作過程我們可以指定,比如說想一次更新兩個容器,每次更新的時候中間停幾秒。這次換回原來的hello
docker service update web --image ninghao/node --update-parallelism 2 --update-delay 6s
--update-parallelism
指定每次更新的容器數。
--update-delay
指定容器更新的間隔。
執行的一開始會消失掉兩個容器,隨后更新完成兩個容器后,會等待6秒,然后再更新兩個。具體可以在http://192.168.33.10:5000 觀察完整過程。