前言
相信Docker技術大家都有所瞭解,單個Docker能發揮的作用畢竟有限,也不便於管理,所以Docker得組叢集來使用才能發揮強大的技術優勢。既然要組叢集那就涉及諸如Docker的資源排程、管理等等一系列問題。目前涉及Docker叢集的三個主要的技術無外乎Swarm、Kubernetes、Mesos三種。從本文開始作者將會一一實踐這幾種主要的Docker叢集技術,話不多說,現在開始。
注: 本文首發於 My 公眾號 CodeSheep ,可 長按 或 掃描 下面的 小心心 來訂閱 ↓ ↓ ↓
環境準備
- Mac OS X 10.13.2
- Docker 17.09.1-ce-mac42 (21090)
- virtualbox(虛擬叢集中節點時需要)
- boot2docker v1.8.0(在虛擬節點中起docker環境時需要)
環境搭建
節點規劃如下:
我們需要4個節點(1個master + 3個slave),由於沒有真實地4臺物理機,所以下文中是靠docker-machine
、virtualbox
以及boot2docker
來虛擬出4個獨立IP地址的帶docker環境的節點,大家注意!
環境安裝:
- Docker環境安裝:
Tips: 以前Mac上一般是使用
boot2docker
這個專門為OS X上執行 Docker 而開發的一個輕量級的虛擬主機管理工具來安裝docker,現在boot2docker
這種安裝方式官方已經deprecated 了(當然下文中還是需要boot2docker.iso
的映象來幫助我們在虛擬的節點上起docker環境),可以直接下載docker的dmg安裝包雙擊進行安裝即可
我們選擇docker CE版安裝即可,下載連結如下:
https://store.docker.com/search?type=edition&offering=community
注意:選擇官方docker dmg包安裝完成以後,
docker-machine
已經天然地整合於其中了,該工具在下文中建立虛擬節點時需要,它是一個可以在虛擬主機節點上安裝docker engine的工具
- virtualbox安裝
由於我們搭建叢集需要具備多個不同IP地址的節點,然而我們手上僅一臺電腦,所以需要藉助virtualbox來虛擬出多個不同IP地址的節點供我們使用需要
去官方下載virtualbox的dmg安裝包,雙擊安裝即可:
https://www.virtualbox.org/
- boot2docker安裝
Boot2Docker是一個專為Docker而設計的輕量級Linux髮型包,解決Windows或者OS X使用者不能安裝Docker的問題。Boot2Docker完全執行於記憶體中,體積小,啟動快。Boot2Docker需要執行在VirtualBox中。
我使用的是brew這個mac上的包管理器安裝的,非常方便,只需一行命令:
brew install boot2docker
除此之外我們還需要下載boot2docker.iso映象在後文中進行使用:
https://github.com/boot2docker/boot2docker/releases/tag/v17.07.0-ce
我們先把boot2docker.iso
下好後面備用
Docker Swarm叢集實驗
先建立4個虛擬節點(1個master + 3個slave)
首先要將之前下載的boot2docker.iso
放到/Users/你的使用者名稱/.docker/machine/cache/
目錄下,然後執行如下命令:
docker-machine create --virtualbox-boot2docker-url ~/.docker/machine/cache/boot2docker.iso master
docker-machine create --virtualbox-boot2docker-url ~/.docker/machine/cache/boot2docker.iso slave1
docker-machine create --virtualbox-boot2docker-url ~/.docker/machine/cache/boot2docker.iso slave2
docker-machine create --virtualbox-boot2docker-url ~/.docker/machine/cache/boot2docker.iso slave3
複製程式碼
注意:上面若不指定boot2docker的路徑:
--virtualbox-boot2docker-url ~/.docker/machine/cache/boot2docker.iso
,直接執行docker-machine create master
建立節點時,可能會報No default Boot2Docker ISO found locally, downloading the latest release...
這種錯誤!所以最好自己指定boot2docker.iso映象路徑
docker-machine命令建立虛擬機器過程細節如下:
建立完4個節點以後,可以用docker-machine ls
命令檢視一下各個節點的情況,可以看到自動為其分配了獨立的IP地址:
ssh接入虛擬節點
開啟4個獨立的terminal終端,分別執行:
docker-machine ssh master
docker-machine ssh slave1
docker-machine ssh slave2
docker-machine ssh slave3
複製程式碼
執行後的效果如下圖:
接下來在master上初始化一個docker swarm叢集
執行命令:
docker swarm init --advertise-addr 192.168.99.100
複製程式碼
效果如下:
上述命令執行成功後,提示中會告知使用者在slave節點上執行命令 docker swarm join --token SWMTKN-1-1uzft9zcrd5cl7eva4gr4ptgrs1gc252483ey19xfphcuxc8ta-evsmmj7b7kleh7yoezjutzuu2 192.168.99.100:2377
可以加入到該叢集中,把命令都告訴你了,你說智不只能!
將3個slave節點加入叢集
分別去三個slave上,輸入上面提示中的命令:
docker swarm join --token SWMTKN-1-1uzft9zcrd5cl7eva4gr4ptgrs1gc252483ey19xfphcuxc8ta-evsmmj7b7kleh7yoezjutzuu2 192.168.99.100:2377
複製程式碼
執行效果如下:
注意:如果忘了docker swarm join 命令中的token命令的話,可以使用命令
docker swarm join-token worker
來get之
好,到此為止應該說docker swarm叢集的搭建工作已經完成了,那下面在這個叢集上做點實際的任務吧!
開始在master節點上建立服務
我們計劃在該docker叢集上部署高可用的nginx容器任務來作為演示:
在master節點上執行如下命令來建立名為mynginx的service,讓其有2份nginx容器副本分配到叢集中去,起在8080埠:
docker service create --replicas 2 -d -p 8080:80 --name mynginx registry.docker-cn.com/library/nginx
然後使用如下兩條命令檢視效果:
docker service ls
docker service ps mynginx
複製程式碼
執行效果如下:
此處有兩點需要注意:
- 我們使用了
registry.docker-cn.com/library/nginx
作為加速映象,不然可能在slave上pull映象的時候timeout - 注意此處建立了service之後並不是nginx容器立馬都在slave上起起來了,是需要等一段時間的(如,我等了近8分鐘),因為在slave上還要去pull nginx映象,再啟動nginx容器等,沒有那麼快
等待若干分鐘以後,我們再看效果,發現此時任務順利地分發到slave1和slave2上了:
分別用瀏覽器訪問:
http://192.168.99.101:8080 和 http://192.168.99.102:8080 ,會得到如下結果:
成功訪問到了slave節點中起起來的nginx服務!
此時分別去 slave1 和 slave2 上檢視容器執行情況,結果如下:
進一步實驗:擴容service中的任務
我們想將nginx容器平滑地擴容到3份,在master上執行:
docker service scale mynginx=3
複製程式碼
然後在master上檢視service,發現新增的一個容器任務分配到slave3上了,當然此時slave3上正在preparing:
等若干分鐘後在master上再次檢視service,發現slave3上的nginx容器任務成功啟動了:
去slave3節點上docker ps看一下,發現容器確實啟動了:
####進一步實驗:叢集中service高可用
目前有3個執行的nginx容器保證服務的可用性,如果其中一個容器意外關閉將會是什麼情況?接下來就來模擬
我們關閉slave1上此時正在執行著的nginx容器,看服務有什麼變化:
此時去master節點上檢視資訊發現,被關掉的nginx被分配到master上重啟了:
此時我又關閉master節點上啟動的nginx容器,發現剛關閉不久後,nginx容器又重新在master上恢復了:
接下來我們來將slave3當機(當機和前文的關閉nginx容器不同,此處模仿的是物理當機),我們在控制檯中使用docker-machine stop來模擬當機動作:
此時去master上檢視service資訊發現slave3當機以後,nginx任務又重啟與slave1上來保持高可用:
最後來把狠的,我們將slave1,slave2,slave3全部從叢集中斷開:
結果去master上檢視service資訊,發現3個容器副本全部遷移到master之上了:
此時在master上執行docker ps
檢視容器資訊如下:執行著3個nginx容器:
總而言之,無論怎麼操作叢集都能保持制定數量的容器副本來實現高可用!
【乾貨】總結一下上文中的常用命令
- 建立虛擬主機節點
docker-machine create 虛擬主機名
複製程式碼
- 檢視虛擬機器節點資訊
docker-machine ls
複製程式碼
- 停止虛擬主機節點
docker-machine stop 虛擬主機名
複製程式碼
- 刪除虛擬主機節點
docker-machine rm 虛擬主機名
複製程式碼
- 初始化docker swarm叢集
docker swarm init --advertise-addr master的IP地址
複製程式碼
- slave節點加入叢集
docker swarm join --token [token] [master的IP]:[master的埠]
複製程式碼
- slave節點主動離開叢集
docker swarm leave
複製程式碼
- 在master上獲取加入叢集的token
docker swarm join-token worker
複製程式碼
- master上建立service舉例:
docker service create --replicas 2 -d -p 8080:80 --name 服務名 映象名
複製程式碼
- master上檢視service資訊
docker service ls
docker service ps 你所建立的服務的ID
複製程式碼
- 在master上刪除service
docker service rm 服務名
複製程式碼
- 在master上進行服務擴容
docker service scale 你的service name=你要的副本數目
複製程式碼
參考文獻
- http://www.widuu.com/docker/installation/mac.html
- http://www.widuu.com/docker/installation/mac.html
- https://www.docker.com/community-edition
- https://www.docker.com/community-edition
- https://www.jianshu.com/p/096244610e15
- https://www.cnblogs.com/atuotuo/p/6265541.html
後記
作者更多的SpringBt實踐文章在此:
- Spring Boot應用監控實戰
- SpringBoot應用部署於外接Tomcat容器
- ElasticSearch搜尋引擎在SpringBt中的實踐
- 初探Kotlin+SpringBoot聯合程式設計
- Spring Boot日誌框架實踐
- SpringBoot優雅編碼之:Lombok加持
如果有興趣,也可以抽點時間看看作者一些關於容器化、微服務化方面的文章:
- 利用K8S技術棧打造個人私有云 連載文章
- 從一份配置清單詳解Nginx伺服器配置
- Docker容器視覺化監控中心搭建
- 利用ELK搭建Docker容器化應用日誌中心
- RPC框架實踐之:Apache Thrift
- RPC框架實踐之:Google gRPC
- 微服務呼叫鏈追蹤中心搭建
- Docker容器跨主機通訊
- Docker Swarm叢集初探
- 高效編寫Dockerfile的幾條準則