Docker Get Started IV
4. Swarms
介紹
在前面的部分,你知道了如何寫一個應用以及如何執行在生產環境中,然後將它變為一個服務,在同一個程序中將服務能力伸縮到原來的5倍。
在本部分,你將在叢集上部署一個應用,執行在多臺機器上。通過將多個機器加入到docker化的叢集中,多容器多機器的應用是可能的,這個docker化的叢集被稱為蜂群。
理解蜂群
一個蜂群是一組執行docker的機器,組合成了一個叢集。在蜂群上,你也可以執行docker命令,但是在叢集上,docker命令是被蜂群管理器(swarm manager)執行的。蜂群中的機器可以是物理機,也可以是虛擬機器。這些機器加入某個蜂群后,他們被稱做節點(node)。
蜂群能使用多種策略來執行容器,例如“emptiest node”,這個策略將首先在資源利用最小的機器上執行容器,還有“global”策略,這個確保每個機器都恰好有一個容器執行。通過Compose檔案,你可以指定swarm manager使用何種策略。
蜂群管理器是蜂群中唯一能執行你命令或者授權其他機器加入蜂群的機器。works是那些提供資源但是沒有能力指揮其他機器的機器。
到目前為止,你使用docker還都是停留在單機模式。docker也可以切換到swarm模式,該模式下可以組建蜂群。啟用swarm模式使得你當前的機器變為一個swarm manager。接下來,Docker將會在整個蜂群上執行你的docker命令,而非你當前的機器上。
設定蜂群
一個蜂群是由多個節點組成的,這些節點要麼是物理的或者虛擬的。使用以下命令啟用swarm模式:
docker swarm init
該命令啟用了swarm模式,並把當前機器設定為了swarm manager。
對去其他機器,你可以執行如下命令來加入到某個蜂群成為裡面的一個worker。
docker swarm join
下面我們使用虛擬機器來建立一個包含兩個機器的叢集,以此來組建一個蜂群。
建立叢集
我們需要一個hypervisor來建立虛擬機器,因此安裝Oracal VirtualBox。
安裝完畢後,我們使用docker-machine來建立3個虛擬機器。
docker-machine create --driver virtualbox myvm1 docker-machine create --driver virtualbox myvm2 docker-machine create --driver virtualbox myvm3
列出虛擬機器檢視對應的IP地址
docker-machine ls
2376是虛擬機器上docker守護程序的埠號。
初始化蜂群,然後增加節點
我們選擇第一臺虛擬機器作為swarm manager,這臺機器執行docker命令和授權其他worker加入到這個蜂群,剩下的兩臺虛擬機器作為worker。
我們可以使用docker-machine ssh到虛擬機器上執行shell命令。
先連上myvm1虛擬機器:
docker-machine ssh myvm1 "docker swarm init --advertise-addr 192.168.99.100"
上面的命令ssh連線到myvm1,然後執行初始化蜂群的命令。
可以看到myvm1上初始化蜂群成功,且作為了swarm manager,暴露了2377埠用於其他機器與其通訊加入蜂群。
接下來我們需要將剩餘兩臺虛擬機器作為worker加入到蜂群中:
docker-machine ssh myvm2 "docker swarm join --token \
SWMTKN-1-623gp73gn96xqhjclwob4lipvuis34lnshb0g5c7uu31s5c2sx-f3ux24m2vqdecn29oxurs2kim \
192.168.99.100:2377"
docker-machine ssh myvm3 "docker swarm join --token \
SWMTKN-1-623gp73gn96xqhjclwob4lipvuis34lnshb0g5c7uu31s5c2sx-f3ux24m2vqdecn29oxurs2kim \
192.168.99.100:2377"
ssh到swarm manager上使用docker node ls檢視節點概況,只有是swarm manager才可以使用該命令檢視節點概況。
docker-machine ssh myvm1 "docker node ls"
在蜂群上部署app
接下來的部署和前面在單機上部署service類似。
上面我們一致通過docker-machine ssh到遠端虛擬機器上執行shell命令,因此不太方便,現在我們先配置一個docker-machine shell到swarm manager這個遠端虛擬機器。這樣配置好後,就運訓使用本地的docker-compose.yml檔案來遠端部署app了,而不用把這個檔案拷貝來拷貝去。
docker-machine env myvm1
執行命令:
eval $(docker-machine env myvm1) #這一步在設定當前shell的環境變數
執行docker-machine ls驗證一下當前的shell確實是連線到myvm1上的。
docker-machine ls
在swarm manager上部署app
和之前的內容一樣,使用docker stack deploy進行部署:
docker stack deploy -c docker-compose.yml getstartedlab
檢視部署的結果:
docker stack ps getstartedlab
可以看到5個容器例項分散在蜂群中的不同節點上。
訪問叢集
web訪問一下試試:
使用3個虛擬機器的IP地址訪問服務:
不同的IP地址隨機出現不同的主機名,表明多容器、多機器叢集部署完成。
所有IP地址都能訪問部署的app的原因是蜂群中的節點組成了一個ingress網路,構建了一個路由網路。這個保證了部署蜂群上的某個埠上的某個服務,蜂群上的節點都要保留這個埠,無論哪個節點執行容器。下面是一個暴露8080埠的蜂群的網路路由示意圖:
迭代和擴容app
如果需要擴縮容,只需要修改docker-compose檔案即可完成。
如果需要對app的功能進行迭代,那麼需要編碼、重新構建、釋出新的映象。最後只需要重新執行docker stack deploy重新部署即可。
清理和重啟
Stacks和Swarms
拆除部署的stack
docker stack rm getstartedlab
重置docker-machine shell變數
eval $(docker-machine env -u)
重啟機器:
docker-machine start <machine-name>
cheet sheet
docker-machine create --driver virtualbox myvm1 # Create a VM (Mac, Win7, Linux)
docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm1 # Win10
docker-machine env myvm1 # View basic information about your node
docker-machine ssh myvm1 "docker node ls" # List the nodes in your swarm
docker-machine ssh myvm1 "docker node inspect <node ID>" # Inspect a node
docker-machine ssh myvm1 "docker swarm join-token -q worker" # View join token
docker-machine ssh myvm1 # Open an SSH session with the VM; type "exit" to end
docker node ls # View nodes in swarm (while logged on to manager)
docker-machine ssh myvm2 "docker swarm leave" # Make the worker leave the swarm
docker-machine ssh myvm1 "docker swarm leave -f" # Make master leave, kill swarm
docker-machine ls # list VMs, asterisk shows which VM this shell is talking to
docker-machine start myvm1 # Start a VM that is currently not running
docker-machine env myvm1 # show environment variables and command for myvm1
eval $(docker-machine env myvm1) # Mac command to connect shell to myvm1
& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression # Windows command to connect shell to myvm1
docker stack deploy -c <file> <app> # Deploy an app; command shell must be set to talk to manager (myvm1), uses local Compose file
docker-machine scp docker-compose.yml myvm1:~ # Copy file to node's home dir (only required if you use ssh to connect to manager and deploy the app)
docker-machine ssh myvm1 "docker stack deploy -c <file> <app>" # Deploy an app using ssh (you must have first copied the Compose file to myvm1)
eval $(docker-machine env -u) # Disconnect shell from VMs, use native docker
docker-machine stop $(docker-machine ls -q) # Stop all running VMs
docker-machine rm $(docker-machine ls -q) # Delete all VMs and their disk images