Longhorn,企業(yè)級(jí)云原生容器分布式存儲(chǔ) - 高可用
目錄
- 數(shù)據(jù)局部性
- 更改默認(rèn)全局設(shè)置
- 使用 Longhorn UI 更改單個(gè)卷的數(shù)據(jù)位置
- 使用 StorageClass 為單個(gè)卷設(shè)置數(shù)據(jù)局部性
- 數(shù)據(jù)局部性設(shè)置
- 如何為卷設(shè)置數(shù)據(jù)局部性
- 意外分離后恢復(fù)卷
- 使用 Longhorn 處理節(jié)點(diǎn)故障
- 卷附件恢復(fù)策略
- 卷附件恢復(fù)策略never (Kubernetes 默認(rèn))
- 卷附件恢復(fù)策略 wait (Longhorn 默認(rèn))
- 卷附件恢復(fù)策略 immediate
- 當(dāng) Kubernetes 節(jié)點(diǎn)出現(xiàn)故障時(shí)會(huì)發(fā)生什么
- 節(jié)點(diǎn)宕機(jī)時(shí)的 Longhorn Pod 刪除策略
- 當(dāng)發(fā)生故障的 Kubernetes 節(jié)點(diǎn)恢復(fù)時(shí)會(huì)發(fā)生什么
數(shù)據(jù)局部性
數(shù)據(jù)局部性設(shè)置(data locality setting)旨在在以下情況下啟用:只要有可能,至少應(yīng)在與使用該卷的 pod 相同的節(jié)點(diǎn)上調(diào)度 Longhorn 卷的一個(gè)副本。我們將擁有本地副本的特性稱為具有 data locality。
例如,當(dāng)集群的網(wǎng)絡(luò)不好時(shí),數(shù)據(jù)局部性(data locality)會(huì)很有用,因?yàn)閾碛斜镜馗北緯?huì)增加卷的可用性。
數(shù)據(jù)局部性(data locality)對(duì)于分布式應(yīng)用程序(例如數(shù)據(jù)庫(kù))也很有用,其中在應(yīng)用程序級(jí)別而不是卷級(jí)別實(shí)現(xiàn)高可用性。在這種情況下,每個(gè) Pod 只需要一個(gè)卷,因此每個(gè)卷都應(yīng)該與使用它的 Pod 調(diào)度在同一節(jié)點(diǎn)上。此外,卷調(diào)度的默認(rèn) Longhorn 行為可能會(huì)導(dǎo)致分布式應(yīng)用程序出現(xiàn)問(wèn)題。問(wèn)題是,如果一個(gè) Pod 有兩個(gè)副本,并且每個(gè) Pod 副本都有一個(gè)卷,Longhorn 不知道這些卷具有相同的數(shù)據(jù),不應(yīng)調(diào)度在同一個(gè)節(jié)點(diǎn)上。因此 Longhorn 可以在同一節(jié)點(diǎn)上調(diào)度相同的副本,從而阻止它們?yōu)楣ぷ髫?fù)載提供高可用性。
當(dāng)數(shù)據(jù)局部性被禁用時(shí),Longhorn 卷可以由集群中任何節(jié)點(diǎn)上的副本支持,并由運(yùn)行在集群中任何節(jié)點(diǎn)上的 pod 訪問(wèn)。
數(shù)據(jù)局部性設(shè)置
Longhorn 目前支持兩種 data locality 設(shè)置模式:
- disabled. 這是默認(rèn)選項(xiàng)。在與附加卷(工作負(fù)載)相同的節(jié)點(diǎn)上可能有也可能沒(méi)有副本。
- best-effort. 此選項(xiàng)指示 Longhorn 嘗試將副本保留在與附加卷(工作負(fù)載)相同的節(jié)點(diǎn)上。Longhorn 不會(huì)停止該卷,即使它由于環(huán)境限制而無(wú)法將副本保留在附加卷(工作負(fù)載)的本地,例如:磁盤(pán)空間不足、磁盤(pán)標(biāo)簽不兼容等。
如何為卷設(shè)置數(shù)據(jù)局部性
可以通過(guò)三種方式為 Longhorn 卷設(shè)置 data locality:
更改默認(rèn)全局設(shè)置
您可以在 Longhorn UI 設(shè)置中更改 data locality 的全局默認(rèn)設(shè)置。全局設(shè)置僅用作默認(rèn)值,類似于副本計(jì)數(shù)(replica count)。它不會(huì)更改任何現(xiàn)有卷的設(shè)置。當(dāng)創(chuàng)建卷時(shí)未指定(data locality),Longhorn 將使用全局默認(rèn)設(shè)置來(lái)確定卷的 data locality。
使用 Longhorn UI 更改單個(gè)卷的數(shù)據(jù)位置
您可以使用 Longhorn UI 在創(chuàng)建卷時(shí)設(shè)置 data locality。您還可以在 volume detail 頁(yè)面中更改卷創(chuàng)建后的 data locality setting。
使用 StorageClass 為單個(gè)卷設(shè)置數(shù)據(jù)局部性
Longhorn 還將 data locality setting 公開(kāi)為 StorageClass 中的參數(shù)。您可以使用指定的 data locality setting 創(chuàng)建 StorageClass,然后使用 StorageClass 創(chuàng)建 PVC。例如,下面的 YAML 文件定義了一個(gè) StorageClass,它告訴 Longhorn CSI driver 將 data locality 設(shè)置為 best-effort:
- kind: StorageClass
- apiVersion: storage.k8s.io/v1
- metadata:
- name: hyper-converged
- provisioner: driver.longhorn.io
- allowVolumeExpansion: true
- parameters:
- numberOfReplicas: "2"
- dataLocality: "best-effort"
- staleReplicaTimeout: "2880" # 48 hours in minutes
- fromBackup: ""
意外分離后恢復(fù)卷
當(dāng)發(fā)生意外分離(unexpected detachment)時(shí),可能發(fā)生在 Kubernetes upgrade、Docker reboot或網(wǎng)絡(luò)斷開(kāi)連接期間,如果 pod 由控制器管理(例如:deployment、statefulset、daemonset 等),Longhorn 會(huì)自動(dòng)刪除工作負(fù)載 pod。通過(guò)刪除 pod,它的控制器會(huì)重新啟動(dòng) pod,Kubernetes 處理卷重新附加(reattachment)和重新掛載(remount)。
如果您不希望 Longhorn 自動(dòng)刪除 workload pod,您可以在 Longhorn UI 的設(shè)置 Automatically Delete Workload Pod when The Volume Is Detached Unexpectedly(卷意外分離時(shí)自動(dòng)刪除工作負(fù)載 Pod) 中進(jìn)行設(shè)置。
對(duì)于沒(méi)有控制器的 Pod,Longhorn 不會(huì)刪除它們,因?yàn)槿绻?Longhorn 刪除,則沒(méi)有人會(huì)重新啟動(dòng)它們。要恢復(fù)意外分離的卷,您必須手動(dòng)刪除并重新創(chuàng)建沒(méi)有控制器的 pod。
使用 Longhorn 處理節(jié)點(diǎn)故障
當(dāng) Kubernetes 節(jié)點(diǎn)出現(xiàn)故障時(shí)會(huì)發(fā)生什么
本節(jié)旨在告知用戶節(jié)點(diǎn)故障(node failure)期間會(huì)發(fā)生什么以及恢復(fù)期間會(huì)發(fā)生什么。
一分鐘后,kubectl get nodes 將報(bào)告失敗節(jié)點(diǎn)的 NotReady。
大約五分鐘后,NotReady 節(jié)點(diǎn)上的所有 Pod 的狀態(tài)將更改為 Unknown 或 NodeLost。
StatefulSets 具有穩(wěn)定的 identity,因此 Kubernetes 不會(huì)為用戶強(qiáng)制刪除 pod。請(qǐng)參閱有關(guān)強(qiáng)制刪除 StatefulSet 的官方 Kubernetes 文檔。
Deployments 沒(méi)有穩(wěn)定的 identity,但是對(duì)于 Read-Write-Once 類型的存儲(chǔ),由于它不能同時(shí)附加到兩個(gè)節(jié)點(diǎn),Kubernetes 創(chuàng)建的新 pod 將無(wú)法啟動(dòng),因?yàn)?RWO 卷仍連接到舊 pod,位于丟失的節(jié)點(diǎn)上。
在這兩種情況下,Kubernetes 都會(huì)自動(dòng)驅(qū)逐丟失節(jié)點(diǎn)上的 pod(為 pod 設(shè)置刪除時(shí)間戳),然后嘗試用舊卷重新創(chuàng)建一個(gè)新的卷。因?yàn)楸或?qū)逐的 pod 會(huì)卡在 Terminating 狀態(tài),并且附加的卷不能被釋放/重用(released/reused),如果沒(méi)有管理(admin)或存儲(chǔ)(storage)軟件的干預(yù),新的 pod 將卡在 ContainerCreating 狀態(tài)。
節(jié)點(diǎn)宕機(jī)時(shí)的 Longhorn Pod 刪除策略
Longhorn 提供了一個(gè)選項(xiàng)來(lái)幫助用戶在宕機(jī)的節(jié)點(diǎn)上自動(dòng)強(qiáng)制刪除 StatefulSet/Deployment 的終止 pod。強(qiáng)制刪除后,Kubernetes 將分離 Longhorn 卷并在新節(jié)點(diǎn)上啟動(dòng)替換 pod。
您可以在 Longhorn UI 或 Settings reference 的 Settings 選項(xiàng)卡中的 Pod Deletion Policy When Node is Down(節(jié)點(diǎn)宕機(jī)時(shí)的 Pod 刪除策略)中找到有關(guān)設(shè)置選項(xiàng)的更多詳細(xì)信息。
卷附件恢復(fù)策略
如果您決定強(qiáng)制刪除 pod(手動(dòng)或在 Longhorn 的幫助下),Kubernetes 將需要大約 6 分鐘的時(shí)間來(lái)刪除與 Pod 關(guān)聯(lián)的 VolumeAttachment 對(duì)象,然后最終將卷與丟失的節(jié)點(diǎn)分離并允許它由新 pod 使用。
這 6 分鐘的時(shí)間段在 Kubernetes 中是硬編碼的:如果丟失節(jié)點(diǎn)上的 pod 被強(qiáng)制刪除,則相關(guān)卷將無(wú)法正確卸載。然后 Kubernetes 會(huì)等待這個(gè)固定的超時(shí)時(shí)間直接清理 VolumeAttachment 對(duì)象。
為了解決這個(gè)問(wèn)題,我們提供了 3 種不同的卷附件恢復(fù)策略。
卷附件恢復(fù)策略never (Kubernetes 默認(rèn))
Longhorn 不會(huì)從故障節(jié)點(diǎn)恢復(fù) Volume Attachment,這與 Kubernetes 的默認(rèn)行為一致。用戶需要強(qiáng)制刪除終止的 pod,此時(shí) Longhorn 將從故障節(jié)點(diǎn)恢復(fù) Volume Attachment。然后允許掛起的替換 pod(replacement pod)在請(qǐng)求的卷可用的情況下正確啟動(dòng)。
卷附件恢復(fù)策略 wait (Longhorn 默認(rèn))
Longhorn 將等待恢復(fù) Volume Attachment,直到所有終止 pod(terminating pod)刪除寬限期過(guò)去。由于此時(shí)需要節(jié)點(diǎn) kubelet 刪除 Pod,并且 Pod 仍然可用,我們可以得出結(jié)論,故障節(jié)點(diǎn) Kubelet 無(wú)法刪除 Pod。此時(shí) Longhorn 將從故障節(jié)點(diǎn)恢復(fù) Volume Attachment。然后允許掛起的替換 pod(replacement pod) 在請(qǐng)求的卷可用的情況下正確啟動(dòng)。
卷附件恢復(fù)策略 immediate
只要有待處理的替換 Pod(replacement pod) 可用,Longhorn 就會(huì)從故障節(jié)點(diǎn)恢復(fù) Volume Attachment。然后允許掛起的替換 pod(replacement pod)在請(qǐng)求的卷可用的情況下正確啟動(dòng)。
當(dāng)發(fā)生故障的 Kubernetes 節(jié)點(diǎn)恢復(fù)時(shí)會(huì)發(fā)生什么
如果節(jié)點(diǎn)在故障后 5 到 6 分鐘內(nèi)重新聯(lián)機(jī),Kubernetes 將重新啟動(dòng) Pod、卸載(unmount)和重新安裝(re-mount)卷,而無(wú)需重新附加卷(re-attaching)和 VolumeAttachment 清理。
因?yàn)榫硪?volume engines)會(huì)在節(jié)點(diǎn)宕機(jī)后關(guān)閉,所以這種直接重新安裝將不起作用,因?yàn)樵撛O(shè)備不再存在于節(jié)點(diǎn)上。
在這種情況下,Longhorn 將分離并重新附加卷以恢復(fù)卷引擎,以便 pod 可以安全地重新掛載/重用卷(remount/reuse)。
如果節(jié)點(diǎn)在故障后 5-6 分鐘內(nèi)沒(méi)有重新上線,Kubernetes 將嘗試基于 pod eviction 機(jī)制刪除所有無(wú)法訪問(wèn)的 pod,這些 pod 將處于 Terminating 狀態(tài)。有關(guān)詳細(xì)信息,請(qǐng)參閱 pod eviction timeout。
然后,如果故障節(jié)點(diǎn)稍后恢復(fù),Kubernetes 將重新啟動(dòng)那些終止的 pod,分離卷(detach the volumes),等待舊的 VolumeAttachment 清理,并重用重新附加和重新掛載(re-attach & re-mount)卷。通常這些步驟可能需要 1 ~ 7 分鐘。
在這種情況下,分離(detaching)和重新附加(re-attaching)操作已經(jīng)包含在 Kubernetes 恢復(fù)過(guò)程中。因此不需要額外的操作,Longhorn 卷將在上述步驟后可用。
對(duì)于上述所有恢復(fù)場(chǎng)景,Longhorn 將通過(guò) Kubernetes 的關(guān)聯(lián)(association)自動(dòng)處理這些步驟。