1. 程式人生 > >docker swarm學習筆記

docker swarm學習筆記

最近學習容器和叢集,別人推薦XXXXXXX,我說我在看官方的swarm,都說不推薦。不推薦是一回事,官方能搞出來並沒把他刪掉,證明肯定有使用場景。所以學習一下,學到哪記到哪,當中也有百度裡找的資料,我相信我這篇是集各百度之所長,一些無實際用的也就不寫出來的。

環境是centos7.5 ,docker是yum安裝的1.13

##開啟轉發功能

vi /etc/sysctl.conf
net.ipv4.ip_forward=1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-arptables = 1
sysctl -p

#安裝1.13docker服務

yum remove -y docker*

sudo yum install -y yum-utils device-mapper-persistent-data lvm2

sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

sudo yum install docker -y

修改/etc/sysconfig/docker檔案
# 將--selinux-enabled設定為false,不然可能會由於selinux服務不能用導致docker啟動失敗

OPTIONS='--selinux-enabled=false --log-driver=json-file --signature-verification=false'

##修改docker儲存目錄(預設var/lib/docker不合適正式環境#
#通過disable enable 檢視docker配置檔案
[[email protected] _data]# systemctl disable docker
Removed symlink /etc/systemd/system/multi-user.target.wants/docker.service.
[[email protected]

_data]# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.

##修改/usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd-current \
-g /data/docker \ ##更換路徑
--add-runtime docker-runc=/usr/libexec/docker/docker-runc-current \
--default-runtime=docker-runc \

##過載配置
systemctl daemon-reload
##重啟服務 ##修改後原有資訊不會保留已經跑的業務注意遷移
systemctl restart docker

systemctl enable docker && systemctl start docker

 

建議先修改獨立唯一的主機名

# 在A機器建立叢集
docker swarm init --advertise-addr 本機內網IP

#在A機器
docker swarm join-token (manager|worker) 輸出 以什麼身份的加入叢集的token值

#在B機器輸入
docker swarm join --token SWMTKN-1-2ftsa277uecm0edb238e9a84h34ifarknitkn9yrqzn1wnafdb-71xjwcjhpzubgqts0ou73h3m9 192.168.0.140:2377
加入A機器的叢集

###刪除叢集
docker swarm leave --force

 

