協助改善此頁面
本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
若要提供此使用者指南,請選擇位於每個頁面右窗格的在 GitHub 上編輯此頁面連結。
本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
Kubernetes 具有原生功能,可讓您的應用程式對運作狀態降低或可用區域 (AZ) 受損等事件更具彈性。在 Amazon EKS 叢集中執行工作負載時,您可以使用 Amazon Application Recovery Controller (ARC) 的區域轉移或區域自動轉移,進一步改善應用程式環境的容錯能力和應用程式復原。ARC 區域轉移旨在作為暫時措施,可讓您將資源的流量從受損的可用區域移出,直到區域轉移過期或您將其取消。您可以視需要延長區域轉移。
您可以為 EKS 叢集啟動區域轉移,也可以透過啟用區域自動轉移 AWS 來允許 為您執行。此轉移會更新叢集中east-to-west網路流量的流程,只考慮在運作狀態良好的 AZs 中的工作者節點上執行之 Pod 的網路端點。此外,處理 EKS 叢集中應用程式傳入流量的任何 ALB 或 NLB 都會自動將流量路由到運作狀態良好的 AZs 中的目標。對於尋求最高可用性目標的客戶,如果 AZ 受損,則必須能夠將所有流量從受損的 AZ 轉向,直到復原為止。為此,您也可以啟用具有 ARC 區域轉移的 ALB 或 NLB。
了解 Pod 之間的東西網路流量流程
下圖說明兩個範例工作負載:訂單和產品。此範例的目的是顯示不同 AZs 中的工作負載和 Pod 如何通訊。


-
若要讓訂單與產品通訊,必須先解析目的地服務的 DNS 名稱。訂單將與 CoreDNS 通訊,以擷取該服務的虛擬 IP 地址 (叢集 IP)。一旦 Orders 解析產品服務名稱,就會將流量傳送至該目標 IP。
-
kube-proxy 會在叢集中的每個節點上執行,並持續監看 EndpointSlices
for Services。建立服務時,EndpointSlice 控制器會在背景中建立和管理 EndpointSlice。每個 EndpointSlice 都有端點清單或資料表,其中包含一部分的 Pod 地址及其執行所在的節點。kube-proxy 會在節點 iptables
上使用 為這些 Pod 端點設定路由規則。kube-proxy 也負責基本形式的負載平衡,方法是將目的地為服務叢集 IP 的流量重新導向至 ,而不是直接傳送至 Pod 的 IP 地址。kube-proxy 會在傳出連線上重寫目的地 IP 來執行此操作。 -
然後,網路封包會透過個別節點上的 ENIs 傳送至 AZ 2 中的產品 Pod (如上圖所述)。
了解 Amazon EKS 中的 ARC 區域轉移
如果您的環境中有 AZ 受損,您可以為 EKS 叢集環境啟動區域轉移。或者,您可以允許 使用區域自動轉移為您 AWS 管理。使用區域自動轉移時, AWS 會監控整體 AZ 運作狀態,並透過自動將流量從叢集環境中受損的 AZ 轉移來回應潛在的 AZ 損害。
一旦 Amazon EKS 叢集已啟用 ARC 的區域轉移,您就可以使用 ARC AWS 主控台、CLI 或區域轉移和區域自動轉移 APIs 來觸發區域轉移或啟用區域自動轉移。在 EKS 區域轉移期間,會自動發生下列狀況:
-
受影響 AZ 中的所有節點都會進行封鎖。這將防止 Kubernetes 排程器將新的 Pod 排程到運作狀態不佳的 AZ 中的節點。
-
如果您使用的是受管節點群組,則可用區域重新平衡將暫停,而且您的 Auto Scaling 群組 (ASG) 將更新,以確保新的 EKS 資料平面節點僅在運作狀態良好的AZs啟動。
-
運作狀態不佳的 AZ 中的節點不會終止,也不會從這些節點移出 Pod。這是為了確保當區域轉移過期或取消時,您的流量可以安全地傳回至仍有完整容量的 AZ
-
EndpointSlice 控制器會在受損的 AZ 中找到所有 Pod 端點,並從相關的 EndpointSlices 中移除它們。這將確保只有運作狀態良好的 AZs 中的 Pod 端點才能接收網路流量。當區域轉移取消或過期時,EndpointSlice 控制器會更新 EndpointSlices,以將端點包含在還原的 AZ 中。
下圖說明 EKS 區域轉移如何確保叢集環境中只有運作狀態良好的 Pod 端點成為目標的高層級流程。


