

 **協助改進此頁面** 

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

若要為本使用者指南貢獻內容，請點選每個頁面右側面板中的**在 GitHub 上編輯此頁面**連結。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 了解 Amazon EKS 中的 Amazon 應用程式復原控制器 (ARC) 區域轉移
<a name="zone-shift"></a>

Kubernetes 提供各種原生功能，可支援您針對運作狀態降級或可用區域 (AZ) 受損等事件，讓應用程式具備更強的復原能力。在 Amazon EKS 叢集中執行工作負載時，您可使用 [Amazon 應用程式復原控制器 (ARC) 區域轉移](https://docs.aws.amazon.com/r53recovery/latest/dg/arc-zonal-shift.html)或[區域自動轉移](https://docs.aws.amazon.com/r53recovery/latest/dg/arc-zonal-autoshift.html)，進一步改善應用程式環境的容錯能力與應用程式復原能力。ARC 區域轉移旨在作為一項臨時措施，讓您將資源的流量遠離受損的 AZ，直到區域轉移到期或您將它取消為止。您可在必要時擴充區域轉移。

您可以為 EKS 叢集啟動區域轉移，也可以透過啟用區域自動轉移 AWS 來允許 為您轉移流量。藉助此區域轉移，可將叢集中的東向西網路流量更新為只考慮正常運作 AZ 中工作節點上執行之 Pod 的網路端點。另外，任何 ALB 或 NLB 在處理 EKS 叢集中應用程式的輸入流量時，都會將流量路由自動至運作狀態良好的可用區域中的目標。若客戶尋求實現最高可用性目標，在可用區域受損時，能夠在復原之前將所有流量從受損的可用區域移出非常重要。因此，您亦可[https://docs.aws.amazon.com/r53recovery/latest/dg/arc-zonal-shift.resource-types.html](https://docs.aws.amazon.com/r53recovery/latest/dg/arc-zonal-shift.resource-types.html)。

## 了解 Pod 間的東西網路流量
<a name="_understanding_east_west_network_traffic_flow_between_pods"></a>

下面的圖表闡述了兩個範例工作負載：訂單與產品。此範例的用途是顯示不同可用區域中的工作負載與 Pod 如何通訊。

![\[網路流量圖解\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/zs-traffic-flow-before-1.png)


![\[網路流量圖解\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/zs-traffic-flow-before-2.png)


1. 為了讓訂單與產品通訊，訂單必須先解析目的地服務的 DNS 名稱。訂單與 CoreDNS 通訊，以便擷取該服務的虛擬 IP 位址 (叢集 IP)。訂單解析產品服務名稱之後，即會傳送流量至該目標 IP 位址。

1. kube-proxy 可在叢集的每個節點上執行，以及持續監看 [EndpointSlices](https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/) 的服務。建立服務後，EndpointSlice 控制器在後台建立及管理 EndpointSlice。每個 EndpointSlice 皆有端點清單或資料表，其中包含 Pod 位址子集，及其正在執行的節點。kube-proxy 可在節點上，使用 `iptables` 為這些 Pod 端點的每一個設定路由規則。此外，kube-proxy 還負責基本形式的負載平衡，以便重新引導目的地為服務叢集 IP 位址的流量，轉而直接傳送至 Pod 的 IP 位址。kube-proxy 可在傳出連線上重寫目的地 IP 位址，藉此來執行此操作。

1. 如先前圖表所示，隨後藉助各自節點上的 ENI，將網路封包傳送至可用區域 2 中的產品 Pod。

### 了解 Amazon EKS 中的 ARC 區域轉移
<a name="_understanding_arc_zonal_shift_in_amazon_eks"></a>

若您的環境中有可用區域受損，您可針對 EKS 叢集環境起始區域轉移。或者，您可以允許 使用區域自動轉移來 AWS 管理轉移流量。使用區域自動轉移， AWS 可監控整體 AZ 運作狀態，並透過自動將流量從叢集環境中受損的 AZ 轉移來回應潛在的 AZ 損害。

Amazon EKS 叢集使用 ARC 啟用區域轉移後，您可以使用 ARC 主控台、CLI 或區域轉移和區域自動轉移 APIs AWS 來啟動區域轉移或啟用區域自動轉移。EKS 區域轉移期間會自動執行以下操作：
+ 封鎖受影響可用區域中的所有節點。此操作可阻止 Kubernetes 排程器將新的 Pod 排程到運作狀態不佳可用區域中的節點。
+ 若您使用[受管節點群組](managed-node-groups.md)，[https://docs.aws.amazon.com/autoscaling/ec2/userguide/auto-scaling-benefits.html#AutoScalingBehavior.InstanceUsage](https://docs.aws.amazon.com/autoscaling/ec2/userguide/auto-scaling-benefits.html#AutoScalingBehavior.InstanceUsage)則會暫停，且 Auto Scaling 群組會更新，進而確保新的 EKS 資料平面節點僅在運作狀態良好的可用區域啟動。
+ 不會終止運作狀態不佳可用區域中的節點，亦不會從節點中移出 Pod。這可確保區域轉移到期或取消時，流量可安全地返回可用區域，以便獲取完整容量。
+ EndpointSlice 控制器可在受損的可用區域中尋找全部 Pod 端點，然後從相關的 EndpointSlices 中將其移除。此操作可確保僅鎖定運作狀態良好可用區域中的 Pod 端點，來接收網路流量。若區域轉移取消或到期，EndpointSlice 控制器將更新 EndpointSlices，以便在還原的可用區域中納入這些端點。

下面的圖表提供了一個高階概觀，闡述 EKS 區域轉移如何確保叢集環境中僅鎖定運作狀態良好的 Pod 端點。

![\[網路流量圖解\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/zs-traffic-flow-after-1.png)


![\[網路流量圖解\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/zs-traffic-flow-after-2.png)


## EKS 區域轉移要求
<a name="_eks_zonal_shift_requirements"></a>

為了將區域轉移與 EKS 成功地配合使用，必須事先設定叢集環境，以便具備復原能力應對可用區域受損。下面的清單列示了可協助確保復原能力的組態選項。
+ 跨多個可用區域佈建叢集的工作節點
+ 佈建足夠的運算容量來適應單一可用區域移除
+ 在每個可用區域預先擴展包括 CoreDNS 在內的 Pod
+ 將多個 Pod 複本分佈到所有可用區域，有助於確保從單一可用區域移出時，您仍有充足的容量
+ 在相同的可用區域主機代管相依或相關的 Pod
+ 手動啟動從可用區域區域移出，藉此測試在沒有一個可用區域的情況下，您的叢集環境是否如預期運作。或者，您可啟用區域自動轉移，以及依賴於自動轉移實際執行。手動或實際區域轉移測試，無須在 EKS 中運作區域轉移，但強烈建議這樣做。

### 跨多個可用區域佈建 EKS 工作節點
<a name="_provision_your_eks_worker_nodes_across_multiple_availability_zones"></a>

 AWS 區域具有多個不同的位置，具有實體資料中心，稱為可用區域 (AZs)。設置可用區域旨在彼此進行實體隔離，以避免可能同時影響整個區域。佈建 EKS 叢集後，建議您將工作節點部署至區域中的多個可用區域。此操作有助於讓叢集環境具備更強的復原能力來應對單一可用區域受損，還可確保在其他可用區域執行的應用程式具有高可用性。開始從受影響的可用區域移出時，EKS 環境的叢集內網路會自動更新，僅使用運作狀態良好的可用區域，進而有助於確保叢集具有高可用性。

確保 EKS 環境具有多可用區域設定，能夠增強系統的整體可靠性。然而，多可用區域環境會影響應用程式資料的傳輸及處理方式，進而影響環境的網路費用。具體來說，頻繁輸出跨區域流量 (在可用區域間分散的流量) 可能會對網路相關成本產生重大影響。您可運用不同的策略，來控制 EKS 叢集中 Pod 間的跨區域流量，進而降低關聯成本。若要了解如何在執行高可用性 EKS 環境時最佳化網路成本的詳細資訊，請參閱[https://aws.github.io/aws-eks-best-practices/cost_optimization/cost_opt_networking/](https://aws.github.io/aws-eks-best-practices/cost_optimization/cost_opt_networking/)。

下面的圖表闡述了三個運作狀態良好可用區域的高可用性 EKS 環境。

![\[網路圖解\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/zs-ha-before-failure.png)


下面的圖表闡述三個可用區域的 EKS 環境如何具備復原能力來應對可用區域受損，以及確保高可用性，因為還有兩個運作狀態良好的可用區域。

![\[網路圖解\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/zs-ha-after-failure.png)


### 佈建足夠的運算容量來應對單一可用區域移除
<a name="_provision_enough_compute_capacity_to_withstand_removal_of_a_single_availability_zone"></a>

如需最佳化 EKS 資料平面中運算基礎結構的資源使用率與成本，最佳實務是使運算容量符合工作負載需求。然而，**若您的所有工作節點容量已滿**，則您需要在排程新的 Pod 之前，將新的工作節點新增至 EKS 資料平面。若執行關鍵工作負載，最佳實務一般是在線上使用備援容量來執行，以便處理負載突增及節點運作狀態問題等情境。若您打算使用區域轉移，需要規劃在發生受損情況時移除整個可用區域的容量。這意味著必須調整備援運算容量，即使其中一個可用區域離線，也足以處理負載。

擴展運算資源後，需要一些時間來處理將新的節點新增至 EKS 資料平面的程序。這可能會影響應用程式的即時效能與可用性，在區域受損的情況下尤其如此。EKS 環境應能在缺少一個可用區域的情況下吸收負載，而不會導致最終使用者或用戶端的體驗降級。這意味著，需要新 Pod 與在工作節點實際排程的間隔時間，需要最大限度地減少或消除延遲。

另外，若出現區域受損，您應竭力緩解在運算容量約束條件中執行的風險，以阻止將新的必要節點新增至運作狀態良好可用區域中的 EKS 資料平面。

若要實現降低這些潛在負面影響的風險，建議您在每個可用區域的某些工作節點中過度佈建運算容量。執行此操作，Kubernetes 排程器就預先有容量可用於新 Pod 置放，在環境中缺少其中一個可用區域時尤其重要。

### 跨可用區域執行及分佈多個 Pod 複本
<a name="_run_and_spread_multiple_pod_replicas_across_availability_zones"></a>

Kubernetes 藉由執行單一應用程式的多個執行個體 (Pod 複本)，可讓您預先擴展您的工作負載。針對應用程式執行多個 Pod 複本，能夠消除單一故障點，以及減少單一複本上的資源壓力來提高整體效能。然而，若要讓應用程式同時具備高可用性與更佳容錯能力，建議您執行應用程式的多個複本，然後將複本分佈到不同的故障網域，亦稱為拓撲網域。此情境中的故障網域為可用區域。藉助[拓撲分佈約束條件](https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/)，您可設定應用程式，使其具備預先存在的靜態穩定性。之後，若可用區域受損，您的環境將會在運作狀態良好的可用區域擁有足夠的複本，以便立即處理任何流量尖峰或激增。

下面的圖表闡述了 EKS 環境，在所有可用區域運作狀態良好時，該環境具有東西向流量。

![\[網路圖解\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/zs-spread-constraints.png)


下面的圖表闡述了具有東西向流量的 EKS 環境，其中單一可用區域發生故障，並且您已開始區域轉移。

![\[網路圖解\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/zs-spread-constraints-2.png)


以下程式碼片段展示了如何在 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) 的多個複本，若預設未設定，則應套用類似的拓撲分佈約束條件。若有單一可用區域受損，這可協助確保您在運作狀態良好的可用區域有足夠的 DNS Pod，以便繼續處理叢集中其他通訊 Pod 的服務探索請求。[CoreDNS EKS 附加元件](managing-coredns.md)具有適用於 CoreDNS Pod 的預設設定，若多個可用區域有可用的節點，可確保這些節點將分佈到叢集的各個可用區域。您可依據意願，使用您自己的自訂組態來取代預設設定。

若您[透過 Helm 安裝 CoreDNS](https://github.com/coredns/helm/tree/master)，可更新 [values.yaml 檔案](https://github.com/coredns/helm/blob/master/charts/coredns/values.yaml)中的 `replicaCount`，以便確保在每個可用區域有充足的複本。另外，若要確保這些複本會分佈到叢集環境的不同可用區域，請確認您更新了同一 `values.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
```

若可用區域受損，您可藉助適用於 CoreDNS 的自動擴展系統，來吸收 CoreDNS Pod 上增加的負載。您所需的 DNS 執行個體數目視乎叢集中執行的工作負載數目而定。CoreDNS 與 CPU 繫結，可使用[水平 Pod 自動擴展器 (HPA)](https://aws.github.io/aws-eks-best-practices/reliability/docs/application/#horizontal-pod-autoscaler-hpa) 依據 CPU 來進行擴展。下面展示了一個範例，您可透過修改來滿足您的需求。

```
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 附加元件中啟用自動擴展組態](coredns-autoscaling.md)，請使用以下組態設定：

```
{
  "autoScaling": {
    "enabled": true
  }
}
```

您亦可使用 [NodeLocal DNS](https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/)，或是使用[叢集比例自動擴展器](https://github.com/kubernetes-sigs/cluster-proportional-autoscaler)來擴展 CoreDNS。如需詳細資訊，請參閱[水平擴展 CoreDNS](https://aws.github.io/aws-eks-best-practices/scalability/docs/cluster-services/#scale-coredns-horizontally)。

### 在同一可用區域設定相依的 Pod
<a name="_colocate_interdependent_pods_in_the_same_availability_zone"></a>

通常，應用程式有各種工作負載，需要彼此通訊來成功完成端對端程序。若這些不同的應用程式分佈到不同的可用區域，並且未在同一可用區域進行主機代管，則單一可用區域受損可能會影響端對端程序。舉例來說，若**應用程式 A** 在可用區域 1 與可用區域 2 有多個複本，但**應用程式 B** 在可用區域 3 有其所有複本，則缺少可用區域 3 會影響兩個工作負載 (**應用程式 A** 與**應用程式 B**) 間的端對端程序。若結合拓撲分佈約束條件與 Pod 親和性，則可將 Pod 分佈到所有可用區域，藉此增強應用程式的復原能力。另外，這可設定某些 Pod 間的關係，來確保其主機代管。

藉助 [Pod 親和性規則](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/)，您可定義工作負載間的關係，來影響 Kubernetes 排程器的行為，以便將 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 親和性規則在同一節點進行主機代管。

![\[網路圖解\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/zs-pod-affinity-rule.png)


### 測試叢集環境是否可應對可用區域缺失
<a name="_test_that_your_cluster_environment_can_handle_the_loss_of_an_az"></a>

在完成前面章節所述的要求之後，下一步是測試是否有充足的運算和工作負載容量來應對可用區域缺失。您可在 EKS 中，手動啟動區域轉移來執行此動作。或者，您可啟用區域自動轉移及設定實際執行，這亦會測試在叢集環境缺少一個可用區域的情況下，應用程式是否如預期運作。

## 常見問答集
<a name="_frequently_asked_questions"></a>

 **這項功能有什麼用？** 

藉由在您的 EKS 叢集中使用 ARC 區域轉移或區域自動轉移，您可自動執行從受損的可用區域移出叢集內網路流量的快速復原程序，以便更好地確保 Kubernetes 應用程式可用性。藉助 ARC，在發生受損可用區域事件期間，您可避免可能引起延長復原時段的冗長且複雜的步驟。

 **此功能如何與其他 AWS 服務搭配使用？** 

EKS 與 ARC 整合，可提供您完成復原操作的主要界面 AWS。若要確保叢集內流量從受損的可用區域適當移出，EKS 會對執行於 Kubernetes 資料平面的 Pod 的網路端點清單做出修改。若您使用 Elastic Load Balancing，將外部流量路由至叢集，可在 ARC 註冊負載平衡器，然後在這些負載平衡器上開始區域轉移，來阻止流量流入降級的可用區域。此外，區域轉移還適用於 EKS 受管節點群組建立的 Amazon EC2 Auto Scaling 群組。若要阻止受損的可用區域用於新的 Kubernetes Pod 或節點啟動，EKS 會從 Auto Scaling 群組中移除受損的可用區域。

 **此功能與預設 Kubernetes 防護有何差異？** 

此功能可與若干 Kubernetes 內建防護功能配合使用，可協助客戶確保應用程式的復原能力。您可設定 Pod 整備與存活探查，來決定 Pod 應接收流量的時間。若這些探查失敗，Kubernetes 會將這些 Pod 作為服務目標進行移除，並且不再將流量傳送至 Pod。雖然這很實用，但客戶設定這些運作狀態檢查並不容易，因此若可用區域降級，需要保證這些探查會失敗。ARC 區域轉移功能提供了額外的安全網路，若 Kubernetes 的原生保護不足，它能協助您完全隔離降級的可用區域。此外，區域轉移還為您提供了一種簡便的方式，來測試架構的運作整備與復原能力。

 **可以代表我 AWS 開始區域轉移嗎？** 

是，若您需要以全自動化方式使用 ARC 區域轉移，您可啟用 ARC 區域自動轉移。透過區域自動轉移，您可以依賴 AWS 來監控 EKS 叢集的AZs運作狀態，並在偵測到可用區域受損時自動啟動區域轉移。

 **若我使用此功能，並且工作節點與工作負載未預先擴展，會發生什麼？** 

若您未預先調整擴展，並且在區域轉移期間依賴於佈建額外的節點或 Pod，則有延遲復原的風險。新增節點至 Kubernetes 資料平面的程序需要一些時間，這可能會影響應用程式的即時效能與可用性，在區域受損時尤其如此。另外，若發生區域受損，您可能會遇到運算容量約束，這可能會阻止新的必要節點新增至運作狀態良好的可用區域。

若工作負載未預先擴展，並且分佈到叢集中的所有可用區域，對於僅執行於受影響可用區域中工作節點的應用程式，區域受損可能會影響其可用性。當工作負載在運作狀態不佳的可用區域擁有全部端點的情況下，若要緩解應用程式可用性完全中斷的風險，EKS 設置有失效安全機制，來將流量傳送至受損區域的 Pod 端點。然而，強烈建議您預先擴展應用程式，然後將其分佈到所有可用區域，以便在發生區域問題時確保可用性。

 **若我執行具狀態應用程式，會如何運作？** 

若您正在執行具狀態應用程式，必須依據您的使用案例和架構來評估其容錯能力。若您有作用中/待命架構或模式，可能會有作用中執行個體位於受損的可用區域。若在應用程式層級未啟用待命，執行時可能會遇到應用程式問題。若在運作狀態良好的可用區域啟動新的 Kubernetes Pod，可能會遇到問題，因為這些 Pod 無法連接至已繫結受損可用區域的持續性磁碟區。

 **此功能是否可與 Karpenter 配合使用？** 

EKS 中的 ARC 區域轉移與區域自動轉移目前不提供 Karpenter 支援。若可用區域受損，您可移除運作狀態不佳的可用區域，藉此來調整相關的 Karpenter NodePool 組態，以便僅在其他可用區域啟動新的工作節點。

 **此功能是否可與 EKS Fargate 配合使用？** 

此功能不與 EKS Fargate 配合使用。依預設，若 EKS Fargate 發現區域運作狀態事件，Pod 更偏好在其他可用區域執行。

 **EKS 受管 Kubernetes 控制平面是否會受到影響？** 

否，依預設，Amazon EKS 在多個可用區域內執行和擴展 Kubernetes 控制平面以確保高可用性。ARC 區域轉移與區域自動轉移僅可在 Kubernetes 資料平面運作。

 **此新功能是否有任何關聯成本？** 

您可在 EKS 叢集中使用 ARC 區域轉移與區域自動轉移，並且不會收取額外費用。但是，您會繼續支付佈建執行個體費用，強烈建議您預先擴展 Kubernetes 資料平面，再使用此功能。您應考慮在成本與應用程式可用性間達成平衡。

## 其他資源
<a name="_additional_resources"></a>
+  [區域轉移的運作方式](https://docs.aws.amazon.com/r53recovery/latest/dg/arc-zonal-shift.how-it-works.html) 
+  [ARC 中的區域轉移最佳實務](https://docs.aws.amazon.com/r53recovery/latest/dg/route53-arc-best-practices.zonal-shifts.html#zonalshift.route53-arc-best-practices.zonal-shifts) 
+  [支援區域轉移和區域自動轉移的資源與情境](https://docs.aws.amazon.com/r53recovery/latest/dg/arc-zonal-shift.resource-types.html) 
+  [在 Amazon EKS 上運作彈性工作負載](https://aws.amazon.com/blogs/containers/operating-resilient-workloads-on-amazon-eks) 
+  [透過確定 Pod 優先順序和過度佈建消除 Kubernetes 節點擴展延遲](https://aws.amazon.com/blogs/containers/eliminate-kubernetes-node-scaling-lag-with-pod-priority-and-over-provisioning) 
+  [為高 DNS 流量擴展 CoreDNS Pod](coredns-autoscaling.md) 