在 Docker Swarm 中管理服務時,資源組態與排程策略至關重要。理解如何限制 CPU 和記憶體等資源,以及分散式排程如何運作,才能確保服務穩定可靠。本文將探討如何在 Swarm 中有效地組態資源,並觀察分散式排程如何影響服務副本的佈署。透過實際操作範例和程式碼解析,讀者將更清楚資源管理和排程策略的應用。
組態資源
在 Docker Swarm 中,資源管理是確保服務正常執行的關鍵因素之一。資源包括 CPU、記憶體等,正確組態這些資源對於服務的穩定性和效能至關重要。
資源使用與節點容量
資源使用不能超過節點容量。在一個由三個節點(一個管理節點和兩個工作節點)組成的 Swarm 中,每個節點的容量為 1GB 記憶體和 1 CPU。
首先,移除已經執行的 mysql 服務,並建立一個具有三個副本的 mysql 服務,該服務請求 4GB 的記憶體。
~ $ docker service rm mysql
mysql
~ $ docker service create \
> --env MYSQL_ROOT_PASSWORD='mysql' \
> --replicas 3 \
> --name mysql \
> --reserve-memory=4GB \
> mysql
cgrihwij2znn4jkfe6hswxgr7
內容解密:
docker service rm mysql:移除名為 mysql 的服務。docker service create:建立一個新的服務。--env MYSQL_ROOT_PASSWORD='mysql':設定環境變數 MYSQL_ROOT_PASSWORD 為 ‘mysql’。--replicas 3:指定服務的副本數為 3。--name mysql:將服務命名為 mysql。--reserve-memory=4GB:為每個服務副本保留 4GB 的記憶體。 由於請求的記憶體(4GB)超過了單個節點的容量(1GB),因此沒有任何服務副本被排程。
擴充套件服務
如果之前執行的服務的所有副本被擴充套件,某些或全部副本可能會被取消排程。這種情況發生在執行新副本所需的資源超過了可用節點容量時。
移除 mysql 服務並建立一個新的 mysql 服務,其資源設定在節點的供應範圍內。
~ $ docker service create \
> --env MYSQL_ROOT_PASSWORD='mysql' \
> --replicas 1 \
> --name mysql \
> --reserve-cpu .5 --reserve-memory 512mb \
> mysql
ysef8n02mhuwa7sxerc9jwjqx
內容解密:
--reserve-cpu .5:為每個服務副本保留 0.5 個 CPU。--reserve-memory 512mb:為每個服務副本保留 512MB 的記憶體。
服務被建立,並且單個副本正在執行。
逐步擴充套件服務
將 mysql 服務擴充套件到三個副本。
~ $ docker service scale mysql=3
mysql scaled to 3
內容解密:
docker service scale mysql=3:將 mysql 服務的副本數擴充套件到 3。
所有三個副本都成功執行,每個節點上執行一個副本。
進一步將 mysql 服務擴充套件到 10 個副本。
~ $ docker service scale mysql=10
mysql scaled to 10
內容解密:
- 部分副本由於資源不足而無法被排程,狀態為 Pending。
增加工作節點
為了使所有副本執行,可以透過增加工作節點來擴充套件 CloudFormation 堆積疊。
選擇 Docker 堆積疊並選擇 Actions ➤ Update Stack,在 Specify Details 中將 Number of Swarm Worker Nodes? 增加到 10。
此圖示說明瞭更新 CloudFormation 堆積疊的流程:
內容解密:
- 圖表展示瞭如何透過更新 CloudFormation 堆積疊來增加工作節點,從而提供更多的資源以執行更多的服務副本。
第8章:排程
在第2章中,我們介紹了Docker Swarm。在第4章中,我們討論了Docker Swarm服務。服務由零個或多個服務任務(副本)組成,這些任務會被排程到Swarm中的節點上。服務的期望狀態包括必須執行的任務數量。排程被定義為將需要執行的服務任務放置在Swarm中的節點上,以保持服務的期望狀態,如圖8-1所示。服務任務只能被排程在工作節點上。管理節點預設也是工作節點。
問題
如果沒有排程策略,服務任務可能會被排程到Swarm中的部分節點上。例如,服務中的所有三個任務可能會被排程到Swarm中的同一個節點上,如圖8-2所示。
不使用排程策略可能會導致以下問題:
- Swarm中的資源未被充分利用:如果所有任務都被排程到單一節點或部分節點上,其他節點的資源容量就無法被利用。
- 資源利用不均衡:如果所有任務都被排程到單一節點或部分節點上,這些節點上的資源就會被過度利用,任務甚至可能會耗盡所有資源容量,從而無法擴充套件副本。
- 缺乏區域性:客戶端根據節點位置存取服務的任務。如果所有服務任務都被排程到單一節點上,那麼在其他節點上存取服務的外部客戶端就無法在本機存取服務,從而導致存取相對遠端任務時的網路開銷。
- 單點故障:如果所有服務都在一個節點上執行,而該節點出現問題,就會導致停機。增加跨節點的冗餘可以避免這個問題。
解決方案
為了克服前一節中討論的問題,Docker Swarm中的服務任務排程是根據內建的排程策略。Docker Swarm模式使用分散排程策略來對節點進行排序,以放置服務任務(副本)。每次排程任務時都會計算節點排序,並將任務排程到排序最高的可用節點上。
Docker Swarm 服務排程範例
# 建立一個具有3個副本的服務
docker service create --replicas 3 --name mysql mysql:latest
內容解密:
此命令建立了一個名為 mysql 的服務,並指定了3個副本,使用 mysql:latest 映象。此範例展示瞭如何使用 Docker Swarm 佈署具有多個副本的服務。
# 檢視服務狀態
docker service ls
內容解密:
此命令列出了所有服務及其目前狀態,包括副本數量和使用的映象。此範例展示瞭如何檢查服務的目前狀態。
# 檢視服務任務狀態
docker service ps mysql
內容解密:
此命令列出了 mysql 服務的所有任務及其目前狀態,包括執行的節點和狀態資訊。此範例展示瞭如何檢查特定服務的任務狀態。
Docker Swarm 服務排程
此圖示展示了Docker Swarm的基本架構,以及服務任務如何被排程到工作節點上。
Docker Swarm 排程策略詳解
Docker Swarm 是一種容器協調工具,用於管理和協調多個 Docker 容器。在 Swarm 中,排程策略決定了容器如何在叢集中的不同節點上分配。本章將探討 Docker Swarm 的預設排程策略——分散排程(Spread Scheduling)。
分散排程策略原理
分散排程策略根據節點的可用資源(如 CPU 和 RAM)以及當前執行的容器數量來計算節點的排名。該策略優先選擇資源利用率較低且容器數量較少的節點,以實作任務在叢集中的均勻分佈。
分散排程的工作流程
- 初始狀態:假設有三個節點,每個節點具有相同的資源容量(例如 3GB RAM 和 3 CPUs),且沒有執行任何容器。
- 建立 MySQL 服務:建立一個 MySQL 服務,設定副本數量為 1,並指定所需的資源(例如 1GB RAM 和 1 CPU)。由於所有節點具有相同的資源可用性和容器數量,新任務將隨機分配到其中一個節點。
- 擴充套件 MySQL 服務:將 MySQL 服務的副本數量擴充套件到 3。此時,新的兩個任務將被排程到其他兩個節點,以實作任務的分散。
- 進一步擴充套件:繼續將 MySQL 服務的副本數量擴充套件到 5。由於所有節點的資源可用性和容器數量趨於一致,新的任務將隨機分配到兩個節點上。
環境設定與驗證
為了驗證分散排程策略的實際效果,我們需要設定一個包含一個管理節點和兩個工作節點的 Docker Swarm 叢集。
建立 CloudFormation Stack:使用 Docker for AWS 建立一個包含三個 EC2 例項的 CloudFormation Stack,分別作為 Swarm 的管理節點和工作節點。
#### CloudFormation Stack 組態 - 管理節點:1 個 - 工作節點:2 個SSH 登入管理節點:使用 SSH 登入到 Swarm 管理節點,並列出叢集中的所有節點。
~ $ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 0waa5g3b6j641xtwsygvjvwc1 ip-172-31-0-147.ec2.internal Ready Active e7vigin0luuo1kynjnl33v9pa ip-172-31-29-67.ec2.internal Ready Active ptm7e0p346zwypos7wnpcm72d * ip-172-31-25-121.ec2.internal Ready Active Leader
建立與排程 MySQL 服務
建立 MySQL 服務:使用
docker service create命令建立一個具有 5 個副本的 MySQL 服務。~ $ docker service create \ --env MYSQL_ROOT_PASSWORD='mysql' \ --replicas 5 \ --name mysql \ mysql驗證服務狀態:使用
docker service ls和docker service ps mysql命令檢查 MySQL 服務的狀態和任務分佈。~ $ docker service ls ID NAME MODE REPLICAS IMAGE PORTS 1onpemnoz4x1 mysql replicated 5/5 mysql:latest ~ $ docker service ps mysql ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS fwjbu3gt2zn0 mysql.1 mysql:latest ip-172-31-0-147.ec2.internal Running Preparing 8 seconds ago w0521ik1awjf mysql.2 mysql:latest ip-172-31-29-67.ec2.internal Running Preparing 8 seconds ago z9wn2nrzfzt8 mysql.3 mysql:latest ip-172-31-0-147.ec2.internal Running Preparing 8 seconds ago tm8jbque3xbb mysql.4 mysql:latest ip-172-31-25-121.ec2.internal Running Preparing 8 seconds ago 7drxfy3vbmp5 mysql.5 mysql:latest ip-172-31-29-67.ec2.internal Running Preparing 8 seconds ago
本章重點回顧
- 分散排程策略的基本原理和工作流程
- 如何在 Docker Swarm 中建立和管理服務
- 分散排程策略在實際環境中的應用和效果
後續章節預覽
本文後續章節將繼續探討 Docker Swarm 的其他排程策略和功能,包括全域性服務、資源限制、以及如何根據實際需求最佳化叢集組態等內容。敬請期待!
Docker Swarm 排程策略詳解
Docker Swarm 是一種容器協調工具,能夠自動化容器的佈署、擴充套件和管理。其中,排程策略是 Swarm 的核心功能之一,負責將服務的副本分配到叢集中的不同節點上。
擴充套件服務與排程
當我們建立一個服務並將其擴充套件到多個副本時,Swarm 會根據排程策略將這些副本分配到叢集中的不同節點上。例如,將 mysql 服務擴充套件到 6 個副本:
docker service scale mysql=6
執行後,Swarm 會將 6 個副本平均分配到叢集中的 3 個節點上,每個節點執行 2 個容器:
docker service ps mysql
輸出結果如下:
| ID | NAME | IMAGE | NODE | DESIRED STATE | CURRENT STATE | ERROR | PORTS |
|---|---|---|---|---|---|---|---|
| fwjbu3gt2zn0 | mysql.1 | mysql:latest | ip-172-31-0-147.ec2.internal | Running | Running 13 seconds ago | ||
| w0521ik1awjf | mysql.2 | mysql:latest | ip-172-31-29-67.ec2.internal | Running | Running 12 seconds ago | ||
| z9wn2nrzfzt8 | mysql.3 | mysql:latest | ip-172-31-0-147.ec2.internal | Running | Running 13 seconds ago | ||
| tm8jbque3xbb | mysql.4 | mysql:latest | ip-172-31-25-121.ec2.internal | Running | Running 8 seconds ago | ||
| 7drxfy3vbmp5 | mysql.5 | mysql:latest | ip-172-31-29-67.ec2.internal | Running | Running 12 seconds ago | ||
| utjo8lwbtzf7 | mysql.6 | mysql:latest | ip-172-31-25-121.ec2.internal | Running | Running 5 seconds ago |
程式碼解析:
docker service scale mysql=6
docker service ps mysql
內容解密:
docker service scale mysql=6:將mysql服務擴充套件到 6 個副本。docker service ps mysql:列出mysql服務的任務(副本)狀態。
期望狀態調節
Swarm 的另一個重要功能是期望狀態調節(Desired State Reconciliation)。當服務的期望狀態與當前狀態不一致時,Swarm 會自動進行調節,以使當前狀態符合期望狀態。
例如,當某個節點離開叢集時,Swarm 會在其他節點上啟動新的副本,以保持服務的可用性:
docker service ps mysql
輸出結果如下:
| ID | NAME | IMAGE | NODE | DESIRED STATE | CURRENT STATE | ERROR | PORTS |
|---|---|---|---|---|---|---|---|
| p14bbk7ij1mt | mysql.1 | mysql:latest | ip-172-31-29-67.ec2.internal | Running | Running 5 minutes ago | ||
| w0521ik1awjf | mysql.2 | mysql:latest | ip-172-31-29-67.ec2.internal | Running | Running 7 minutes ago | ||
| uatsaay7axlc | mysql.3 | mysql:latest | ip-172-31-25-121.ec2.internal | Running | Running about a minute ago | ||
| z9wn2nrzfzt8 _ | mysql.3 | mysql:latest | 0waa5g3b6j641xtwsygvjvwc1 | Shutdown | Running2 minutesago |
程式碼解析:
docker service ps mysql
內容解密:
docker service ps mysql:列出mysql服務的任務(副本)狀態。- Swarm 自動在其他節點上啟動新的副本,以保持服務的可用性。
圖表說明
下圖展示了更新 Docker for AWS CloudFormation stack 的過程:
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title Docker Swarm 資源組態與排程策略
package "Docker 架構" {
actor "開發者" as dev
package "Docker Engine" {
component [Docker Daemon] as daemon
component [Docker CLI] as cli
component [REST API] as api
}
package "容器運行時" {
component [containerd] as containerd
component [runc] as runc
}
package "儲存" {
database [Images] as images
database [Volumes] as volumes
database [Networks] as networks
}
cloud "Registry" as registry
}
dev --> cli : 命令操作
cli --> api : API 呼叫
api --> daemon : 處理請求
daemon --> containerd : 容器管理
containerd --> runc : 執行容器
daemon --> images : 映像檔管理
daemon --> registry : 拉取/推送
daemon --> volumes : 資料持久化
daemon --> networks : 網路配置
@enduml
此圖示說明瞭如何透過 AWS 管理控制檯更新 CloudFormation stack。