Docker Swarm 學習筆記總結
Docker Swarm 學習筆記總結
Swarm 介紹
Docker Swarm是Docker官方提供的叢集工具。它可以將一些關聯的Docker主機轉變成一個虛擬Docker主機。因為Docker Swarm符合Docker API的標準,任何已經可以與Docker守護程序通訊的工具都可以使用Swarm來透明地擴充套件到多個主機。支援工具包括:
- Dokku
- Docker Compose
- Docker Machine
- Jenkins
Swarm 架構
Swarm 是用來被用來管理 Docker 叢集的,所以單個 Docker host 是整個叢集的基礎。Swarm 自身可以有兩種安裝方式,一種是當成普通的 Docker 容器來安裝,一種是當成一個簡單的應用被安裝在一臺虛擬機器或者物理機上。它的架構圖如下:
所有的 Docker node 都會被當成一個排程候選物件。類似於 OpenStack 中的 compute node.
Swarm 叢集功能
Swarm 排程器
排程是叢集中十分重要的功能,Swarm目前支援三種排程策略:Spread、Binpack和random。 在執行swarm manage啟動管理服務時,可通過–strategy引數指定排程策略,預設是:spread。
三種排程策略的優缺點:
-
spread: 配置相同情況下,選擇一個正在執行的容器數量最少的那個節點,平攤容器到各個節點。
-
binpack:儘可能將所有容器放在一臺節點上執行,儘量少用節點,避免容器碎片化。
-
random: 直接隨機分配,不考慮叢集節點狀態,方便進行測試使用。
Swarm 過濾器
Swarm 過濾器(filter)可以實現特定的容器分配到特點的節點上。目前支援物種過濾器:Constraint、Affinity、Port、Dependency、Health。
-
Constraint 過濾器: 繫結到節點的鍵值對,相當於給節點打標籤。比如在啟動Docker服務時,指定某個節點顏色為 red。
-
Affinity 過濾器:允許使用者在啟動一個容器的時候,讓它分配到某個已有容器的節點上。
-
其他過濾器也類似,通過-e affinity:image==
選擇擁有指定映象的節點,通過-e affinity:lael_name==value來選擇擁有指定標籤的容器所允許的節點。
Swarm 服務發現
通過不同的路徑來選擇特定的服務發現後端機制:
- token://
: 使用Docker Hub提供的服務,適用於公網; - file://pah/to/file:使用本地檔案,需手動管理;
- consul://
/ :使用consul服務,私有環境; - etcd://
, , / :使用etcd服務,私有環境; - zk://
, , / :使用zk服務,私有環境; - [nodes://]
, , :手動指定叢集中節點地址,方便進行服務測試。
Swarm 叢集實戰
安裝Dcoker Swarm的方式
安裝Docker Swarm有兩種方式:
- 直接以swarm為映象模板啟動容器;
- 在系統中安裝swarm的二進位制可執行檔案。
官網也列舉出了這兩種方法的優缺點:
以swarm映象啟動容器:
- 無需在系統中安裝可執行的二進位制檔案;
- 用docker run命令每次都可以獲取並執行最近版本的映象;
- 容器是Swarm與主機環境相隔離,無需維護shell的路徑和環境。
在系統中安裝swarm:
- Swarm專案的開發者在測試程式碼變更的過程中,無需在執行該二進位制檔案前進行容器化(“containerizing”)操作。
叢集建立步驟
建立一個Swarm叢集的第一步是從網上拉取Docker Swarm映象。然後,你可以使用Docker配置Swarm manager和所有節點執行Docker Swarm。步驟:
- 在每個節點上開啟一個TCP埠用於跟Swarm manager通訊
- 在每個節點上安裝Docker
- 建立和管理TLS證書以保護叢集
叢集部署環境
Docker01 和 Docker02 分別對應 manager0 和 manager1; Docker04 和 Docker05 分別對應 node0 和 node1; Docker03 對應 consul0;
配置ssl證書及安裝docker服務
mkdir -p /etc/docker/certs.d/DomainName:Port cp ca.crt /etc/docker/certs.d/DomainName:Port/ service docker restart
建立Swarm叢集:
# 在高可用的Swarm叢集中建立主管理者 # 操作物件 manager0 和 consul0 # <manager0_ip> 和 <consul_ip>相同 docker run -d -p 4000:4000 swarm manage -H :4000 --replication --advertise <manager0_ip>:4000 consul://<consul_ip>:8500 # 操作物件 manager1 docker run -d -p 4000:4000 swarm manage -H :4000 --replication --advertise <manager1_ip>:4000 consul://172.30.0.161:8500 # 操作物件 node0 和 node1 docker run -d swarm join --advertise=<node_ip>:2375 consul://<consul_ip>:8500
叢集使用:
# 操作物件 manager0 和 consul0 docker -H :4000 info # 在Swarm叢集中執行應用 docker -H :4000 run hello-world # 查詢Swarm叢集的哪個節點在執行該應用 docker -H :4000 ps - 測試Swarm叢集的故障; # 獲取swarm容器的id或名稱 # 操作物件 manager0 docker ps # 刪除或關閉當前的主管理者 manager0 docker rm -f <id_name> # 建立或啟動Swarm叢集管理者 manager0 docker run -d -p 4000:4000 swarm manage -H :4000 --replication --advertise <manager0_ip>:4000 consul://<consul_ip>:8500 # 檢視該容器的日誌 sudo docker logs <id_name> # 獲取叢集管理者和節點的資訊 docker -H :4000 info
個人總結
Swarm 上的容器選擇
- 適合無狀態服務:web服務、反向代理、採集器等
- 不適合有狀態服務:資料庫、redis、zk等
設定Docker倉庫
- 指明Docker倉庫地址
- 私有倉庫增加引數:–with-registry-auth
- 使用tag進行版本上線及回滾
改造無狀態化應用容器
- 採用共享儲存掛載方式
日誌採集服務
集中式的日誌和指標是使用分散式檔案系統的必須項,如ELK,Graphana,Graylog 等等。
這裡有許多可選項,有開源專案,也有SaaS類服務。這些打造和整合成可靠的服務是複雜且艱難的。建議先使用雲端服務(如Loggly, Logentries), 當成本上漲的時候,再開始架設自己的日誌收集服務。 例:ELK 棧日誌處理配置:
docker service update \ --log-driver gelf \ --log-opt gelf-address=udp://monitoring.example.com:12201 \ --log-opt tag=example-tag \ example-service
建立可附加的網路
記得使用它,否則無法在Docker Swarm下一條命令跑起一個容器。這是Docker1.13+新功能。如果使用舊版本的Docker, 最好升級下。
程式碼:
docker network create --driver=overlay --attachable core
增加環境變數
如果建立Docker映象的時候,遵循了最佳實踐原則(https://rock-it.pl/how-to-writ … iles/),允許在執行的時候通過環境變數設定一切配置項,那麼把應用遷到Swarm的過程完全沒有問題。
例,有用的命令:
docker service create \ --env VAR=VALUE \ --env-file FILENAME \ ... docker service update \ --env-add VAR=NEW_VALUE \ --env-rm VAR \ ..
下一個級別就是使用非公開的API掛載檔案像掛載祕鑰那樣(Authorized keys, SSL certs 等)。作者暫時還未使用此功能,不能詳述,但這個功能特性絕對值得思考和使用。
設定適當例項和批量更新
保持適當數量的例項,以應對高流量和例項或者節點不可用的情況。同時太多的例項數也會佔用CPU和記憶體,並且導致爭搶CUP資源。
update-parallelism的預設值是1,預設只有一個例項在執行。但這個更新速度太慢了,建議是 replicas / 2。
相關命令:
docker service update \ --update-parallelism 10 \ webapp You can scale multiple services at once docker service scale redis=1 nginx=4 webapp=20 Check scaling status docker service ls Check details of a service (without stopped containers) docker service ps webapp | grep -v "Shutdown"
把Swarm配置儲存為程式碼
最好使用Docker Compose v3版本的語法(https://docs.docker.com/compos … eploy)。
他允許使用程式碼指定幾乎所有的服務選項。作者在開發的時候使用 Docker-compose.yml,在生產環境(swarm)配置使用 Docker-compose.prod.yml . 部署Docker-compose檔案中所描述的服務,需要Docker stack deploy 命令(屬於新版本 Stack命令集合中的一部分[https://docs.docker.com/engine … tack/])
Docker compose v3例子:
docker-compose.prod.yml version: '3' services: webapp: image: registry.example.com/webapp networks: - ingress deploy: replicas: ${WEBAPP_REPLICAS} mode: replicated restart_policy: condition: on-failure proxy: image: registry.example.com/webapp-nginx-proxy networks: - ingress ports: - 80:80 - 443:443 deploy: replicas: ${NGINX_REPLICAS} mode: replicated restart_policy: condition: on-failure networks: ingress: external: true
部署的例子(建立或者更新服務):
export NGINX_REPLICAS=2 WEBAPP_REPLICAS=5 docker login registry.example.com docker stack deploy \ -c docker-compose.prod.yml\ --with-registry-auth \ frontend
提示:Docker-compose檔案支援環境變數 (${VARIABLE}), 所以,可以動態調整配置作為測試等。
設定限制
就經驗而言,可以為所有服務設定CPU使用限制。當某一個容器應用佔用掉所有主機資源時,此限制可以避免這種情況發生。
當想把所有容器均勻地釋出在所有主機上或是想確保有足夠的資源來響應操作時,需使用Reserve-cpu這個引數。
例如:
docker service update --limit-cpu 0.25 --reserve-cpu 0.1 webapp
監控連線
曾經在Swarm網路上遇到過一些問題。很多次所有的流量都被路由到同一個容器例項上,而同時有9個容器例項正常且健康的。這種情況下——即流量持續導到一個例項上,做擴容或者縮容操作的時候,加上這個引數–endpoint-mode 。
參考文件
ofollow,noindex" target="_blank">https://www.ibm.com/developerworks/cn/cloud/library/1511_zhangyq_dockerswarm/index.html
http://dockone.io/article/1486
http://dockone.io/article/2318
https://rock-it.pl/my-experience-with-docker-swarm-when-you-need-it/
Docker技術入門於實戰~Swarm章節