EKS 區域轉移要求
若要讓區域轉移在 EKS 中成功運作,您需要事先設定叢集環境以應對 AZ 受損。以下是您必須遵循的步驟清單。
-
跨多個AZs佈建叢集的工作者節點
-
佈建足夠的運算容量,以承受移除單一可用區域
-
在每個 AZ 中預先擴展您的 Pod (包括 CoreDNS)
-
將多個 Pod 複本分散到所有AZs,以確保從單一可用區域轉移將讓您擁有足夠的容量
-
將相互依賴或相關的 Pod 共同放置在相同的 AZ 中
-
透過手動啟動區域轉移,測試您的叢集環境是否可如預期使用一個較少的可用區域。或者,您可以啟用區域自動轉移,並在自動轉移實務執行時回覆。區域轉移在 EKS 中運作時不需要,但強烈建議這麼做。
在多個AZs佈建 EKS 工作者節點
AWS 區域具有多個不同的位置,其實體資料中心稱為可用區域 (AZs)。AZs旨在彼此實體隔離,以避免可能影響整個區域的同時影響。佈建 EKS 叢集時,您應該將工作者節點部署到區域中的多個 AZs。這將使您的叢集環境對單一可用區受損更具彈性,並允許您維護在其他AZs區中執行之應用程式的高可用性 (HA)。當您從受影響的可用區域開始區域轉移時,EKS 環境的叢集內網路會自動更新為僅使用運作狀態良好的可用AZs,同時為您的叢集維持高可用性狀態。
確保您擁有 EKS 環境的此類多可用區設定,可增強系統的整體可靠性。不過,多可用區域環境在傳輸和處理應用程式資料的方式上扮演重要角色,這反而會影響您環境的網路費用。特別是,頻繁的輸出跨區域流量 (分散在AZs之間的流量) 可能會對您的網路相關成本產生重大影響。您可以套用不同的策略來控制 EKS 叢集中 Pod 之間的跨區域流量,並降低相關聯的成本。如需如何在執行高可用性 EKS 環境時最佳化網路成本的詳細資訊,請參閱此最佳實務指南
下圖說明具有 3 個運作狀態良好的 AZs 的高可用性 EKS 環境。

下圖說明具有 3 個AZs EKS 環境如何對可用區域受損具有彈性,並由於其他 2 個運作狀態良好的AZs而保持高可用性。

佈建足夠的運算容量,可承受移除單一可用區域
若要最佳化 EKS 資料平面中運算基礎設施的資源使用率和成本,最佳實務是使運算容量符合工作負載需求。不過,如果您的所有工作者節點都已滿容量,這可讓您依賴將新的工作者節點新增至 EKS 資料平面,然後才能排程新的 Pod。執行關鍵工作負載時,通常最佳實務是在線上使用備援容量執行,以處理負載突然增加、節點運作狀態問題等事件。如果您計劃使用區域轉移,則計劃移除整個 AZ 容量,因此您需要調整備援運算容量,以便即使 AZ 離線也能處理負載。
擴展運算時,將新節點新增至 EKS 資料平面的程序需要一些時間,這可能會影響應用程式的即時效能和可用性,尤其是在區域受損的情況下。您的 EKS 環境應具有彈性,以吸收遺失可用區負載,以避免最終使用者或用戶端體驗降級。這表示在需要新 Pod 的時間,以及實際排程在工作者節點的時間之間,盡可能減少或消除任何延遲。
此外,如果發生區域受損,您應該降低潛在運算容量限制的風險,以防止在運作狀態良好的 AZs 中將新所需的節點新增至 EKS 資料平面。
若要達成此目的,您應該在每個AZs的某些工作者節點中過度佈建運算容量,以便 Kubernetes 排程器具有可用於新 Pod 置放的預先存在容量,特別是當您的環境中有一個較少的可用區域時。
在 AZs 中執行並分散多個 Pod 複本
Kubernetes 可讓您透過執行單一應用程式的多個執行個體 (Pod 複本) 來預先擴展工作負載。為應用程式執行多個 Pod 複本可消除單一故障點,並透過減少單一複本上的資源負擔來提高其整體效能。不過,若要同時擁有高可用性和更佳的應用程式容錯能力,您應該在不同的故障網域 (也稱為拓撲網域) 中執行並分散應用程式的多個複本,在此情況下為 AZs。透過拓撲分散限制
下圖說明當所有 AZs都正常運作時,具有east-to-west流量流的 EKS 環境。

