您好,登錄后才能下訂單哦!
Swarm是Docker公司推出的用來管理docker集群的平臺,幾乎全部用GO語言來完成的開發的,代碼開源在https://github.com/docker/swarm, 它是將一群Docker宿主機變成一個單一的虛擬主機,Swarm使用標準的Docker API接口作為其前端的訪問入口,換言之,各種形式的Docker
Client(compose,docker-py等)均可以直接與Swarm通信,甚至Docker本身都可以很容易的與Swarm集成,這大大方便了用戶將原本基于單節點的系統移植到Swarm上,同時Swarm內置了對Docker網絡插件的支持,用戶也很容易的部署跨主機的容器集群服務。
從 Docker 1.12.0 版本開始,Docker Swarm 已經包含在 Docker 引擎中(docker swarm),并且已經內置了服務發現工具,我們就不需要像之前一樣,再配置 Etcd 或者 Consul 來進行服務發現配置了。
Docker swarm中有三種角色:
- Manager node:負責執行容器的編排和集群的管理工作,保持并維護swarm處于期望的狀態,swarm可以有多個manager node,他們會自動協商選舉出一個leader執行編排任務;但相反,不能沒有manager node;
- Worker node:接受并執行由manager node派發的任務,并且默認manager node也是一個work node,不過可以將它設置manager-only node,讓它負責編排和管理工作;
- Service:用來定義worker上執行的命令;
注意:在一個Docker Swarm群集中,每臺docker服務器的角色可以都是manager,但是,不可以都是worker,也就是說,不可以群龍無首,并且,參與群集的所有主機名,千萬不可以沖突。
注意事項:
[root@node01 ~]# tail -3 /etc/hosts
192.168.1.1 node01
192.168.1.2 node02
192.168.1.3 node03
//三臺主機都需配置hosts文件實現域名解析的效果
[root@node01 ~]# docker swarm init --advertise-addr 192.168.1.1
//--advertise-addr:指定與其他node通信的地址
命令的返回信息,如圖:
圖中①的命令:以worker身份加入swarm群集中的命令;
②的命令:以manager身份加入swarm群集中的方法;
出現上圖表示初始化成功!注意:--token表示期限為24小時;
###################node02的操作如下###################
[root@node02 ~]# docker swarm join --token SWMTKN-1-4pc1gjwjrp9h5dny52j58m0lclq88ngovis0w3rinjd05lklu5-ay18vjhwu7w8gsqvct84fv8ic 192.168.1.1:2377
###################node03的操作如下###################
[root@node03 ~]# docker swarm join --token SWMTKN-1-4pc1gjwjrp9h5dny52j58m0lclq88ngovis0w3rinjd05lklu5-ay18vjhwu7w8gsqvct84fv8ic 192.168.1.1:2377
//node02、node03默認是以worker身份加入的
###################node01的操作如下###################
[root@node01 ~]# docker node ls
//查看節點詳細信息(只能是manager身份才可查看)
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
mc3xn4az2r6set3al79nqss7x * node01 Ready Active Leader 18.09.0
olxd9qi9vs5dzes9iicl170ob node02 Ready Active 18.09.0
i1uee68sxt2puzd5dx3qnm9ck node03 Ready Active 18.09.0
//可以看出node01、node02、node03的狀態為Active
###################node02的操作如下###################
[root@node02 ~]# docker swarm leave
###################node03的操作如下###################
[root@node03 ~]# docker swarm leave
//node02、node03申請離開群集
###################node01的操作如下###################
[root@node01 ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
mc3xn4az2r6set3al79nqss7x * node01 Ready Active Leader 18.09.0
olxd9qi9vs5dzes9iicl170ob node02 Down Active 18.09.0
i1uee68sxt2puzd5dx3qnm9ck node03 Down Active 18.09.0
///可以看到node02、node03的狀態為Down
[root@node01 ~]# docker node rm node02
[root@node01 ~]# docker node rm node03
//node01將node02、node03移除群集
//如果worker節點沒有辭職,manager節點可以使用“-f”表示強制開出worker節點
以上命令可以將某一個節點加入、刪除群集。
[root@node01 ~]# docker swarm leave -f
//manager節點退出swamr群集環境,這就表示swarm群集解散
不過加入時是使用worker身份的,如果想要讓節點是以manager身份加入群集,需要使用以下命令:
[root@node01 ~]# docker swarm join-token manager
//查詢以manager身份加入群集的命令
[root@node01 ~]# docker swarm join-token worker
//查詢以worker身份加入群集的命令
如圖:
###################node02的操作如下###################
[root@node02 ~]# docker swarm join --token SWMTKN-1-2c0gcpxihwklx466296l5jp6od31pshm04q990n3ssncby3h0c-78rnxee2e990axj0q7td74zod 192.168.1.1:2377
###################node03的操作如下###################
[root@node03 ~]# docker swarm join --token SWMTKN-1-2c0gcpxihwklx466296l5jp6od31pshm04q990n3ssncby3h0c-78rnxee2e990axj0q7td74zod 192.168.1.1:2377
//node02、node03加入群集是以manager身份加入
###################node01的操作如下###################
[root@node01 ~]# docker node ls //查看節點的詳細信息
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
exr8uoww0eih53iujqz5cbv6q * node01 Ready Active Leader 18.09.0
r35f48huyw5hvnkuzatrftj1r node02 Ready Active Reachable 18.09.0
gsg1irl1bywgdsmfawi9rna7p node03 Ready Active Reachable 18.09.0
//從MANAGER STATUS這列就可看出
雖然加入群集時,可以指定使用manager、worker身份,但是也可以通過以下命令,進行降級、升級,操作如下:
[root@node01 ~]# docker node demote node02
[root@node01 ~]# docker node demote node03
//將node02、node03降級為worker
[root@node01 ~]# docker node promote node02
[root@node01 ~]# docker node promote node03
//將node02、node03升級為manager
//自行驗證
部署圖形化UI界面由node01來完成!
[root@node01 ~]# docker run -d -p 8080:8080 -e HOST=172.16.0.10 -e PORT=8080 -v /var/run/docker.sock:/var/run/docker.sock --name visualizer dockersamples/visualizer
//-e HOST指定的是容器
使用瀏覽器訪問:
瀏覽器可以正常訪問,則表示圖形化UI界面部署完成!
node01發布一個任務,(必須在manager角色的主機上)運行六個容器,命令如下:
[root@node01 ~]# docker service create --replicas 6 --name web -p 80:80 nginx
// --replicas:副本數量;大概可以理解為一個副本就是一個容器
容器運行完成后,可以登錄web頁面進行查看,如圖:
注意:如果另外兩臺節點服務器上沒有相應的驚醒,則默認會從docker Hub上自動進行下載!
[root@node01 ~]# docker service ls //查看創建的service
ID NAME MODE REPLICAS IMAGE PORTS
nbfzxltrcbsk web replicated 6/6 nginx:latest *:80->80/tcp
[root@node01 ~]# docker service ps web //查看創建的service都運行在那些容器上
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
v7pmu1waa2ua web.1 nginx:latest node01 Running Running 6 minutes ago
l112ggmp7lxn web.2 nginx:latest node02 Running Running 5 minutes ago
prw6hyizltmx web.3 nginx:latest node03 Running Running 5 minutes ago
vg38mso99cm1 web.4 nginx:latest node01 Running Running 6 minutes ago
v1mb0mvtz55m web.5 nginx:latest node02 Running Running 5 minutes ago
80zq8f8252bj web.6 nginx:latest node03 Running Running 5 minutes ago
如果現在node02、node03發生宕機時,service并不會因為節點的當即而死掉,而是自動跑到正常的節點上。
模擬node02宕機,web頁面如下:
恢復node02,web頁面如下:
即使node02恢復正常,也不會將service分配給node02。
因此,可以得出一個結論:如果node發生故障,service會自動跑到可用的節點上;反之,如果node沒有發生故障,默認情況下,service不會輕易更改節點!
擴容:就是添加幾臺service;
收縮:就是減少幾臺service;
針對上述環境實現收縮、擴容;
[root@node01 ~]# docker service scale web=8
//原本有6個service,現在增加到8臺
web頁面如下:
關于service分配到那臺node節點上,是根據docker swarm自身的算法進行分配的。
[root@node01 ~]# docker service scale web=4
//原本有8個service,現在減少到4臺
web頁面如下:
上述環境中,三臺都是manager,即使是一臺manager、兩臺worker默認情況manager也是進行工作的,將node02、node03降級為worker,執行如下命令:
[root@node01 ~]# docker node demote node02
[root@node01 ~]# docker node demote node03
如圖:
可以通過設置,使某臺節點不運行service,如下:
[root@node01 ~]# docker node update --availability drain node01
//設置noder01以后不運行容器,但已經運行的容器并不會停止
// --availability:選項后面共有三個選項可配置,如下:
active:工作;pause:暫時不工作;drain:永久性的不工作
web頁面如下:
[root@node01 ~]# docker node update --availability drain node02
//node02也不參加工作,但已經運行的容器并不會停止
如圖:
由此可以得出:不是只有manager才有不工作的權力!
docker swarm集群會產生兩種不同類型的流量:
在swarm中有三個重要的概念:
- overlay networks:管理swarm中Docker守護進程間的通信。你可以將服務附加到一個或多個已存在的overlay網絡上,使得服務與服務之間能夠通信;
- ingress network:是一個特殊的overlay網絡,用于服務節點間的負載均衡。當然任何swarm節點在發布的端口上接收到請求后,將請求交給一個名為IPVS的模塊。IPVS跟蹤參與該服務的所有IP地址,選擇其中的一個,并通過ingress網絡將請求到它;
- docker_gwbridge:是一種橋接網絡,將overlay網絡(包括ingress網絡)連接到一個單獨的Docker守護進程的物理網絡。默認情況下,服務正在運行的每個容器都連接到本地Docker守護進程主機的docker_gwbridge網絡;
docker_gwbridge網絡在初始化Swarm或加入Swarm時自動創建。大多數情況下,用戶不需要自定義配置,但是Docker允許自定義;
查看node01上默認的網絡,如圖:
注意:圖中的SCOPE,注意其作用范圍!
除了Swarm群集默認創建的兩個網絡以外,我們還可以自定義創建overlay網絡,連接到此網絡的容器,即可互相通信,,但是需要注意,自定義的網絡只能是創建的manager主機才可查看到!
創建自定義overlay網絡
[root@node01 ~]# docker network create -d overlay --subnet 200.0.0.0/24 --gateway 200.0.0.1 --attachable my_net
//Docker swarm群集創建overlay網絡時,必須使用--attachable選項來指定名稱,否則其他節點的容器運行時無法使用此網絡
創建自定義的overlay網絡時,必須是manager才可以創建,并且只在manager節點上才顯示的,別的worker節點是查看不到的,但是可以使用。
如下:
[root@node02 ~]# docker run -itd --name test01 --ip 200.0.0.10 --network my_net busybox
//node02使用剛才自定義的overlay網絡創建容器
[root@node03 ~]# docker run -itd --name test02 --network my_net --ip 200.0.0.20 busybox
//node03使用自定義的overlay網絡創建容器
測試訪問:
這是node02、node03已經使用過這個自定義的網絡了,這是在node02、node03上就可以查看到了!
而且基于docker swarm創建的overlay網絡也符合自定義跨主機網絡的特點,可以使用主機名進行通信。
通過搭建registry私有倉庫,可以便于讓其他node下載鏡像。搭建私有倉庫可以參考Docker搭建私有倉庫
[root@node01 ~]# docker run -itd --name registry -p 5000:5000 -v /registry:/var/lib/registry --restart=always registry:2
[root@node01 ~]# vim /usr/lib/systemd/system/docker.service
//更改內容為
ExecStart=/usr/bin/dockerd --insecure-registry 192.168.1.1:5000
[root@node01 ~]# systemctl daemon-reload
[root@node01 ~]# systemctl restart docker
[root@node01 ~]# docker ps -a -q | xargs docker start
//由于剛才創建的容器并沒有設置自動啟動,所以在重啟docker服務的時候,需要手動啟動
[root@node01 ~]# ssh-keygen -t rsa
[root@node01 ~]# ssh-copy-id root@node02
[root@node01 ~]# ssh-copy-id root@node03
//設置免密登錄
[root@node01 ~]# scp /usr/lib/systemd/system/docker.service root@node02:/usr/lib/systemd/system/docker.service
[root@node01 ~]# scp /usr/lib/systemd/system/docker.service root@node03:/usr/lib/systemd/system/docker.service
//將docker的配置文件復制到node02、node03上,因為docker的配置文件都是一樣的內容
[root@node02 ~]# systemctl daemon-reload
[root@node02 ~]# systemctl restart docker
[root@node03 ~]# systemctl daemon-reload
[root@node03 ~]# systemctl restart docker
//重新啟動node02、node03節點的docker服務
[root@node01 ~]# docker pull httpd
[root@node01 ~]# docker tag httpd:latest 192.168.1.1:5000/httpd:latest
[root@node01 ~]# docker push 192.168.1.1:5000/httpd:latest
//將httpd鏡像上傳到私有倉庫中
[root@node01 ~]# mkdir version{1,2,3,}
[root@node01 ~]# cd version1
[root@node01 version1]# echo "version1" >> index.html
[root@node01 version1]# echo -e "FROM httpd:latest\nADD index.html /usr/local/apache2/htdocs/index.html" > Dockerfile
[root@node01 version1]# docker build -t 192.168.1.1:5000/httpd:v1 .
//version1目錄下模擬生成版本v1
[root@node01 version1]# cp Dockerfile ../version2
[root@node01 version1]# cd !$
cd ../version2
[root@node01 version2]# echo "version2" >> index.html
[root@node01 version2]# docker build -t 192.168.1.1:5000/httpd:v2 .
//vesion2目錄下模擬生成版本v2
[root@node01 version2]# cp Dockerfile ../version3
[root@node01 version2]# cd !$
cd ../version3
[root@node01 version3]# echo "version3" >> index.html
[root@node01 version3]# docker build -t 192.168.1.1:5000/httpd:v3 .
//vesion3目錄下模擬生成版本v3
//注意在主頁面做一些區分
[root@node01 ~]# docker push 192.168.1.1:5000/httpd:v1
[root@node01 ~]# docker push 192.168.1.1:5000/httpd:v2
[root@node01 ~]# docker push 192.168.1.1:5000/httpd:v3
//將生成的鏡像上傳到私有倉庫
[root@node01 ~]# docker service create --replicas 3 --name httpd 192.168.1.1:5000/httpd:v1
//基于192.168.1.1:5000/httpd:v1創建三個service副本
瀏覽器訪問測試:
三個service副本是輪詢的方式來服務的,根據node02、node03的首頁內容進行測試!
node02:
[root@node02 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b6c1d88fcadf 192.168.1.1:5000/httpd:v1 "httpd-foreground" 4 minutes ago Up 4 minutes 80/tcp httpd.1.qubzhexjprpt7s89ku91mlle0
[root@node02 ~]# docker exec -it b6c1d88fcadf /bin/bash
root@b6c1d88fcadf:/usr/local/apache2# echo "node02" >> htdocs/index.html
node03
[root@node03 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ee19c342188c 192.168.1.1:5000/httpd:v1 "httpd-foreground" 5 minutes ago Up 5 minutes 80/tcp httpd.3.9ru7zsokixz29iw99qbdp15gn
[root@node03 ~]# docker exec -it ee19c342188c /bin/bash
root@ee19c342188c:/usr/local/apache2# echo "node03" >> htdocs/index.html
訪問測試:
[root@node01 ~]# curl 127.0.0.1
version1
node03
[root@node01 ~]# curl 127.0.0.1
version1
[root@node01 ~]# curl 127.0.0.1
version1
node02
//效果已經實現
[root@node01 ~]# docker service update --image 192.168.1.1:5000/httpd:v2 httpd
//更新容器的鏡像為版本2
瀏覽器進行測試:
默認情況下,swarm一次只更新一個副本,并且兩個副本之間并沒有等待時間,可以通過以上方法進行設置。
[root@node01 ~]# docker service update --replicas 6 --image 192.168.1.1:5000/httpd:v3 --update-parallelism 2 --update-delay 1m httpd
//--update-parallelism:設置更新的副本數量;
//--update-delay:更新的間隔時間
// --replicas 6:并在升級的過程中另外再創建3個副本
從更新的過程中可以看出效果!
瀏覽器確認版本更新成功:
[root@node01 ~]# docker service rollback httpd
//回滾為上一個版本
瀏覽器訪問測試:
注意:當我們執行回滾操作的時候,默認是回滾到上一次操作的版本,并且不可以連續回滾。
[root@node02 ~]# docker swarm leave
//那個節點想退出swarm群集,就在那臺節點上執行這條命令
//節點自動退出swarm群集(相當于辭職)
[root@node01 ~]# docker node rm 節點名稱
//由manager主動刪除節點(相當于開除)
[root@node01 ~]# docker node promote 節點名稱
//將節點升級
[root@node01 ~]# docker node demote 節點名稱
//將節點降級
[root@node01 ~]# docker node ls
//查看swarm群集的信息(只可以在manager角色的主機上查看)
[root@node01 ~]# docker node update --availability drain 節點名稱
//調整節點不參加工作
[root@node01 ~]# docker swarm join-token worker
//查看加入swarm群集的令牌(可以是worker也可以是manager)
[root@node01 ~]# docker service scale web=4
//擴容、收縮swarn群集servie的數量(取決與群集原本的數量)
//比原本群集數量多,就是擴容,反之、收縮
[root@node01 ~]# docker service ls
//查看創建的service
[root@node01 ~]# docker service ps service的名稱
//查看創建的service運行在那些容器上
[root@node01 ~]# docker service create --replicas 6 --name web -p 80:80 nginx
//指定運行的service副本數量
[root@node01 ~]# docker service create --replicas 3 --constraint node.hostname==node03 --name test nginx
//指定node節點,創建名為test的容器
[root@node01 ~]# docker node update --label-add mem=max node02
//以鍵值對的方式給docker02主機打上標簽“mem=max”,等號兩邊的內容是可以自定義的
[root@node01 ~]# docker service create --name test1 --replicas 3 --constraint 'node.labels.mem==max' nginx
//基于nginx鏡像在標簽為“mem==max”的主機上運行3個名為test1的服務
[root@node01 ~]# docker node inspect node02
//標簽相關的信息,在Spec{ }中有顯示
- 參與群集的主機名一定不能沖突,并且可以互相解析對方的主機名;
- 集群內的所有節點可以都是manager角色,但是不可以都是worker角色;
- 當指定運行的鏡像時,如果群集中的節點本地沒有該鏡像,那么它將會自動下載對應的鏡像;
- 當群集正常工作時,若一個運行著容器的docker服務器發生宕機,那么,其所運行的所有容器,都將轉移到其他正常運行的節點之上,而且,就算發生宕機的服務器恢復正常運行,也不會再接管之前運行的容器;
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。