docker node --help (節點相關
docker service --help(容器相關

 

docker service rm NAME (此命令刪除執行中容器無需確認,謹慎使用

#檢視指定節點上執行的service
docker node ps docker123

#把名為nginxtest的nginx容器建立到hostname為docker123的node上。(constraint 引數可以指定多個不同的hostname的節點)
docker service create --replicas 1 --constraint node.hostname==docker123 --name nginxtest nginx

#在叢集中建立4個副本 名為test123的 alpine 容器,並執行引數ping docker.com
docker service create --replicas 4 --name test123 alpine ping docker.com

#給node ID為“hbex1b6iw7wfjsushdbot9gfs ” 新增nginx標籤 (ID引數也可使用hostname)
docker node update --label-add func=nginx hbex1b6iw7wfjsushdbot9gfs

#把nginx容器建立到帶nginx標籤的node上。
docker service create --name my_testnginx --constraint 'node.labels.func == nginx' nginx

#檢視節點標籤
docker node inspect hostname

#刪除標籤
docker node update --label-rm func hostname

#把docker123節點排除掉 並停用該節點上所有容器,將這些容器移動到別的可用節點上
docker node update --availability drain docker123

#把docker123節點排除掉不再分配任務,但允許已執行的容器繼續執行。
docker node update --availability pause

#恢復為可用狀態 允許任務被分配到該節點上
docker node update --availability Active docker123

# 減少服務副本,增加服務副本
docker service scale SERVICE=副本數量

##docker swarm無法常規重啟單個副本容器(副本容器通過docker ps也可以檢視到,也可以用docker restart ID的方式重啟,但是一旦操作該副本會轉移到其他可用節點上,並且本機器會不停嘗試啟動該副本,不建議操作)

##在學習這塊的時候因為沒有接觸過叢集,百度的時候一直搜尋重啟叢集容器,然而在swarm的環境中沒有“重啟”這個名詞,官方文件解釋的也極其簡單,作為一個傻瓜式的教程(不,可能傻瓜的是我。。)還是在此說明,swarm叢集只有“更新”的概念,update就是重啟。修改完容器內的配置後,可以使用以下命令更新。

#強制更新,一次更新1個副本,每隔30秒更新下一個副本 更新服務myweb

docker service update --force --update-parallelism 1 --update-delay 30s myweb

 

###不採用掛載目錄的情況下如何把檔案拷入容器

#顯示test123服務的全部ID
docker service ps test123 -q
#顯示該服務的資訊
docker service ps test123
#找到對應副本的對應ID
docker ps檢視本機docker id,再用 docer cp 本機目錄 容器ID:容器目錄 的方式把包放到叢集的容器裡

在使用docker的過程中發現基於swarm使用Storage Driver: overlay的方式進行儲存.但是發現這個特別佔用儲存空間.
清理所有停止的容器
docker container prune

清理所有不用資料(停止的容器,不使用的volume,不使用的networks,懸掛的映象)
docker system prune -a

# type=volume,將容器目錄對映到卷儲存上。docker volume create創建出的卷,可用在此處。
#如果拷貝war檔案到該卷後 再重啟某節點docker服務 該節點容器恢復後 使用的卷新增的檔案不會被刪除。
#以下面為例,4個副本,2個副本在A節點,A節點如果進入某個容器的shell環境刪除了 該卷下的一個tomcat自帶檔案,則兩個容器裡的相應檔案都會被刪除,且重啟docker服務後該檔案不會生成。
##換言之 用了掛載卷後,相當於對應容器的副本 共用同一個卷,且資料全部存在本地磁碟上 而非容器裡,可以理解為容器裡的該目錄只是磁碟的一個映像。
docker service create --mount src=tomcatdata,dst=/usr/local/tomcat/ --name myweb --publish 80:8080 --replicas 4 tomcat
#tomcatdata卷會自動建立
#可以使用docker volume inspect tomcatdata 檢視卷資訊

 

#實測,起了4個副本,分佈3個節點,有一個節點是2個副本的,然後請求了4次, 的確是每個副本收到一次訪問,兩個副本因為掛載的目錄相同 所以日誌寫入在同一個檔案裡了。
#牛逼的是 #我nginx反向代理是反向到3個節點的81埠,理論上是負載均衡到3個節點的docker對外埠,如果docker叢集只是往副本做負載均衡,那麼B節點應該不會知道A節點是否訪問,可能造成AB兩個節點同時轉發到同一個副本上導致容器負載不均衡。。
#而docker叢集應該是做了處理,不管請求是轉發到哪個節點的容器對外埠,轉發到後端副本容器的請求 都被負載均衡了。

 

 

以副本模式的方式起容器,則在一個節點上會存有映象,在我刪除myweb服務後,去三個節點執行
docker system prune -a
命令,會發現只有一個節點刪除了400多M的資料,其他的資料都只有幾M甚至更少,推測是有一個節點儲存映象,其他節點副本都是通過這個映象起的,之前測過如果存映象的節點宕機,發生漂移,會在漂移的目標端下拉新的映象,在最後清理時會有2個節點有400M的資料被清理,而映象節點宕機時也不會影響在跑節點。

 

最後是不同型別的節點重啟影響範圍:

worker節點重啟docker服務時,本節點容器重啟,不會影響其他節點。
manager節點重啟docker服務時,本節點容器重啟,也不會影響其他節點。
manager節點(Leader)重啟docker服務時,會造成Leader轉移到其他manager節點,本節點容器重啟,不會影響其他節點。

 

 

線上環境我覺得如果規模不是那種巨型量級的話是可以考慮使用swarm叢集的,以掛載卷的方式啟動容器,然後用rsync同步所有tomcat的目錄(排除日誌目錄)。

目前尚待驗證的幾個問題:

1.如果我節點出現異常,容器漂移後 等節點恢復 如何把容器重新平均分佈(用減少副本和增加副本的方法試過,不過感覺應該有更好的方法)

2.假設上面的例子 其中的2副本節點宕機的情況下 兩個副本是否會轉移到同一個節點上,如果轉移到同一個節點,那麼一個節點有3個副本,到時候會否導致一個節點承載了75%的量,另一個只有25%。

如有人知道以上問題的還請幫助解答下,謝謝。