下圖說明單一可用區故障時具有east-to-west流量流的 EKS 環境,而且您啟動區域轉移。

以下程式碼片段是如何使用此 Kubernetes 功能設定工作負載的範例。
apiVersion: apps/v1
kind: Deployment
metadata:
name: orders
spec:
replicas: 9
selector:
matchLabels:
app:orders
template:
metadata:
labels:
app: orders
tier: backend
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: "topology.kubernetes.io/zone"
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app: orders
最重要的是,您應該執行 DNS 伺服器軟體 (CoreDNS/kube-dns) 的多個複本,並在尚未預設設定時套用類似的拓撲分散限制。這有助於確保您在運作狀態良好的AZs有足夠的 DNS Pod,以便在單一可用區域受損時,繼續處理叢集中其他通訊 Pod 的服務探索請求。CoreDNS EKS 附加元件具有預設設定,可在多個可用AZs有節點時,將 CoreDNS Pod 分散到叢集的可用區域。您也可以將這些預設設定取代為您自己的自訂組態。
使用 Helm 安裝 CoreDNS replicaCount
的 ,以確保您在每個可用區域中有足夠數量的複本。此外,為了確保這些複本分散到叢集環境中的不同AZs,您應該更新相同 value.yaml 檔案中的 topologySpreadConstraints
屬性。下面的程式碼片段示範如何為此設定 CoreDNS。
CoreDNS Helm values.yaml
replicaCount: 6
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
k8s-app: kube-dns
如果 AZ 受損,您可以使用 CoreDNS 的自動擴展系統來吸收 CoreDNS Pod 上增加的負載。您需要的 DNS 執行個體數目取決於叢集中執行的工作負載數目。CoreDNS 是 CPU 繫結,允許它使用 Horizontal Pod Autoscaler (HPA)
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: coredns
namespace: default
spec:
maxReplicas: 20
minReplicas: 2
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: coredns
targetCPUUtilizationPercentage: 50
或者,EKS 可以在 CoreDNS 的 EKS 附加元件版本中管理 CoreDNS 部署的自動擴展。此 CoreDNS 自動擴展器會持續監控叢集狀態,包括節點和 CPU 核心的數量。根據該資訊,控制器將動態調整 EKS 叢集中 CoreDNS 部署的複本數量。
若要在 CoreDNS EKS 附加元件中啟用自動擴展組態,您應該新增下列選用組態設定:
{
"autoScaling": {
"enabled": true
}
}
您也可以使用 NodeLocal DNS
在相同 AZ 中共置相互依存 Pod
在大多數情況下,您可能正在執行不同的工作負載,這些工作負載必須互相通訊,才能成功執行end-to-end程序。如果不同的應用程式分散在不同 AZs 中,但未共置在相同的 AZ 中,則單一 AZ 受損可能會影響基礎end-to-end程序。例如,如果應用程式 A 在 AZ 1 和 AZ 2 中有多個複本,但應用程式 B 在 AZ 3 中有其所有複本,則 AZ 3 的遺失將影響這兩個工作負載 (應用程式 A 和 B) 之間的任何end-to-end程序。將拓撲分散限制與 Pod 親和性結合,可以透過將 Pod 分散到所有AZs,以及設定特定 Pod 之間的關係,以確保它們共置在一起,來增強應用程式的彈性。
使用 Pod 親和性規則
apiVersion: apps/v1
kind: Deployment
metadata:
name: products
namespace: ecommerce
labels:
app.kubernetes.io/version: "0.1.6"
spec:
serviceAccountName: graphql-service-account
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- orders
topologyKey: "kubernetes.io/hostname"
下圖說明已使用 Pod 親和性規則在相同節點上共置的 Pod。

