在建構生產級 Docker 叢集時,穩定且高效的組態至關重要。本文建議採用 Ubuntu Server 16.04.3 LTS 與 Linux Kernel 4.4 LTS 的組合,搭配 Docker CE 17.06.2 或 17.09.1 版本,並使用 Overlay2 作為儲存驅動程式,以確保基礎環境的穩定性及與 Docker 的高度相容性。網路層面,建議捨棄 Docker 預設的 overlay 網路,改用 WeaveWorks 等效能更佳的網路外掛,搭配 Træfik 負載平衡器,實作服務請求的有效路由與管理。此外,整合 Envoy 作為 Sidecar Proxy,可實作分散式追蹤,提升服務監控與問題排查效率。文章也探討了在 AWS Spot 例項上佈署 Docker Swarm 叢集的策略,以及如何透過使用者資料指令碼自動化節點組態,有效降低營運成本。最後,文章以 Python 程式碼示例說明如何實作帶有指數退避的重試機制,提升服務的容錯能力與穩定性。
穩定化叢集組態
在建立Docker叢集時,首先需要謹慎地穩定化叢集組態。目前,Docker叢集的最佳組態如下:
作業系統與核心版本
- Ubuntu Server 16.04.3 LTS:雖然Red Hat Linux或CentOS可能更適合某些使用場景,但Ubuntu Server因其易用性和與Docker的良好相容性而被廣泛採用。Docker在Ubuntu Server上的測試最為充分。
- Linux Kernel 4.4 LTS:4.4核心是一個長期支援版本(LTS),非常適合Docker環境。雖然4.9核心也是一個不錯的選擇,但過於新的核心(如4.13)可能與Docker的相容性尚待驗證。
Docker儲存驅動程式
- Overlay2:對於執行在4.4+核心上的Docker,overlay2應該成為預設的儲存驅動程式。AUFS曾經是Docker的常用儲存驅動,但在新版本中,overlay2提供了更好的效能和穩定性。在CentOS或RHEL 7.4上,overlay2也是一個很好的選擇。
Docker版本
- Docker CE 17.06.2 或 17.09.1:這兩個版本都是穩定且適合生產環境的選擇。如果你有企業支援,Docker EE 17.06也是一個很好的選擇。
穩定的Docker Swarm堆積疊組態
graph LR
A[Ubuntu Server 16.04.3 LTS] --> B[Linux Kernel 4.4 LTS]
B --> C[Docker CE 17.06.2 或 17.09.1]
C --> D[Overlay2 儲存驅動]
D --> E[WeaveWorks 網路外掛]
E --> F[Træfik 負載平衡]
F --> G[Envoy 分散式追蹤]
圖表翻譯: 上圖展示了一個穩定的Docker Swarm叢集組態,包括作業系統、核心版本、Docker版本、儲存驅動程式、網路外掛以及負載平衡和分散式追蹤元件。
選擇適當的網路外掛
長久以來,Docker預設的overlay網路被認為不適合生產環境。儘管其品質不斷提升,但我們仍然可以考慮其他網路外掛以獲得最佳效能。例如,可以使用WeaveWorks或Contiv來替換預設的overlay驅動程式。本章節中,我們使用WeaveWorks網路外掛版本2。
為什麼選擇WeaveWorks?
WeaveWorks網路外掛使用了與Kubernetes CNI相同的底層網路實作,並且經過了開發團隊的嚴格測試,在生產叢集中的表現非常出色。為了避免當前overlay網路驅動程式中的斷線問題,建議完全移除根據預設overlay網路驅動程式的ingress網路。
新的Ingress和路由機制
由於我們將移除預設的Docker ingress網路,因此需要建立自己的路由機制。如圖7.2所示,我們將使用根據L7負載平衡器Træfik構建新的ingress層,以實作對叢集中服務的請求路由。
Træfik的優勢
- 自動解析服務為IP位址列表。
- 可以選擇使用Docker Swarm提供的根據IPVS的負載平衡器,或是Træfik內建的負載平衡機制。
- 支援根據主機名稱匹配服務,並將請求轉發到特定的服務任務。
- 可以在不影響執行中的服務的前提下,靈活地重新啟動或重新組態ingress層。
分散式追蹤元件
在本文提出的架構中,我們為每個佈署的函式使用Envoy作為Sidecar Proxy。Envoy允許函式之間的分散式追蹤呼叫,即使這些函式是由不同的FaaS平台準備或佈署的。這是避免供應商鎖定的重要一步。
Envoy作為Sidecar Proxy的兩種組態
-
直接嵌入EnvoyProxy到Docker映像檔中:這種方式效能最佳,因為EnvoyProxy透過容器內的迴環介面與函式程式通訊。但是,當需要更改Envoy的組態時,需要重新啟動EnvoyProxy和函式例項。
-
將EnvoyProxy作為Edge Proxy分離出來:這種方式在管理和靈活性方面更具優勢,但會引入EnvoyProxy和函式容器之間的網路開銷。
graph LR
A[函式例項] -->|迴環介面|> B[EnvoyProxy Sidecar]
A -->|HTTP請求|> C[外部服務]
subgraph 容器內部
A
B
end
subgraph 組態1
D[函式容器] -->|包含|> B
end
subgraph 組態2
E[EnvoyProxy Edge Proxy] -->|請求轉發|> F[函式容器]
end
圖表翻譯: 上圖展示了兩種使用Envoy作為Sidecar Proxy的組態,第一種是將EnvoyProxy直接嵌入函式容器,第二種是將EnvoyProxy作為Edge Proxy獨立出來。
重試和斷路器模式
在本文中,我們將討論重試和斷路器模式,這些模式對於解決服務鏈中的級聯故障至關重要。
重試機制
當服務鏈中的某個服務或函式不可用時,會導致整體可用性下降。例如,如果五個不同的函式或服務各有99%的可用性,那麼客戶端體驗到的整體可用性將降低到95.09%。為瞭解決這個問題,我們需要在發生錯誤(如HTTP 500)時重試呼叫另一個服務或函式例項。
然而,簡單的重試機制可能會增加對已經故障的服務的不必要負載,因此需要更為智慧的重試策略。
import random
import time
def retry_with_backoff(func, max_retries=3, backoff_factor=0.5):
retries = 0
while retries < max_retries:
try:
return func()
except Exception as e:
print(f"嘗試失敗:{e}")
retries += 1
time.sleep(backoff_factor * (2 ** retries))
raise Exception("達到最大重試次數")
# 示例用法:
def example_function():
if random.random() < 0.5: # 模擬50%失敗率
raise Exception("模擬錯誤")
return "成功"
result = retry_with_backoff(example_function)
print(result)
內容解密:
這段程式碼實作了一個帶有指數退避的重試機制。retry_with_backoff函式接受一個需要執行的函式func,並設定最大重試次數max_retries和退避因子backoff_factor。每次重試失敗後,等待時間會指數增加,以避免對故障服務造成額外負載。這種機制在分散式系統中非常有用,可以提高整體的可靠性和彈性。
本篇文章詳細討論瞭如何穩定化Docker叢集組態,包括選擇適當的作業系統、核心版本、Docker版本和儲存驅動程式。同時,我們還探討了使用WeaveWorks網路外掛和Træfik負載平衡器來最佳化叢集網路,以及如何使用Envoy實作分散式追蹤。此外,我們還深入討論了重試和斷路器模式對於提高系統可靠性的重要性,並提供了一個Python範例來說明如何實作帶有指數退避的重試機制。這些技術對於建立一個高效、可靠的生產級Docker叢集至關重要。
在AWS Spot例項上準備生產級Docker Swarm叢集以執行FaaS平台
使用Spot例項節省成本
當我們談論雲端運算時,其按需例項的價格其實已經相當便宜。然而,從長遠來看,使用雲端例項的成本最終會與購買實體機器相差無幾。為瞭解決這個定價問題,主要的雲端供應商,如Amazon EC2和Google Cloud Platform,提供了一種新的例項型別,在本文中統稱為Spot例項。
Spot例項的特點
Spot例項比按需例項便宜得多,但其缺點是生命週期短且可能被意外終止。也就是說,Spot例項可能在任何時候被終止。當它被終止時,我們可以選擇是否保留或完全丟棄其儲存卷。在AWS上,例項會在終止前約120秒透過遠端後設資料接收通知,而在Google Cloud上,則會在機器停止前30秒透過ACPI訊號傳送通知。兩者的比較如前圖所示。
在AWS上使用EC2 Spot例項
在Amazon EC2上,存取https://aws.amazon.com/ec2/spot/,我們會看到如下所示的頁面。登入AWS控制檯以設定Spot例項:
請求Spot例項的三種模式
- 一次性請求:這是一次性的請求,當例項被終止後,我們需要再次發起請求。
- 請求一組例項並讓AWS維護目標例項數量:當某些例項被終止時,AWS會盡力根據我們的最大競價分配例項,以滿足每個佇列的目標數量。本章中我們選擇了這種請求模式。
- 請求固定時間段的例項:固定時間段稱為Spot區塊,可以設定在1到6小時之間。設定較長時間段將需要支付更多費用。
準備Docker Swarm叢集
假設我們已經有三台機器被組態為管理節點。為了獲得最便宜的費率,建議使用三台按需EC2節點作為Docker管理節點,並使用N-3台Spot例項作為Docker工作節點。我們從三台Spot工作節點開始。
叢集初始化
首先,透過SSH登入我們希望作為第一個管理節點的機器,安裝Docker,並在其上執行docker swarm init命令。eth0是由雲端供應商提供的私有網路介面。在繼續之前,請使用ip addr命令檢查您的介面。如果您知道哪個介面是私有的,請使用以下命令初始化叢集:
$ docker swarm init --advertise-addr=eth0
接下來,透過SSH登入其他兩台節點,安裝Docker,並使用docker swarm join命令加入叢集。不要忘記使用管理節點的加入令牌,而不是工作節點的令牌。下面的例子中的令牌是管理節點令牌。請注意,在此設定過程中,我的第一個管理節點的IP是172.31.4.52,請將其替換為您的IP位址:
$ docker swarm join --token SWMTKN-1-5rvucdwofoam27qownciovd0sngpm31825r2wbdz1jdneiyfyt-b5bdh4i2jzev4aq4oid1pubi6 172.31.4.52:2377
對於這前三台節點,不要忘記將它們標記為管理節點,以便您記住。
#### 內容解密:
此步驟用於初始化Docker Swarm叢集並將節點加入叢集。
1. `docker swarm init --advertise-addr=eth0` 命令用於初始化Swarm叢集,並指定通告地址為eth0介面。
2. `docker swarm join` 命令用於將其他節點加入Swarm叢集,需要指定加入令牌和管理節點的地址。
3. 將節點標記為管理節點,以方便管理和識別。
驗證叢集狀態
請確保docker info命令顯示管理節點列表,包含所有私有的IP地址。我們使用grep -A3來檢視目標後的下三行:
$ docker info | grep -A3 "Manager Addresses:"
Manager Addresses:
172.31.0.153:2377
172.31.1.223:2377
172.31.4.52:2377
或者,如果您熟悉jq命令,可以嘗試以下操作:
$ docker info --format="{{json .Swarm.RemoteManagers}}" | jq -r .[].Addr
172.31.4.52:2377
172.31.1.223:2377
172.31.0.153:2377
docker info命令也接受--format引數,讓我們自定義輸出。在前面的例子中,我們使用了範本提供的JSON方法生成JSON輸出。然後,我們使用jq查詢所有Swarm管理節點的IP地址。JSON範本和jq的組合將成為建立我們自己的根據Docker的叢集操作指令碼的強大工具。
在Spot例項上組態工作節點
然後,我們將組態另外三台節點作為一組Spot例項。如以下截圖所示,它顯示了請求一組三台Spot例項的設定。選擇“請求並維護”選項,然後將目標容量設定為3台例項:
組態啟動指令碼
我們組態啟動指令碼以在例項建立時安裝Docker,將節點加入叢集,並設定網路驅動程式。啟動指令碼必須放在佇列設定的“使用者資料”部分,如以下截圖所示:
#### 內容解密:
此步驟用於在Spot例項上組態Docker工作節點。
1. 透過AWS控制檯請求一組Spot例項,並設定目標容量。
2. 在“使用者資料”部分組態啟動指令碼,以安裝Docker並將節點加入Swarm叢集。
3. 啟動指令碼還負責設定網路驅動程式,以確保叢集內的網路連線正常。
隨著雲端運算技術的不斷發展,使用Spot例項佈署FaaS平台將變得越來越普遍。透過結合Docker Swarm和Spot例項,我們可以實作既經濟又高效的FaaS解決方案。未來,我們可以期待更多的創新和最佳化,使這一領域繼續發展和成熟。
程式碼示例:自動化佈署指令碼
#!/bin/bash
# 安裝Docker
sudo apt-get update
sudo apt-get install -y docker.io
# 將節點加入Swarm叢集
sudo docker swarm join --token SWMTKN-1-5rvucdwofoam27qownciovd0sngpm31825r2wbdz1jdneiyfyt-b5bdh4i2jzev4aq4oid1pubi6 172.31.4.52:2377
# 組態網路驅動程式
sudo docker network create -d overlay my-network
#### 內容解密:
此指令碼用於自動化佈署Docker Swarm工作節點。
1. 首先,更新軟體包列表並安裝Docker。
2. 然後,將節點加入Swarm叢集,使用指定的加入令牌和管理節點地址。
3. 最後,建立一個overlay型別的網路,用於跨多個Docker主機的容器間通訊。
透過這種自動化佈署指令碼,我們可以簡化工作節點的組態過程,提高佈署效率。這對於大規模佈署FaaS平台尤其重要,因為它可以減少手動操作的錯誤和時間消耗。
總之,使用AWS Spot例項和Docker Swarm可以幫助我們以較低的成本佈署高效的FaaS平台。透過自動化佈署指令碼和仔細的規劃,我們可以進一步簡化佈署過程,提高系統的可靠性和可擴充套件性。這使得根據FaaS的應用開發和佈署變得更加靈活和經濟。
使用WeaveWorks網路外掛建立Docker Swarm網路
在建立Docker Swarm叢集時,網路組態是一個重要的環節。WeaveWorks提供了一個強大的網路外掛,能夠幫助我們建立一個跨主機的容器網路。本篇文章將介紹如何在Docker Swarm中使用WeaveWorks網路外掛。
安裝WeaveWorks網路外掛
在建立Docker Swarm叢集時,我們需要在每個節點上安裝WeaveWorks網路外掛。可以使用以下命令安裝:
docker plugin install --grant-all-permissions weaveworks/net-plugin:2.1.3
內容解密:
此命令會安裝WeaveWorks網路外掛的2.1.3版本。--grant-all-permissions引數用於自動授權外掛所需的許可權。
驗證WeaveWorks網路外掛安裝
安裝完成後,可以使用以下命令驗證外掛是否正確安裝:
docker plugin ls
輸出結果應該包含WeaveWorks網路外掛的資訊,例如:
ID NAME DESCRIPTION ENABLED
f85f0fca2af9 weaveworks/net-plugin:2.1.3 Weave Net plugin for Docker true
內容解密:
此命令會列出已安裝的Docker外掛。ENABLED欄位顯示外掛是否已啟用。
檢查WeaveWorks網路狀態
可以使用以下命令檢查WeaveWorks網路外掛的狀態:
curl localhost:6782/status
輸出結果應該包含WeaveWorks網路外掛的狀態資訊,例如:
Version: 2.1.3
Service: router
Protocol: weave 1..2
Name: e6:cc:59:df:57:72(ip-172-31-11-209)
Encryption: disabled
PeerDiscovery: enabled
Targets: 3
Connections: 5 (5 established)
Peers: 6 (with 30 established connections)
TrustedSubnets: none
Service: ipam
Status: idle
Range: 10.32.0.0/12
DefaultSubnet: 10.32.0.0/12
Service: plugin (v2)
內容解密:
此輸出結果顯示了WeaveWorks網路外掛的狀態,包括連線數、節點數和IP範圍等資訊。
建立WeaveWorks網路
可以使用以下命令建立一個WeaveWorks網路:
docker network create -d weaveworks/net-plugin:2.1.3 \
--subnet=10.32.0.0/24 \
--gateway=10.32.0.1 \
--attachable my_net
內容解密:
此命令會建立一個名為my_net的WeaveWorks網路,子網為10.32.0.0/24,閘道器為10.32.0.1。--attachable引數允許容器使用docker run命令附加到此網路。
WeaveWorks網路拓撲
下圖顯示了WeaveWorks網路的拓撲結構:
graph LR;
A[ip-172-31-11-209] --> B[ip-172-31-8-157];
A --> C[ip-172-31-4-52];
A --> D[ip-172-31-1-223];
A --> E[ip-172-31-15-229];
A --> F[ip-172-31-0-153];
B --> A;
C --> A;
D --> A;
E --> A;
F --> A;
圖表翻譯: 此圖表顯示了WeaveWorks網路中各個節點之間的連線關係。每個節點都與其他五個節點建立連線,形成了一個全網狀網路。