Kubernetes 叢集的災難復原規劃需涵蓋 etcd、控制平面、工作節點及應用程式資料等導向。etcd 備份是復原的關鍵,持久化資料的備份策略則需根據實際儲存方案調整。工作節點的復原主要仰賴重建機制,雲端環境中通常涉及建立新例項並加入叢集。應用程式資料的保護則需考量持久化卷的特性和備份機制,同時留意本地資料的處理方式,避免資料遺失。
在 Kubernetes 叢集中,etcd 的備份與還原至關重要,它儲存了整個叢集的狀態資訊。etcdctl 工具提供 snapshot save 和 restore 命令,方便進行備份和還原操作。備份策略需考量完整性、一致性和額外元件的備份需求。Ark 工具則提供更進階的備份和還原功能,例如部分備份、還原到新環境、持久化資料備份和排程備份等。
災難復原策略與實務
在設計 Kubernetes 叢集時,瞭解叢集規模與效能之間的關係至關重要。當叢集規模擴大時,其效能可能會逐漸下降。因此,在選擇叢集規模時,必須確保遠低於預期的 etcd 載荷。值得注意的是,Kubernetes 控制平面的故障通常不會影響資料平面。換言之,如果 API 伺服器、控制器管理器或排程器發生故障,Pod 通常會繼續運作。
狀態與備份
每個災難復原方案的核心問題都是:「如何還原到一個明確的先前狀態?」我們需要確保在災難發生時,擁有所有必要的資料,以便還原到運作狀態。幸運的是,在 Kubernetes 中,大部分叢集的操作狀態都集中儲存在 etcd 叢集中。因此,我們花了很多時間確保能夠在發生故障時重建其內容。
需要備份的專案
- 所有由 Kubernetes API 伺服器使用的 PKI 資產,通常位於
/etc/kubernetes/pki目錄下。 - 任何 Secret 加密金鑰,這些金鑰儲存在一個靜態檔案中,該檔案由 API 伺服器引數
--experimental-encryption-provider-config指定。 - 任何管理員憑證,大多數佈署工具(包括 kubeadm)會建立靜態的管理員憑證,並將其儲存在 kubeconfig 檔案中。
應用程式資料
除了重建 Kubernetes 本身所需的狀態外,還原有狀態的 Pod 也需要還原與這些 Pod 相關的持久化資料。
持久化卷
使用者可以透過多種方式在 Kubernetes 中持久化資料。備份這些資料的方式取決於您的環境。例如,在雲端供應商中,可能只需將持久化卷重新掛載到對應的 Pod 即可。同時,也可以依賴於支援卷的底層架構,例如使用根據 Ceph 的卷時,具有多個資料副本可能就足夠了。
# 建立 Persistent Volume 的範例
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
local:
path: /mnt/data
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node1
內容解密:
此範例展示瞭如何建立一個本地 Persistent Volume(PV)。capacity 指定了儲存容量,accessModes 定義了存取模式,persistentVolumeReclaimPolicy 設定為 Retain 以保留資料。local.path 指定了節點上的儲存路徑,而 nodeAffinity 確保該 PV 被排程到指定的節點上。
本地資料
一個經常被忽視的問題是,使用者有時會無意中將關鍵資料持久化到節點的本地磁碟上。在內部佈署環境中,由於可能沒有網路附加儲存,因此這種情況尤其常見。如果沒有適當的控制措施(例如 PodSecurityPolicy 和/或准入控制器),使用者可能會使用 emptyDir 或 hostPath 卷,並對這些資料的永續性做出錯誤的假設。
工作節點
工作節點在設計上是可替換的。因此,在設計工作節點的災難復原策略時,只需確保有一套可靠的流程來重建工作節點即可。在雲端供應商中,這通常意味著啟動一個新的例項並將其加入控制平面。
etcd
由於 etcd 叢集保留了其資料集的多個副本,因此完全故障的情況相對較少見。然而,備份 etcd 總是被視為生產叢集的最佳實踐。可以使用原生 etcd 命令列工具來備份 etcd 資料。
ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot save etcd-`date +%Y%m%d`.db
內容解密:
此命令使用 etcdctl 工具對 etcd 進行快照備份。ETCDCTL_API=3 指定使用 etcd 的 v3 API,--endpoints $ENDPOINT 指定了 etcd 的端點,而 snapshot save 命令則將快照儲存到指定的檔案中,檔案名稱包含了當前的日期。
綜上所述,一個完善的災難復原策略需要涵蓋 Kubernetes 的各個方面,包括控制平面、etcd、持久化資料以及工作節點等。只有這樣,才能在發生災難時快速還原叢集的運作。
Kubernetes 叢集備份與還原策略
在 Kubernetes 叢集管理中,備份與還原策略是確保系統穩定性和資料安全性的重要環節。有效的備份策略可以幫助您在發生災難或系統故障時快速還原叢集運作。
etcd 備份與還原
etcd 是 Kubernetes 的核心元件之一,負責儲存叢集的所有狀態資訊。因此,etcd 的備份與還原是 Kubernetes 叢集備份策略中的關鍵部分。
etcd 備份
etcd 的備份可以透過 etcdctl 工具來完成。以下是使用 etcdctl 進行 etcd 備份的範例:
ETCDCTL_API=3 etcdctl snapshot save etcd-$DATE.db
內容解密:
ETCDCTL_API=3指定使用 etcd 的 v3 API。etcdctl snapshot save命令用於建立 etcd 的快照備份。etcd-$DATE.db是備份檔案的名稱,其中$DATE應該替換為實際的日期。
etcd 還原
當需要還原 etcd 時,可以使用以下命令:
ETCDCTL_API=3 etcdctl snapshot restore etcd-$DATE.db --name $MEMBERNAME
內容解密:
--name $MEMBERNAME指定了要還原的 etcd 成員名稱。
備份策略的考量
在實施 etcd 備份策略時,需要考慮以下幾點:
- 完整性:etcd 備份包含了整個 etcd 鍵空間的狀態,這意味著備份檔案中包含了叢集的所有狀態資訊。
- 一致性:在備份過程中,如果 Kubernetes 叢集仍在運作,可能會存在暫時性的不一致狀態。
- 額外元件的備份:如果使用了額外的元件,如 Kubernetes Aggregate API 伺服器或 etcd-backed Calico,則需要額外的策略來備份這些元件的資料。
Ark:Kubernetes 叢集備份工具
Ark 是 Heptio 開發的一款專門用於 Kubernetes 叢集備份和還原的工具。它透過 Kubernetes API 進行備份,確保了資料的一致性,並允許更靈活的備份策略。
Ark 的特點
- 部分備份與還原:Ark 允許根據特定的標籤選擇器進行備份和還原。
- 還原到新環境:Ark 可以將備份還原到新的叢集或現有叢集中的新名稱空間。
- 持久化資料備份:Ark 可以與雲端提供商整合,自動對持久化卷進行快照備份。
- 排程備份:Ark 支援排程備份,確保定期進行備份。
Kubernetes 叢集擴充套件:叢集守護程式的角色與實踐
Kubernetes 作為一個強大的容器協調平台,其擴充套件性是其成功的關鍵因素之一。叢集守護程式(Cluster Daemons)是實作 Kubernetes 叢集擴充套件的一種簡單而常見的方式。它們為叢集新增自動化功能,使得叢集內的所有使用者都能無縫地享受到這些功能,而無需進行額外的組態。
叢集守護程式的定義與特性
叢集守護程式是一種特殊的代理程式,它們執行在 Kubernetes 叢集內,並為叢集新增額外的功能。這些守護程式具有兩個主要的特徵:首先,它們需要在 Kubernetes 叢集上執行;其次,它們為叢集提供了自動化的功能,這些功能對所有使用者都是透明的,無需使用者進行額外的操作。
佈署與管理
叢集守護程式通常被封裝成容器映像,並透過 Kubernetes 的組態物件進行佈署和管理。它們可以透過 DaemonSet 或 Deployment 在叢集中執行。通常,這些守護程式會被佈署在一個專用的 Namespace 中,以避免與其他應用程式混淆。當需要對這些守護程式進行監控、升級或維護時,它們會像其他應用程式一樣被管理。
叢集守護程式的應用場景
叢集守護程式可以提供多種自動化的功能,例如:
自動化指標收集:例如,Prometheus 可以作為一個叢集守護程式,自動從叢集中的各個 Pod 中收集指標資料。
apiVersion: apps/v1 kind: Deployment metadata: name: prometheus-deployment spec: replicas: 1 selector: matchLabels: app: prometheus template: metadata: labels: app: prometheus spec: containers: - name: prometheus image: prometheus/prometheus:latest volumeMounts: - name: prometheus-config mountPath: /etc/prometheus volumes: - name: prometheus-config configMap: name: prometheus-config內容解密:
- 這段 YAML 組態定義了一個名為
prometheus-deployment的 Deployment,用於佈署 Prometheus。 replicas: 1表示該 Deployment 將執行一個副本。selector.matchLabels和template.metadata.labels定義了標籤選擇器,用於比對由該 Deployment 管理的 Pod。spec.containers中定義了容器名稱、使用的映像以及掛載的組態卷。volumes部分定義了一個名為prometheus-config的 ConfigMap,用於掛載 Prometheus 的組態檔案。
- 這段 YAML 組態定義了一個名為
安全掃描:一個叢集守護程式可以掃描叢集中佈署的服務,以檢測跨站指令碼攻擊(XSS)等安全漏洞。
安裝與操作考量
安裝叢集守護程式通常涉及使用容器映像和 Kubernetes 組態檔案。這些組態可以由叢集管理員開發,也可以透過套件管理器(如 Helm)提供。安裝完成後,守護程式將立即開始運作,並像其他應用程式一樣透過 Kubernetes 組態物件進行升級、修復或移除。
儘管安裝叢集守護程式相對簡單,但它們的操作複雜度卻可能相當高。因為這些守護程式提供的功能是自動且透明的,使用者可能會依賴它們而沒有察覺。一旦這些守護程式出現問題,可能會對叢集的運作產生重大影響。因此,叢集管理員需要清楚地瞭解安裝和管理這些守護程式的責任。
Kubernetes 叢集擴充套件:叢集助理的角色與實作
在 Kubernetes 環境中,除了叢集守護程式(cluster daemon)之外,另一種重要的擴充套件方式是叢集助理(cluster assistant)。雖然兩者在某些方面相似,但叢集助理需要使用者主動參與組態,以啟用特定的功能。
叢集助理的使用場景
叢集助理主要用於簡化複雜的任務,減少使用者的工作量,避免因手動組態錯誤而導致的問題。這些任務通常涉及繁瑣的步驟,容易出錯,或者需要專業知識。例如,為 HTTP 服務新增 SSL 憑證就是一個典型的例子。
SSL 憑證組態例項
要為 Kubernetes 中的 HTTP 服務新增 SSL 憑證,使用者需要完成以下步驟:
- 取得 SSL 憑證:這通常涉及安裝工具、設定伺服器以及認證網域名稱等步驟。
- 將憑證佈署到 Web 伺服器:這可能需要建立 Kubernetes Secret,並將其與 HTTP 負載平衡器相關聯。
然而,這些步驟可能對開發者造成困擾。有些開發者可能會採取不安全的做法,直接將憑證封裝到容器映像中。叢集助理的出現正是為瞭解決這些問題,透過自動化流程來簡化 SSL 憑證的取得、佈署和輪換,確保所有操作都遵循最佳實踐。
叢集助理的優勢
對於叢集管理員來說,叢集助理具有以下優勢:
- 集中知識和最佳實踐:透過簡化複雜的組態,減少使用者疑問。
- 確保服務的一致性:所有佈署到叢集的服務都遵循相同的組態和最佳實踐。
安裝叢集助理
由於叢集助理和叢集守護程式在實作上並無本質區別,主要差異在於互動模式,因此安裝方法也大同小異。叢集助理同樣可以透過封裝指令碼或程式,並在 Kubernetes Pod 中執行來實作。
簡單範例:將指令碼轉換為叢集守護程式
#!/bin/bash
# 啟動一個簡單的 Web 伺服器
mkdir -p www
cd www
python -m SimpleHTTPServer 8080 &
cd ..
# 每隔十分鐘掃描所有服務並生成報告
while true; do
for service in $(kubectl --all-namespaces get services | awk '{print $0}'); do
python XssPy.py -u ${service} -e > www/${service}-$(date).txt
done
sleep 600
done
內容解密:
- 啟動 Web 伺服器:使用 Python 的
SimpleHTTPServer模組在 8080 連線埠上啟動一個簡單的 Web 伺服器,用於提供 XSS 掃描報告。 - 無限迴圈掃描:指令碼進入無限迴圈,每次迴圈都會遍歷叢集中所有服務,並使用
XssPy.py指令碼掃描每個服務的 XSS 弱點。 - 生成報告:掃描結果被寫入到
www目錄下的檔案中,檔案名稱包含服務名稱和掃描時間。 - 間隔執行:每次掃描完成後,指令碼會休眠 10 分鐘(600 秒),然後再次執行掃描。
這個範例展示瞭如何將一個簡單的指令碼轉換為叢集守護程式,用於定期掃描叢集中所有服務的 XSS 弱點,並提供掃描報告。進一步地,可以將此指令碼封裝到 Pod 中執行,從而實作自動化的安全掃描。
擴充套件 Kubernetes API 伺服器的生命週期
前面的例子都是執行在叢集上的應用程式,但這種叢集擴充套件方式存在一定的限制。更深入的擴充套件方式是擴充套件 API 伺服器本身的行為。這些擴充套件可以直接應用於所有 API 請求,因為它們是由 API 伺服器本身處理的。這使得叢集具有額外的擴充套件性。
使用案例:擴充套件 API 生命週期
由於 API 生命週期擴充套件存在於 API 伺服器的路徑中,因此可以使用它們對服務建立的所有 API 物件強制執行要求。例如,假設要確保叢集中執行的所有容器映像都來自公司的私有登入檔,並且維護命名約定。可能需要所有映像都具有 registry.my-co.com/<team-name>/<server-name>:<git-hash> 的形式,其中 registry.my-co.com 是公司執行的私有映像登入檔,<team-name> 和 <server-name> 是眾所周知的團隊和應用程式,最後,<git-hash> 是原始碼提交雜湊,表示構建映像的修訂版本。要求這樣的映像名稱可確保開發人員不會將生產映像儲存在公共(未經身份驗證的)映像儲存函式庫中,並且命名約定可確保任何應用程式(例如前面描述的 XSS 掃描器)都可以存取傳送通知所需的後設資料。要求 git-hash 可確保開發人員僅從已簽入(因此經過程式碼審查)的原始碼構建映像,並且可以輕鬆地從執行中的映像轉到其執行的原始碼。
程式碼範例:自定義准入控制器
import re
def validate_image_name(image_name):
pattern = r"^registry\.my-co\.com\/([a-zA-Z0-9_-]+)\/([a-zA-Z0-9_-]+):([a-f0-9]{7,})$"
match = re.match(pattern, image_name)
if not match:
return False
team_name, server_name, git_hash = match.groups()
# 驗證 team_name、server_name 和 git_hash 的有效性
# 例如,檢查 team_name 是否與已知團隊相關聯,git_hash 是否在團隊儲存函式庫的發布分支中
return True
def admission_controller(request):
# 解析請求中的映像名稱
image_name = request["object"]["spec"]["containers"][0]["image"]
if not validate_image_name(image_name):
return {"allowed": False, "status": {"code": 403, "message": "無效的映像名稱"}}
return {"allowed": True}
內容解密:
validate_image_name函式:使用正規表示式驗證映像名稱是否符合預期的格式。- 正規表示式模式
r"^registry\.my-co\.com\/([a-zA-Z0-9_-]+)\/([a-zA-Z0-9_-]+):([a-f0-9]{7,})$"用於比對registry.my-co.com/<team-name>/<server-name>:<git-hash>格式。 - 如果比對成功,則提取
team_name、server_name和git_hash以進行進一步驗證。
- 正規表示式模式
admission_controller函式:實作準入控制器的邏輯。- 從請求中提取映像名稱,並呼叫
validate_image_name進行驗證。 - 如果驗證失敗,傳回
{"allowed": False}以拒絕該請求,並提供錯誤訊息。 - 如果驗證成功,傳回
{"allowed": True}以允許該請求。
- 從請求中提取映像名稱,並呼叫
安裝 API 生命週期擴充套件
安裝 API 生命週期擴充套件有兩個部分。第一部分是建立一個服務來處理 webhook 呼叫,第二部分是建立一個新的 Kubernetes API 物件來新增擴充套件。要建立處理來自 API 伺服器的 webhook 呼叫的服務,需要建立一個能夠適當回應的網路服務。
API 生命週期擴充套件示意圖
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title Kubernetes 叢集災難復原與擴充套件策略
package "Kubernetes Cluster" {
package "Control Plane" {
component [API Server] as api
component [Controller Manager] as cm
component [Scheduler] as sched
database [etcd] as etcd
}
package "Worker Nodes" {
component [Kubelet] as kubelet
component [Kube-proxy] as proxy
package "Pods" {
component [Container 1] as c1
component [Container 2] as c2
}
}
}
api --> etcd : 儲存狀態
api --> cm : 控制迴圈
api --> sched : 調度決策
api --> kubelet : 指令下達
kubelet --> c1
kubelet --> c2
proxy --> c1 : 網路代理
proxy --> c2
note right of api
核心 API 入口
所有操作經由此處
end note
@enduml此圖示說明瞭 API 請求的流程,包括准入控制器的驗證步驟。