測試您的叢集環境是否可以處理 AZ 的遺失
完成上述要求後,下一個重要步驟是測試您是否有足夠的運算和工作負載容量來處理 AZ 遺失。您可以透過手動觸發 EKS 中的區域轉移來執行此操作。或者,您可以啟用區域自動轉移,並設定實務執行,以測試您的應用程式在叢集環境中的可用區域是否如預期運作。
常見問答集
為什麼我應該使用此功能?
透過在 EKS 叢集中使用 ARC 區域轉移或區域自動轉移,您可以藉由自動化快速復原程序,將叢集內網路流量從受損的可用區域轉移出來,以更好地維持 Kubernetes 應用程式可用性。使用 ARC,您可以避免長時間且複雜的步驟,這通常會導致在受損的 AZ 事件期間延長復原期間。
此功能如何與其他 AWS 服務搭配使用?
EKS 與 ARC 整合,提供主要界面供您完成復原操作 AWS。為了確保叢集內流量適當路由離開受損的可用區域,會修改在 Kubernetes 資料平面中執行之 Pod 的網路端點清單。如果您使用 AWS 負載平衡器將外部流量路由到叢集,則已經可以向 ARC 註冊負載平衡器,並在它們上觸發區域轉移,以防止流量流入降級的區域。此功能也會與 EKS 受管節點群組 (MNG) 建立的 Amazon EC2 Auto Scaling 群組 (ASG) 互動。為了防止受損的 AZ 用於新的 Kubernetes Pod 或節點啟動,EKS 會從 ASG 中移除受損的 AZ。
此功能與預設 Kubernetes 保護有何不同?
此功能可搭配多種 Kubernetes 原生內建保護,協助客戶保持彈性。您可以設定 Pod 整備和活體探查,以決定 Pod 何時應接收流量。當這些探查失敗時,Kubernetes 會將這些 Pod 移除為服務的目標,且流量不會再傳送至 Pod。雖然這很實用,但客戶設定這些運作狀態檢查並不容易,因此當區域降級時,保證它們會失敗。ARC 區域轉移功能為您提供額外的安全網,當 Kubernetes 的原生保護尚未足夠時,可協助它們完全隔離降級的可用區域。它也提供簡單的方法來測試架構的操作準備程度和彈性。
可以代表我 AWS 觸發區域轉移嗎?
是,如果您想要完全自動化的方式來使用 ARC 區域轉移,您可以啟用 ARC 區域自動轉移。透過區域自動轉移,您可以依賴 AWS 來監控 EKS 叢集的AZs運作狀態,並在偵測到可用區域受損時自動觸發轉移。
如果我使用此功能,而且我的工作者節點和工作負載未預先擴展,會發生什麼情況?
如果您未預先調整規模,並依賴於在區域轉移期間佈建其他節點或 Pod,則會有延遲復原的風險。將新節點新增至 Kubernetes 資料平面的程序需要一些時間,這可能會影響應用程式的即時效能和可用性,尤其是在區域受損的情況下。此外,如果區域受損,您可能會遇到潛在的運算容量限制,這可能會阻止將新所需的節點新增至運作狀態良好的AZs。
如果您的工作負載未預先擴展,並分散到叢集中的所有AZs,則區域受損可能會影響僅在受影響可用區域中的工作者節點上執行的應用程式可用性。為了降低應用程式完全可用性中斷的風險,如果工作負載在運作狀態不佳的可用區域中擁有其所有端點,EKS 會無法安全地將流量傳送至受損區域中的 Pod 端點。不過,強烈建議您預先擴展應用程式,並將其分散到所有AZs,以便在發生區域問題時維持可用性。
如果我執行具狀態的應用程式,會發生什麼情況?
如果您執行具狀態的應用程式,則需要根據使用案例和架構來評估其容錯能力。如果您有作用中/待命架構或模式,則可能會有作用中位於受損 AZ 中的執行個體。在應用程式層級,如果未啟用待命,您可能會遇到應用程式的問題。當新的 Kubernetes Pod 在運作狀態良好的可用AZs啟動時,您可能會遇到問題,因為它們無法連接至繫結至受損可用區域的持久性磁碟區。
此功能是否適用於 Karpenter?
Karpenter 支援目前不適用於 EKS 中的 ARC 區域轉移和區域自動轉移。如果 AZ 受損,您可以透過移除運作狀態不佳的 AZ 來調整相關的 Karpenter NodePool 組態,以便僅在運作狀態良好的 AZs 中啟動新的工作者節點。
此功能是否適用於 EKS Fargate?
此功能不適用於 EKS Fargate。根據預設,當 EKS Fargate 辨識區域運作狀態事件時,Pod 會偏好在其他 AZs 中執行。
EKS 受管 Kubernetes 控制平面是否會受到影響?
否,根據預設,Amazon EKS 會在多個AZs執行和擴展 Kubernetes 控制平面,以確保高可用性。ARC 區域轉移和區域自動轉移只會在 Kubernetes 資料平面上運作。
此新功能是否有任何相關成本?
您可以在 EKS 叢集中使用 ARC 區域轉移和區域自動轉移,無需額外費用。不過,您將繼續支付佈建執行個體的費用,強烈建議您在使用此功能之前預先擴展 Kubernetes 資料平面。您應該考慮成本和應用程式可用性之間的正確平衡。