

 **協助改進此頁面** 

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

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

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

# Amazon EKS 混合節點概觀
<a name="hybrid-nodes-overview"></a>

透過 *Amazon EKS 混合節點*，您可以使用內部部署和邊緣基礎結構作為 Amazon EKS 叢集中的節點。AWS 負責管理 Amazon EKS 叢集的 AWS 託管 Kubernetes 控制平面，而您可管理在內部部署或邊緣環境中執行的混合節點。這會統一您環境中的 Kubernetes 管理，並將內部部署和邊緣應用程式的 Kubernetes 控制平面管理卸載至 AWS。

Amazon EKS 混合節點可與任何內部部署硬體或虛擬機器搭配使用，將 Amazon EKS 的效率、可擴展性和可用性帶入需要執行應用程式的任何環境。您可以搭配 Amazon EKS 混合節點使用各種 Amazon EKS 功能，包括 Amazon EKS 附加元件、Amazon EKS Pod 身分識別、叢集存取項目、叢集洞察和擴充的 Kubernetes 版本支援。Amazon EKS 混合節點會以原生方式與 AWS Systems Manager、AWS IAM Roles Anywhere、Amazon Managed Service for Prometheus 和 Amazon CloudWatch 等 AWS 服務整合，以進行集中式監控、記錄和身分管理。

使用 Amazon EKS 混合節點時，沒有前期承諾，也沒有最低費用，並且當您混合節點的 vCPU 資源連接到 Amazon EKS 叢集時，會按小時向您收費。如需有關定價的詳細資訊，請參閱 [Amazon EKS 定價](https://aws.amazon.com/eks/pricing/)。

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/tFn9IdlddBw?rel=0/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/tFn9IdlddBw?rel=0)


## 功能
<a name="hybrid-nodes-features"></a>

EKS 混合節點具有下列高階功能：
+  **受管 Kubernetes 控制平面**：AWS 負責管理 EKS 叢集的 AWS 託管 Kubernetes 控制平面，而您可管理在內部部署或邊緣環境中執行的混合節點。這會統一您環境中的 Kubernetes 管理，並將內部部署和邊緣應用程式的 Kubernetes 控制平面管理卸載至 AWS。透過將 Kubernetes 控制平面移動至 AWS，您可以為應用程式節省內部部署容量，並信任 Kubernetes 控制平面會隨工作負載擴展。
+  **一致的 EKS 體驗**：EKS 混合節點支援大多數 EKS 功能，可在內部部署和雲端環境中提供一致的 EKS 體驗，包括 EKS 附加元件、EKS Pod 身分識別、叢集存取項目、叢集洞察、擴充的 Kubernetes 版本支援等。如需 EKS 混合節點支援的 EKS 附加元件的詳細資訊，請參閱 [設定混合節點的附加元件](hybrid-nodes-add-ons.md)。
+  **集中式可觀測性和身分管理**：EKS 混合節點會以原生方式與 AWS Systems Manager、AWS IAM Roles Anywhere、Amazon Managed Service for Prometheus 和 Amazon CloudWatch 等 AWS 服務整合，以進行集中式監控、記錄和身分管理。
+  **爆量至雲端或新增內部部署容量**：單一 EKS 叢集可用於執行混合節點以及 AWS 區域、AWS Local Zones 或 AWS Outpost 中的節點，以便爆量至雲端或向您的 EKS 叢集新增內部部署容量。如需詳細資訊，請參閱[混合模式叢集的考量事項](hybrid-nodes-webhooks.md#hybrid-nodes-considerations-mixed-mode)。
+  **彈性基礎結構**：EKS 混合節點遵循*自有基礎結構*方法，並且與您用於混合節點的基礎結構無關。您可以在實體或虛擬機器以及 x86 和 ARM 架構上執行混合節點，從而能夠跨不同的基礎結構類型移轉在混合節點上執行的內部部署工作負載。
+  **彈性聯網**：使用 EKS 混合節點，EKS 控制平面和混合節點之間的通訊會透過您在叢集建立期間傳遞的 VPC 和子網路路由，而該子網路以 EKS 中用於控制平面到節點聯網的[現有機制](https://docs.aws.amazon.com/eks/latest/best-practices/subnets.html)為建構基礎。這對於將您的內部部署網路連線至 AWS 中的 VPC 的慣用方法而言非常靈活。有多種[記錄的選項](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/network-to-amazon-vpc-connectivity-options.html)可供使用，包括 AWS Site-to-Site VPN、AWS Direct Connect 或您自己的 VPN 解決方案，而您可以選擇最適合您使用案例的方法。

## 限制
<a name="hybrid-node-limits"></a>
+ 每個叢集最多支援 15 個遠端節點網路 CIDR 和 15 個 遠端 Pod 網路 CIDR。

## 考量事項
<a name="hybrid-nodes-general"></a>
+ EKS 混合節點可與新的或現有的 EKS 叢集搭配使用。
+ EKS 混合節點可在所有 AWS 區域中使用，AWS GovCloud (美國) 區域和 AWS 中國區域除外。
+ EKS 混合節點必須在您的內部部署環境與 AWS 之間建立可靠的連線。EKS 混合節點不適用於中斷連線、中斷、間歇性或受限 (DDIL) 環境。如果您在 DDIL 環境中執行，請考慮 [Amazon EKS Anywhere](https://aws.amazon.com/eks/eks-anywhere/)。如需混合節點在網路中斷連線案例中的行為方式的資訊，請參閱 [EKS 混合節點的最佳實務](https://docs.aws.amazon.com/eks/latest/best-practices/hybrid-nodes-network-disconnections.html)。
+ 不支援在雲端基礎結構上執行 EKS 混合節點，包括 AWS 區域、AWS Local Zones、AWS Outpost 或其他雲端。如果您在 Amazon EC2 執行個體上執行混合節點，則需支付混合節點費用。
+ 混合節點的計費從節點加入 EKS 叢集時開始，並在節點從叢集中移除時停止。如果您未使用混合節點，則請務必從 EKS 叢集中將其移除。

## 其他資源
<a name="hybrid-nodes-resources"></a>
+  [https://www.eksworkshop.com/docs/networking/eks-hybrid-nodes/](https://www.eksworkshop.com/docs/networking/eks-hybrid-nodes/)：在示範環境中部署 EKS 混合節點的逐步說明。
+  [https://www.youtube.com/watch?v=ZxC7SkemxvU](https://www.youtube.com/watch?v=ZxC7SkemxvU)：AWS re:Invent 工作階段會向客戶介紹 EKS 混合節點啟動，顯示他們如何在其環境中使用 EKS 混合節點。
+  [https://repost.aws/articles/ARL44xuau6TG2t-JoJ3mJ5Mw/unpacking-the-cluster-networking-for-amazon-eks-hybrid-nodes](https://repost.aws/articles/ARL44xuau6TG2t-JoJ3mJ5Mw/unpacking-the-cluster-networking-for-amazon-eks-hybrid-nodes)：文章說明各種為 EKS 混合節點設定聯網的方法。
+  [https://aws.amazon.com/blogs/containers/run-genai-inference-across-environments-with-amazon-eks-hybrid-nodes/](https://aws.amazon.com/blogs/containers/run-genai-inference-across-environments-with-amazon-eks-hybrid-nodes/)：部落格文章說明如何使用 EKS 混合節點跨環境執行 GenAI 推論。

# 混合節點的先決條件設定
<a name="hybrid-nodes-prereqs"></a>

若要使用 Amazon EKS 混合節點，您必須擁有從內部部署環境往返的私有連線 AWS、具有支援作業系統的裸機伺服器或虛擬機器，以及已設定的 AWS IAM Roles Anywhere 或 AWS Systems Manager (SSM) 混合啟用。您負責在整個混合節點生命週期中管理這些先決條件。
+ 從內部部署環境往返的混合網路連線 AWS 
+ 實體或虛擬機器形式的基礎結構
+ 與混合節點相容的作業系統
+ 內部部署 IAM 憑證提供者已設定

![\[混合節點網路連線。\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-prereq-diagram.png)


## 混合網路連線
<a name="hybrid-nodes-prereqs-connect"></a>

Amazon EKS 控制平面和混合節點之間的通訊會透過您在叢集建立期間傳遞的 VPC 和子網路路由，而該子網路以 Amazon EKS 中用於控制平面到節點聯網的[現有機制](https://aws.github.io/aws-eks-best-practices/networking/subnets/)為建構基礎。有數個[文件記錄的選項](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/network-to-amazon-vpc-connectivity-options.html)可讓您將內部部署環境與您的 VPC 連接，包括 AWS Site-to-Site VPN、 AWS Direct Connect 或您自己的 VPN 連接。如需如何使用這些解決方案進行混合網路連線的詳細資訊，請參閱 [AWS Site-to-Site VPN](https://docs.aws.amazon.com/vpn/latest/s2svpn/VPC_VPN.html) 和 [AWS Direct Connect](https://docs.aws.amazon.com/directconnect/latest/UserGuide/Welcome.html) 使用者指南。

為了獲得最佳體驗，我們建議您擁有至少 100 Mbps 的可靠網路連線能力，以及最多 200 毫秒的混合節點往返延遲。 AWS 這是適用於大多數使用案例的一般指引，但並非嚴格要求。頻寬和延遲需求可能會因混合節點的數量和工作負載特性而有所不同，例如應用程式映像大小、應用程式彈性、監控和記錄組態，以及存取儲存在其他服務中的資料的應用程式相依性 AWS 。建議您在部署到生產環境之前，先使用您自己的應用程式和環境進行測試，以驗證您的聯網設定是否符合工作負載的需求。

## 內部部署網路組態
<a name="hybrid-nodes-prereqs-onprem"></a>

您必須啟用從 Amazon EKS 控制平面到內部部署環境的傳入網路存取，以允許 Amazon EKS 控制平面與在混合節點上執行的 `kubelet` 通訊，並且也可以選擇與在混合節點上執行的 Webhook 通訊。此外，您必須為在其上執行的混合節點和元件啟用傳出網路存取，以便與 Amazon EKS 控制平面通訊。您可以設定此通訊，讓 AWS Direct Connect、 AWS Site-to-Site或您自己的 VPN 連線保持完全私有。

您用於內部部署節點和 Pod 網路的無類別網域間路由 (CIDR) 範圍必須使用 IPv4 RFC-1918 或 CGNAT 地址範圍。您的內部部署路由器必須設定為路由至您的內部部署節點和選用 Pod。如需內部部署網路需求的詳細資訊，請參閱 [內部部署聯網組態](hybrid-nodes-networking.md#hybrid-nodes-networking-on-prem)，包括必須在防火牆和內部部署環境中啟用的必要連接埠和通訊協定的完整清單。

## EKS 叢集組態
<a name="hybrid-nodes-prereqs-cluster"></a>

為了將延遲降至最低，建議您在最接近內部部署或邊緣環境的 AWS 區域中建立 Amazon EKS 叢集。您可以在 Amazon EKS 叢集建立期間，透過兩個 API 欄位傳遞內部部署節點和 Pod CIDR：`RemoteNodeNetwork` 和 `RemotePodNetwork`。您可能需要與您的內部部署網路團隊討論，以識別您的內部部署節點和 Pod CIDR。如果您為 CNI 使用覆蓋網路，節點 CIDR 會從內部部署網路配置，而 Pod CIDR 會從您使用的容器網路介面 (CNI) 配置。根據預設，Cilium 和 Calico 會使用覆蓋網路。

您透過 `RemoteNodeNetwork` 和 `RemotePodNetwork` 欄位設定的內部部署節點和 Pod CIDR 可用於設定 Amazon EKS 控制平面，進而將流量透過 VPC 路由至 `kubelet` 以及在混合節點上執行的 Pod。您的內部部署節點和 Pod CIDR 不能彼此重疊，亦不能與您在叢集建立期間傳遞的 VPC CIDR 或 Amazon EKS 叢集的服務 IPv4 組態重疊。此外，Pod CIDR 對每個 EKS 叢集必須是唯一的，以便您的內部部署路由器可以路由流量。

建議您對 Amazon EKS Kubernetes API 伺服器端點使用公有或私有端點存取。如果您選擇「公有和私有」，Amazon EKS Kubernetes API 伺服器端點一律會解析為在 VPC 外部執行的混合節點的公有 IP，以防止您的混合節點加入叢集。當您使用公有端點存取時，Kubernetes API 伺服器端點會解析為公共 IP，而從混合節點到 Amazon EKS 控制平面的通訊將會透過網際網路路由。當您選擇私有端點存取時，Kubernetes API 伺服器端點會解析為私有 IPs，而且從混合節點到 Amazon EKS 控制平面的通訊將透過您的私有連線連結路由，在大多數情況下是 AWS Direct Connect AWS Site-to-Site VPN。

## VPC 組態
<a name="hybrid-nodes-prereqs-vpc"></a>

您必須為您的內部部署節點，使用其路由表中的路由設定在 Amazon EKS 叢集建立期間傳遞的 VPC，以及使用作為目標的虛擬私有閘道 (VGW) 或傳輸閘道 (TGW) 設定 Pod 網路 (選用)。以下所示為範例。使用內部部署網路的值取代 `REMOTE_NODE_CIDR` 和 `REMOTE_POD_CIDR`。


| 目標 | Target | Description | 
| --- | --- | --- | 
|  10.226.0.0/16  |  本機  |  VPC 內 VPC 路由的本機流量  | 
|  REMOTE\$1NODE\$1CIDR  |  tgw-abcdef123456  |  內部部署節點 CIDR，將流量路由到 TGW  | 
|  REMODE\$1POD\$1CIDR  |  tgw-abcdef123456  |  內部部署 Pod CIDR，將流量路由到 TGW  | 

## 安全群組組態
<a name="hybrid-nodes-prereqs-sg"></a>

當您建立叢集時，Amazon EKS 會建立名稱為 `eks-cluster-sg-<cluster-name>-<uniqueID>` 的安全群組。您無法更改此叢集安全群組的傳入規則，但可以限制傳出規則。您必須將其他安全群組新增至叢集，才能啟用在混合節點上執行的 kubelet 和 Webhook (選用)，進而聯絡 Amazon EKS 控制平面。這個其他安全群組所需的傳入規則如下所示。使用內部部署網路的值取代 `REMOTE_NODE_CIDR` 和 `REMOTE_POD_CIDR`。


| 名稱 | 安全群組規則 ID | IP 版本 | Type | 通訊協定 | 連接埠範圍 | 來源 | 
| --- | --- | --- | --- | --- | --- | --- | 
|  內部部署節點傳入  |  sgr-abcdef123456  |  IPv4  |  HTTPS  |  TCP  |  443  |  REMOTE\$1NODE\$1CIDR  | 
|  內部部署 Pod 傳入  |  sgr-abcdef654321  |  IPv4  |  HTTPS  |  TCP  |  443  |  REMOTE\$1POD\$1CIDR  | 

## 基礎設施
<a name="hybrid-nodes-prereqs-infra"></a>

您必須擁有可用作混合節點的裸機伺服器或虛擬機器。混合節點與底層基礎結構無關，並可支援 x86 和 ARM 架構。Amazon EKS 混合節點遵循「自有基礎結構」方法，而您要負責佈建和管理用於混合節點的裸機伺服器或虛擬機器。雖然沒有嚴格的最低資源需求，但我們建議您為混合節點使用至少具有 1 個 vCPU 和 1GiB RAM 的主機。

## 作業系統
<a name="hybrid-nodes-prereqs-os"></a>

Bottlerocket、Amazon Linux 2023 (AL2023)、Ubuntu 和 RHEL 經過持續驗證，可用作混合節點的節點作業系統。Bottlerocket 僅支援 VMware vSphere 環境中 AWS的 。在 Amazon EC2 外部執行時， AWS 支援計劃不涵蓋 AL2023。 Amazon EC2 AL2023 只能在內部部署虛擬化環境中使用，如需詳細資訊，請參閱 [Amazon Linux 2023 使用者指南](https://docs.aws.amazon.com/linux/al2023/ug/outside-ec2.html)。 AWS 支援與 Ubuntu 和 RHEL 作業系統整合的混合節點，但不支援作業系統本身。

您負責作業系統佈建和管理。在首次測試混合節點時，最簡單的方式是在已佈建的主機上執行 Amazon EKS 混合節點 CLI (`nodeadm`)。對於生產部署，建議您在黃金作業系統映像中包含 `nodeadm`，並將它設定為作為 systemd 服務執行，以便在主機啟動時自動將主機加入 Amazon EKS 叢集。

## 內部部署 IAM 憑證提供者
<a name="hybrid-nodes-prereqs-iam"></a>

Amazon EKS 混合節點使用由 AWS SSM 混合啟用或 IAM Roles Anywhere AWS 佈建的臨時 IAM 登入資料來驗證 Amazon EKS 叢集。您必須將 AWS SSM 混合啟用或 AWS IAM Roles Anywhere 與 Amazon EKS 混合節點 CLI () 搭配使用`nodeadm`。如果您現有的公有金鑰基礎設施 (PKI) 沒有憑證授權機構 (CA) 和內部部署環境的憑證，建議您使用 AWS SSM 混合啟用。如果您有現有的 PKI 和現場部署憑證，請使用 AWS IAM Roles Anywhere。

與在 Amazon EC2 上執行的節點的 [Amazon EKS 節點 IAM 角色](create-node-role.md) 類似，您將建立混合節點 IAM 角色，其中包含將混合節點加入 Amazon EKS 叢集所需的許可。如果您使用的是 AWS IAM Roles Anywhere，請設定信任政策，允許 AWS IAM Roles Anywhere 擔任混合節點 IAM 角色，並使用混合節點 AWS IAM 角色做為可擔任的角色來設定 IAM Roles Anywhere 設定檔。如果您使用的是 AWS SSM，請設定信任政策，允許 AWS SSM 擔任混合節點 IAM 角色，並使用混合節點 IAM 角色建立混合啟用。如需有關如何建立具有必要許可的混合節點 IAM 角色的資訊，請參閱 [準備混合節點的憑證](hybrid-nodes-creds.md)。

# 準備混合節點的聯網
<a name="hybrid-nodes-networking"></a>

本主題概述了您在建立 Amazon EKS 叢集和連接混合節點之前必須設定的聯網設定。本指南假設您已符合使用 [AWS Site-to-Site VPN](https://docs.aws.amazon.com/vpn/latest/s2svpn/SetUpVPNConnections.html)、[AWS Direct Connect](https://docs.aws.amazon.com/directconnect/latest/UserGuide/Welcome.html) 或您自己的 VPN 解決方案實現混合網路連線的先決條件要求。

![\[混合節點網路連線。\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-prereq-diagram.png)


## 內部部署聯網組態
<a name="hybrid-nodes-networking-on-prem"></a>

### 最低網路需求
<a name="hybrid-nodes-networking-min-reqs"></a>

為了獲得最佳體驗，我們建議您擁有至少 100 Mbps 的可靠網路連線能力，以及最多 200 毫秒的混合節點往返延遲。 AWS 這是適用於大多數使用案例的一般指引，但並非嚴格要求。頻寬和延遲需求可能會因混合節點的數量和工作負載特性而有所不同，例如應用程式映像大小、應用程式彈性、監控和記錄組態，以及存取儲存在其他服務中的資料的應用程式相依性 AWS 。建議您在部署到生產環境之前，先使用您自己的應用程式和環境進行測試，以驗證您的聯網設定是否符合工作負載的需求。

### 內部部署節點和 Pod CIDR
<a name="hybrid-nodes-networking-on-prem-cidrs"></a>

識別將用於混合節點及其上執行的工作負載的節點和 Pod CIDR。如果您為 CNI 使用覆蓋網路，節點 CIDR 會從內部部署網路配置，而 Pod CIDR 會從您的容器網路介面 (CNI) 配置。當您使用 `RemoteNodeNetwork` 和 `RemotePodNetwork` 欄位建立 EKS 叢集時，您可以將內部部署節點 CIDR 和 Pod CIDR 作為輸入進行傳遞。您的內部部署節點 CIDR 必須在內部部署網路上可路由。如需內部部署 Pod CIDR 可路由性的資訊，請參閱下一節。

內部部署節點和 Pod CIDR 區塊必須符合下列要求：

1. 在下列其中一個 `IPv4` RFC-1918 範圍內：`10.0.0.0/8`、 `172.16.0.0/12`或 `192.168.0.0/16` ，或在 RFC 6598 定義的 CGNAT 範圍內：`100.64.0.0/10`。

1. EKS 叢集的 VPC CIDR 或您的 Kubernetes Service `IPv4` CIDR 不會彼此重疊。

### 內部部署 Pod 網路路由
<a name="hybrid-nodes-networking-on-prem-pod-routing"></a>

使用 EKS 混合節點時，我們通常會建議您將內部部署網路上的內部部署 Pod CIDR 設定為可路由，以便啟用雲端和內部部署環境之間的完整叢集通訊和功能。

 **可路由的 Pod 網路** 

如果您能夠將內部部署網路上的 Pod 網路設定為可路由，請遵循下列指引。

1. 設定以下 `RemotePodNetwork` 欄位：使用內部部署 Pod CIDR 的 EKS 叢集、使用內部部署 Pod CIDR 的 VPC 路由表，以及使用內部部署 Pod CIDR 的 EKS 叢集安全群組。

1. 您可以使用多種技術，讓您的內部部署 Pod CIDR 在內部部署網路上可路由，包括邊界閘道協定 (BGP)、靜態路由或其他自訂路由解決方案。BGP 是建議的解決方案，因為它比需要自訂或手動路由組態的替代解決方案更具可擴展性且更容易管理。 AWS 支援 Cilium 和 Calico 的 BGP 功能來公告 Pod CIDRs，如需詳細資訊，請參閱 [可路由的遠端 Pod CIDR](hybrid-nodes-concepts-kubernetes.md#hybrid-nodes-concepts-k8s-pod-cidrs) [設定混合節點的 CNI](hybrid-nodes-cni.md)和 。

1. Webhooks 可以在混合節點上執行，因為 EKS 控制平面能夠與指派給 Webhook 的 Pod IP 位址進行通訊。

1. 在雲端節點上執行的工作負載能夠直接與同一 EKS 叢集中混合節點上執行的工作負載進行通訊。

1.  AWS 其他服務，例如 AWS Application Load Balancer 和 Amazon Managed Service for Prometheus，能夠與混合節點上執行的工作負載進行通訊，以平衡網路流量和湊集 Pod 指標。

 **不可路由的 Pod 網路** 

如果您*不*能將內部部署網路上的 Pod 網路設定為可路由，請遵循下列指引。

1. Webhook 無法在混合節點上執行，因為 Webhook 需要從 EKS 控制平面連線至指派給 Webhook 的 Pod IP 位址。在此情況下，我們建議您在與混合節點相同的 EKS 叢集中的雲端節點上執行 Webhook，如需詳細資訊，請參閱 [設定混合節點的 Webhook](hybrid-nodes-webhooks.md)。

1. 當對雲端節點使用 VPC CNI 及對混合節點使用 Cilium 或 Calico 時，雲端節點上執行的工作負載將不能直接與混合節點上執行的工作負載進行通訊。

1. 使用服務流量分佈，以將流量保持在其來源區域的本機。如需有關服務流量分佈的詳細資訊，請參閱 [設定服務流量分佈](hybrid-nodes-webhooks.md#hybrid-nodes-mixed-service-traffic-distribution)。

1. 將 CNI 設定為在 Pod 流量離開內部部署主機時，使用輸出偽裝或網路位址轉譯 (NAT)。在 Cilium 中，其預設為啟用。Calico 需要將 `natOutgoing` 設定為 `true`。

1. Application AWS Load Balancer 和 Amazon Managed Service for Prometheus 等 AWS 其他服務無法與在混合節點上執行的工作負載通訊。

### 混合節點安裝和升級期間所需的存取
<a name="hybrid-nodes-networking-access-reqs"></a>

在安裝過程中 (即您在主機上安裝混合節點相依性時)，您必須可以存取下列網域。當您建置作業系統映像時，可以執行此程序一次；另外在執行時期，也可在每個主機上執行此程序。這包括初始安裝以及升級混合節點的 Kubernetes 版本時。

某些套件是使用作業系統的預設套件管理工具進行安裝的。對於 AL2023 和 RHEL，`yum` 命令可用於安裝 `containerd`、`ca-certificates`、`iptables` 和 `amazon-ssm-agent`。對於 Ubuntu，`apt` 可用於安裝 `containerd`、`ca-certificates` 和 `iptables`，而 `snap` 可用於安裝 `amazon-ssm-agent`。


| 元件 | URL | 通訊協定 | 站點 | 
| --- | --- | --- | --- | 
|  EKS 節點成品 (S3)  |  https://hybrid-assets.eks.amazonaws.com  |  HTTPS  |  443  | 
|   [EKS 服務端點](https://docs.aws.amazon.com/general/latest/gr/eks.html)   |  https://eks.*region*.amazonaws.com  |  HTTPS  |  443  | 
|   [ECR 服務端點](https://docs.aws.amazon.com/general/latest/gr/ecr.html)   |  https://api.ecr.*region*.amazonaws.com  |  HTTPS  |  443  | 
|  EKS ECR 端點  |  請參閱 [檢視 Amazon EKS 附加元件的 Amazon 容器映像登錄檔](add-ons-images.md) 了解區域端點。  |  HTTPS  |  443  | 
|  SSM 二進位檔端點 1   |  https://amazon-ssm-*region*.s3.*region*.amazonaws.com  |  HTTPS  |  443  | 
|   [SSM 服務端點](https://docs.aws.amazon.com/general/latest/gr/ssm.html) 1   |  https://ssm.*region*.amazonaws.com  |  HTTPS  |  443  | 
|  IAM Anywhere 二進位檔端點 2   |  https://rolesanywhere.amazonaws.com  |  HTTPS  |  443  | 
|   [IAM Anywhere 服務端點](https://docs.aws.amazon.com/general/latest/gr/rolesanywhere.html) 2   |  https://rolesanywhere.*region*.amazonaws.com  |  HTTPS  |  443  | 
|  作業系統套件管理工具端點  |  套件儲存庫端點是作業系統特定的，並且可能因地理區域而有所不同。  |  HTTPS  |  443  | 

**注意**  
 1 只有在您為內部部署 AWS IAM 憑證提供者使用 AWS SSM 混合啟用時，才需要存取 SSM 端點。  
 2 只有在您為內部部署 AWS IAM 憑證提供者使用 AWS IAM Roles Anywhere 時，才需要存取 IAM 端點。

### 持續叢集操作所需的存取
<a name="hybrid-nodes-networking-access-reqs-ongoing"></a>

持續叢集操作需要為您的內部部署防火牆提供下列網路存取。

**重要**  
視您選擇的 CNI 而定，您需要為 CNI 連接埠設定其他網路存取規則。如需詳細資訊，請參閱 [Cilium 文件](https://docs.cilium.io/en/stable/operations/system_requirements/#firewall-rules)和 [Calico 文件](https://docs.tigera.io/calico/latest/getting-started/kubernetes/requirements#network-requirements)。


| Type | 通訊協定 | Direction | 站點 | 來源 | 目標 | Usage | 
| --- | --- | --- | --- | --- | --- | --- | 
|  HTTPS  |  TCP  |  傳出  |  443  |  遠端節點 CIDR  |  EKS 叢集 IP 1   |  kubelet 到 Kubernetes API 伺服器  | 
|  HTTPS  |  TCP  |  傳出  |  443  |  遠端 Pod CIDR  |  EKS 叢集 IP 1   |  Pod 到 Kubernetes API 伺服器  | 
|  HTTPS  |  TCP  |  傳出  |  443  |  遠端節點 CIDR  |   [SSM 服務端點](https://docs.aws.amazon.com/general/latest/gr/ssm.html)   |  SSM 混合啟用憑證重新整理和 SSM 活動訊號，每 5 分鐘一次  | 
|  HTTPS  |  TCP  |  傳出  |  443  |  遠端節點 CIDR  |   [IAM Anywhere 服務端點](https://docs.aws.amazon.com/general/latest/gr/rolesanywhere.html)   |  IAM Roles Anywhere 憑證重新整理  | 
|  HTTPS  |  TCP  |  傳出  |  443  |  遠端 Pod CIDR  |   [STS 區域端點](https://docs.aws.amazon.com/general/latest/gr/sts.html)   |  Pod 到 STS 端點，僅 IRSA 需要  | 
|  HTTPS  |  TCP  |  傳出  |  443  |  遠端節點 CIDR  |   [Amazon EKS Auth 服務端點](https://docs.aws.amazon.com/general/latest/gr/eks.html)   |  節點至 Amazon EKS 身分驗證端點，僅 Amazon EKS Pod 身分識別需要  | 
|  HTTPS  |  TCP  |  傳入  |  10250  |  EKS 叢集 IP 1   |  遠端節點 CIDR  |  Kubernetes API 伺服器到 kubelet  | 
|  HTTPS  |  TCP  |  傳入  |  Webhook 連接埠  |  EKS 叢集 IP 1   |  遠端 Pod CIDR  |  Kubernetes API 伺服器到 Webhook  | 
|  HTTPS  |  TCP/UDP  |  傳入，傳出  |  53  |  遠端 Pod CIDR  |  遠端 Pod CIDR  |  Pod 到 CoreDNS。如果您在雲端中執行至少 1 個 CoreDNS 複本，則必須允許 DNS 流量通往執行 CoreDNS 的 VPC。  | 
|  使用者定義  |  使用者定義  |  傳入，傳出  |  應用程式連接埠  |  遠端 Pod CIDR  |  遠端 Pod CIDR  |  Pod 到 Pod  | 

**注意**  
 1 EKS 叢集的 IP。請參閱以下有關 Amazon EKS 彈性網路介面的章節。

### Amazon EKS 網路介面
<a name="hybrid-nodes-networking-eks-network-interfaces"></a>

Amazon EKS 會將網路介面連接到您在叢集建立期間傳遞的 VPC 中的子網路，以啟用 EKS 控制平面與 VPC 之間的通訊。Amazon EKS 建立的網路界面可在 Amazon EC2 主控台或使用 AWS CLI 建立叢集後找到。在 EKS 叢集上套用變更時，會刪除原始網路介面並建立新的網路介面，例如 Kubernetes 版本升級。您可對叢集建立期間傳遞的子網路使用受限子網路大小以限制 Amazon EKS 網路介面的 IP 範圍，這樣您就能更輕鬆地設定內部部署防火牆，以允許與這組已知的受限 IP 建立傳入/傳出連線。若要控制在其中建立的子網路網路介面，可以限制建立叢集時指定的子網路數量，或在建立叢集後您可以更新子網路。

Amazon EKS 佈建的網路介面具有格式 `Amazon EKS your-cluster-name ` 的說明。如需可用來尋找 Amazon AWS EKS 佈建之網路介面 IP 地址的 CLI 命令，請參閱下列範例。使用您在叢集建立期間傳遞的 VPC 的 ID 取代 `VPC_ID`。

```
aws ec2 describe-network-interfaces \
--query 'NetworkInterfaces[?(VpcId == VPC_ID && contains(Description,Amazon EKS))].PrivateIpAddress'
```

## AWS VPC 和子網路設定
<a name="hybrid-nodes-networking-vpc"></a>

Amazon EKS 的現有 [VPC 和子網路要求](network-reqs.md)適用於具有混合節點的叢集。此外，您的 VPC CIDR 無法與內部部署節點和 Pod CIDR 重疊。您必須在 VPC 路由表中為內部部署節點設定路由，也可選擇性地為 Pod CIDR 設定路由。必須設定這些路由，以將流量路由到您用於混合網路連線的閘道，該閘道通常是虛擬私有閘道 (VGW) 或傳輸閘道 (TGW)。如果您使用 TGW 或 VGW 將 VPC 連接到內部部署環境，則必須為您的 VPC 建立 TGW 或 VGW 附件。您的 VPC 必須支援 DNS 主機名稱和 DNS 解析。

下列步驟使用 AWS CLI。您也可以在 中 AWS 管理主控台 或透過 AWS CloudFormation、 AWS CDK 或 Terraform 等其他界面建立這些資源。

### 步驟 1：建立 VPC
<a name="_step_1_create_vpc"></a>

1. 執行下列命令以建立 VPC。將 VPC\$1CIDR 取代為 RFC 1918 （私有）、CGNAT (RFC 6598) 或非 RFC 1918/非 CGNAT （公有） （例如 10.0.0.0/16) 的 IPv4 CIDR 範圍。注意：根據預設，已為 VPC 啟用 DNS 解析 (這是 EKS 要求)。

   ```
   aws ec2 create-vpc --cidr-block VPC_CIDR
   ```

1. 為您的 VPC 啟用 DNS 主機名稱。請注意，根據預設，已為 VPC 啟用 DNS 解析。使用您在上一個步驟中建立的 VPC 的 ID 取代 `VPC_ID`。

   ```
   aws ec2 modify-vpc-attribute --vpc-id VPC_ID --enable-dns-hostnames
   ```

### 步驟 2：建立子網路
<a name="_step_2_create_subnets"></a>

建立至少 2 個子網路。Amazon EKS 會將這些子網路用於叢集網路介面。如需詳細資訊，請參閱[子網路要求和考量事項](network-reqs.md#network-requirements-subnets)。

1. 您可以使用下列命令尋找 AWS 區域的可用區域。使用您的區域取代 `us-west-2`。

   ```
   aws ec2 describe-availability-zones \
        --query 'AvailabilityZones[?(RegionName == us-west-2)].ZoneName'
   ```

1. 建立子網。使用 VPC 的 ID 取代 `VPC_ID`。使用您子網路的 CIDR 區塊取代 `SUBNET_CIDR` (例如 10.0.1.0/24)。使用將建立子網路的可用區域取代 `AZ` (例如 us-west-2a)。您建立的子網路必須至少位於 2 個不同的可用區域。

   ```
   aws ec2 create-subnet \
       --vpc-id VPC_ID \
       --cidr-block SUBNET_CIDR \
       --availability-zone AZ
   ```

### （選用） 步驟 3：使用 Amazon VPC Transit Gateway (TGW) 或 AWS Direct Connect 虛擬私有閘道 (VGW) 連接 VPC
<a name="optional_step_3_attach_vpc_with_amazon_vpc_transit_gateway_tgw_or_shared_aws_direct_connect_virtual_private_gateway_vgw"></a>

如果您使用的是 TGW 或 VGW，則請將 VPC 連接到 TGW 或 VGW。如需詳細資訊，請參閱 [Amazon VPC Transit Gateways 中的 Amazon VPC 附件](https://docs.aws.amazon.com/vpc/latest/tgw/tgw-vpc-attachments.html)或 [AWS Direct Connect 虛擬私有閘道關聯](https://docs.aws.amazon.com/vpn/latest/s2svpn/how_it_works.html#VPNGateway)。

 **轉換閘道** 

執行下列命令以連接 Transit Gateway。使用 VPC 的 ID 取代 `VPC_ID`。使用您在上一個步驟中建立的子網路的 ID 取代 `SUBNET_ID1` 和 `SUBNET_ID2`。使用您 TGW 的 ID 取代 `TGW_ID`。

```
aws ec2 create-transit-gateway-vpc-attachment \
    --vpc-id VPC_ID \
    --subnet-ids SUBNET_ID1 SUBNET_ID2 \
    --transit-gateway-id TGW_ID
```

 **虛擬私有閘道** 

執行下列命令以連接 Transit Gateway。使用您 VGW 的 ID 取代 `VPN_ID`。使用 VPC 的 ID 取代 `VPC_ID`。

```
aws ec2 attach-vpn-gateway \
    --vpn-gateway-id VPN_ID \
    --vpc-id VPC_ID
```

### (選用) 步驟 4：建立路由表
<a name="_optional_step_4_create_route_table"></a>

您可以修改 VPC 的主要路由表，也可以建立自訂路由表。下列步驟會建立自訂路由表，其中包含通往內部部署節點和 Pod CIDR 的路由。如需詳細資訊，請參閱[子網路路由表](https://docs.aws.amazon.com/vpc/latest/userguide/subnet-route-tables.html)。使用 VPC 的 ID 取代 `VPC_ID`。

```
aws ec2 create-route-table --vpc-id VPC_ID
```

### 步驟 5：建立內部部署節點和 Pod 的路由
<a name="_step_5_create_routes_for_on_premises_nodes_and_pods"></a>

在路由表中，為每個內部部署遠端節點建立路由。您可以修改 VPC 的主要路由表，也可以使用您在上一個步驟中建立的自訂路由表。

以下範例顯示如何為您的內部部署節點和 Pod CIDR 建立路由。在範例中，傳輸閘道 (TGW) 可用於連接 VPC 與內部部署環境。如果您有多個內部部署節點和 Pod CIDR，請對每個 CIDR 重複這些步驟。
+ 如果您使用的是網際網路閘道或虛擬私有閘道 (VGW)，則請使用 `--gateway-id` 取代 `--transit-gateway-id`。
+ 使用您在上一個步驟中建立的路由表的 ID 取代 `RT_ID`。
+ 使用您將用於混合節點的 CIDR 範圍取代 `REMOTE_NODE_CIDR`。
+ 使用您將用於為混合節點上執行的 Pod 的 CIDR 範圍取代 `REMOTE_POD_CIDR`。Pod CIDR 範圍會對應至容器聯網介面 (CNI) 組態，而此組態最常使用覆蓋網路內部部署。如需詳細資訊，請參閱[設定混合節點的 CNI](hybrid-nodes-cni.md)。
+ 使用您 TGW 的 ID 取代 `TGW_ID`。

 **遠端節點網路** 

```
aws ec2 create-route \
    --route-table-id RT_ID \
    --destination-cidr-block REMOTE_NODE_CIDR \
    --transit-gateway-id TGW_ID
```

 **遠端 Pod 網路** 

```
aws ec2 create-route \
    --route-table-id RT_ID \
    --destination-cidr-block REMOTE_POD_CIDR \
    --transit-gateway-id TGW_ID
```

### (選用) 步驟 6：將子網路和路由表建立關聯
<a name="_optional_step_6_associate_subnets_with_route_table"></a>

如果您在上一個步驟中建立了自訂路由表，請將您在上一個步驟中建立的每個子網路與您的自訂路由表建立關聯。如果您要修改 VPC 主要路由表，子網路會自動與 VPC 的主要路由表建立關聯，並且您可以略過此步驟。

對先前步驟中建立的每個子網路，執行下列命令。使用您在上一個步驟中建立的路由表取代 `RT_ID`。使用子網路的 ID 取代 `SUBNET_ID`。

```
aws ec2 associate-route-table --route-table-id RT_ID --subnet-id SUBNET_ID
```

## 叢集安全群組組態
<a name="hybrid-nodes-networking-cluster-sg"></a>

持續叢集操作需要為 EKS 叢集安全群組提供下列存取。當您使用設定的遠端節點和 Pod 網路建立或更新叢集時，Amazon EKS 會自動為混合節點建立必要的**傳入**安全群組規則。由於根據預設，安全群組允許所有**傳出**流量，Amazon EKS 不會自動修改混合節點的叢集安全群組的**傳出**規則。如果您想要自訂叢集安全群組，您可以根據下表中的規則限制流量。


| Type | 通訊協定 | Direction | 站點 | 來源 | 目標 | Usage | 
| --- | --- | --- | --- | --- | --- | --- | 
|  HTTPS  |  TCP  |  傳入  |  443  |  遠端節點 CIDR  |  N/A  |  kubelet 到 Kubernetes API 伺服器  | 
|  HTTPS  |  TCP  |  傳入  |  443  |  遠端 Pod CIDR  |  N/A  |  Pod，當 CNI 未針對 Pod 流量使用 NAT 時，需要存取 K8s API 伺服器。  | 
|  HTTPS  |  TCP  |  傳出  |  10250  |  N/A  |  遠端節點 CIDR  |  Kubernetes API 伺服器到 Kubelet  | 
|  HTTPS  |  TCP  |  傳出  |  Webhook 連接埠  |  N/A  |  遠端 Pod CIDR  |  Kubernetes API 伺服器到 Webhook (如果在混合節點上執行 Webhooks on hybrid nodes)  | 

**重要**  
 **安全群組規則限制**：根據預設，Amazon EC2 安全群組最多有 60 條傳入規則。如果您的叢集安全群組接近此限制，則安全群組傳入規則可能不適用。在此情況下，可能需要在缺少的傳入規則中手動進行新增。  
 **CIDR 清除責任**：如果您從 EKS 叢集中移除遠端節點或 Pod 網路，EKS 不會自動移除對應的安全群組規則。您負責從安全群組規則中手動移除未使用的遠端節點或 Pod 網路。

如需有關 Amazon EKS 建立的叢集安全群組的詳細資訊，請參閱 [檢視叢集的 Amazon EKS 安全群組要求](sec-group-reqs.md)。

### (選用) 手動安全群組組態
<a name="_optional_manual_security_group_configuration"></a>

如果您需要建立其他安全群組或修改自動建立的規則，您可以使用下列命令作為參考。根據預設，以下命令會建立一個允許所有傳出存取的安全群組。您可以將傳出存取限制為僅包含上述規則。如果您正在考慮限制傳出規則，建議您先徹底測試所有應用程式和 Pod 連線，之後再將變更的規則套用到生產叢集。
+ 在第一個命令中，使用您安全群組的名稱取代 `SG_NAME`
+ 在第一個命令中，使用您在上一個步驟中建立的 VPC 的 ID 取代 `VPC_ID`
+ 在第二個命令中，使用您在第一個命令中建立的安全群組的 ID 取代 `SG_ID`
+ 在第二個命令中，使用混合節點和內部部署網路的值取代 `REMOTE_NODE_CIDR` 和 `REMOTE_POD_CIDR`。

```
aws ec2 create-security-group \
    --group-name SG_NAME \
    --description "security group for hybrid nodes" \
    --vpc-id VPC_ID
```

```
aws ec2 authorize-security-group-ingress \
    --group-id SG_ID \
    --ip-permissions '[{"IpProtocol": "tcp", "FromPort": 443, "ToPort": 443, "IpRanges": [{"CidrIp": "REMOTE_NODE_CIDR"}, {"CidrIp": "REMOTE_POD_CIDR"}]}]'
```

# 準備混合節點的作業系統
<a name="hybrid-nodes-os"></a>

Bottlerocket、Amazon Linux 2023 (AL2023)、Ubuntu 和 RHEL 經過持續驗證，可用作混合節點的節點作業系統。Bottlerocket 僅支援 VMware vSphere 環境中 AWS的 。在 Amazon EC2 外部執行時， AWS 支援計劃不涵蓋 AL2023。 Amazon EC2 AL2023 只能在內部部署虛擬化環境中使用，如需詳細資訊，請參閱 [Amazon Linux 2023 使用者指南](https://docs.aws.amazon.com/linux/al2023/ug/outside-ec2.html)。 AWS 支援與 Ubuntu 和 RHEL 作業系統整合的混合節點，但不支援作業系統本身。

您負責作業系統佈建和管理。在首次測試混合節點時，最簡單的方式是在已佈建的主機上執行 Amazon EKS 混合節點 CLI (`nodeadm`)。對於生產部署，建議您在作業系統映像中包含 `nodeadm`，並將它設定為作為 systemd 服務執行，以便在主機啟動時自動將主機加入 Amazon EKS 叢集。如果您在 vSphere 上使用 Bottlerocket 作為節點作業系統，則不需要使用 `nodeadm`，因為 Bottlerocket 已包含混合節點所需的相依性，並且會在主機啟動時自動連接至您設定的叢集。

## 版本相容性
<a name="_version_compatibility"></a>

下表所列的作業系統版本代表相容且經過驗證可用作混合節點的節點作業系統。如果您使用的是不包含在此資料表中的其他作業系統變體或版本，則 AWS Support 不會涵蓋混合節點與作業系統變體或版本的相容性。混合節點與底層基礎結構無關，並可支援 x86 和 ARM 架構。


| 作業系統 | 版本 | 
| --- | --- | 
|  Amazon Linux  |  Amazon Linux 2023 (AL2023)  | 
|  Bottlerocket  |  執行 Kubernetes v1.28 及更新版本的 v1.37.0 及更新版本的 VMware 變體  | 
|  Ubuntu  |  Ubuntu 20.04、Ubuntu 22.04、Ubuntu 24.04  | 
|  Red Hat Enterprise Linux  |  RHEL 8、RHEL 9  | 

## 作業系統考量事項
<a name="_operating_system_considerations"></a>

### 一般
<a name="_general"></a>
+ Amazon EKS 混合節點 CLI (`nodeadm`) 可用於簡化混合節點元件和相依性的安裝和組態。在作業系統映像建置管道期間或每個內部部署主機的執行時期，您可以執行 `nodeadm install` 程序。如需有關 `nodeadm` 安裝的元件的詳細資訊，請參閱 [混合節點 `nodeadm` 參考](hybrid-nodes-nodeadm.md)。
+ 如果您在內部部署環境中使用代理連線至網際網路，安裝和升級程序需要額外的作業系統組態，才能將套件管理工具設定為使用代理。如需說明，請參閱 [設定混合節點的代理](hybrid-nodes-proxy.md)。

### Bottlerocket
<a name="_bottlerocket"></a>
+ 連接 Bottlerocket 節點的步驟和工具與其他作業系統的步驟不同，並會在 [使用 Bottlerocket 連接混合節點](hybrid-nodes-bottlerocket.md) 中單獨介紹，而不會涵蓋在 [連接混合節點](hybrid-nodes-join.md) 的步驟中。
+ Bottlerocket 的步驟不會使用混合節點 CLI 工具 `nodeadm`。
+ EKS 混合節點僅支援 Bottlerocket 版本 1.37.0 及更新版本的 VMware 變體。Bottlerocket 的 VMware 變體適用於 Kubernetes 版本 1.28 及更新版本。不支援[其他 Bottlerocket 變體](https://bottlerocket.dev/en/os/1.36.x/concepts/variants)作為混合節點作業系統。注意： Bottlerocket 的 VMware 變體僅適用於 x86\$164 架構。

### Containerd
<a name="_containerd"></a>
+ Containerd 是標準 Kubernetes 容器執行時期，也是混合節點以及所有 Amazon EKS 節點運算類型的相依性。Amazon EKS 混合節點 CLI (`nodeadm`) 會嘗試在 `nodeadm install` 程序期間安裝 containerd。您可以使用 `--containerd-source` 命令列選項，在 `nodeadm install` 執行時期設定 containerd 安裝。有效選項為 `none`、`distro` 和 `docker`。如果您使用的是 RHEL，則 `distro` 不是有效選項，並且您可以將 `nodeadm` 設定為從 Docker 的儲存庫安裝 containerd 建置，也可以手動安裝 containerd。使用 AL2023 或 Ubuntu 時，`nodeadm` 預設為從作業系統分佈中安裝 containerd。如果您不希望 nodeadm 安裝 containerd，則請使用 `--containerd-source none` 選項。

### Ubuntu
<a name="_ubuntu"></a>
+ 如果您使用的是 Ubuntu 24.04，您可能需要更新您的 containerd 版本，或變更 AppArmor 組態以採用允許 Pod 正確終止的修正，請參閱 [Ubuntu \$12065423](https://bugs.launchpad.net/ubuntu/+source/containerd-app/\+bug/2065423)。需要重新啟動才能將變更套用至 AppArmor 設定檔。Ubuntu 24.04 的最新版本在其套件管理工具中具有更新的 containerd 版本，且帶有修正 (containerd 版本 1.7.19\$1)。

### ARM
<a name="_arm"></a>
+ 如果您使用的是 ARM 硬體，則需要具有密碼編譯延伸功能的 ARMv8.2 相容處理器 (ARMv8.2\$1crypto)，才能執行 EKS kube-proxy 附加元件的版本 1.31 及更新版本。Raspberry Pi 5 之前的所有 Raspberry Pi 系統，以及 Cortex-A72 型處理器皆不符合此要求。解決方法是：您可以繼續使用 EKS kube-proxy 附加元件的版本 1.30，直到 2026 年 7 月延長支援結束為止，請參閱 [Kubernetes 發布行事曆](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)，或使用來自上游的自訂 kube-proxy 映像。
+ kube-proxy 日誌中的下列錯誤訊息會指出這種不相容性：

```
Fatal glibc error: This version of Amazon Linux requires a newer ARM64 processor compliant with at least ARM architecture 8.2-a with Cryptographic extensions. On EC2 this is Graviton 2 or later.
```

## 建置作業系統映像
<a name="_building_operating_system_images"></a>

Amazon EKS 提供[範例 Packer 範本](https://github.com/aws/eks-hybrid/tree/main/example/packer)，您可使用這些範本來建立包含 `nodeadm` 的作業系統映像，並將其設定為在主機啟動時執行。建議執行此程序，以避免在每個主機上個別提取混合節點相依性，並自動化混合節點引導程序。您可以搭配 Ubuntu 22.04、Ubuntu 24.04、RHEL 8 或 RHEL 9 ISO 映像使用範例 Packer 範本，並且可以使用這些格式輸出映像：OVA、Qcow2 或 raw。

### 先決條件
<a name="_prerequisites"></a>

使用範例 Packer 範本之前，您必須在執行 Packer 的機器上安裝下列內容。
+ Packer 版本 1.11.0 或更新版本。如需有關安裝 Packer 的指示，請參閱 Packer 文件中的[安裝 Packer](https://developer.hashicorp.com/packer/tutorials/docker-get-started/get-started-install-cli)。
+ 如果建置 OVA，則為 VMware vSphere 外掛程式 1.4.0 或更新版本
+ 如果是建置 `Qcow2` 或原始映像，則為 QEMU 外掛程式版本 1.x

### 設定環境變數
<a name="_set_environment_variables"></a>

在執行 Packer 建置之前，請在執行 Packer 的機器上設定下列環境變數。

 **一般** 

必須設定下列環境變數，才能運用所有作業系統和輸出格式建置映像。


| 環境變數 | Type | 說明 | 
| --- | --- | --- | 
|  PKR\$1SSH\$1PASSWORD  |  String  |  Packer 會在佈建時使用 `ssh_username` 和 `ssh_password` 變數，將 SSH 傳送至建立的機器。這需要與在個別作業系統的啟動或使用者資料檔案中建立初始使用者的密碼相符。預設值設定為 "builder" 或 "ubuntu"，視作業系統而定。設定密碼時，請務必在對應的 `ks.cfg` 或 `user-data` 檔案中對其進行變更，以保持相符。  | 
|  ISO\$1URL  |  String  |  要使用的 ISO 的 URL。可以是從伺服器下載的 Web 連結，也可以是本機檔案的絕對路徑  | 
|  ISO\$1CHECKSUM  |  String  |  所提供 ISO 的關聯檢查總和。  | 
|  CREDENTIAL\$1PROVIDER  |  String  |  混合節點的憑證提供者。對於 SSM 混合啟用，有效值為 `ssm` (預設)，而對於 IAM Roles Anywhere，有效值為 `iam`  | 
|  K8S\$1VERSION  |  String  |  混合節點的 Kubernetes 版本 (例如 `1.31`)。如需支援的 Kubernetes 版本，請參閱 [Amazon EKS 支援的版本](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)。  | 
|  NODEADM\$1ARCH  |  String  |  `nodeadm install` 的架構。選取 `amd` 或 `arm`。  | 

 **RHEL** 

如果您使用的是 RHEL，則必須設定下列環境變數。


| 環境變數 | Type | 說明 | 
| --- | --- | --- | 
|  RH\$1USERNAME  |  String  |  RHEL 訂閱管理員使用者名稱  | 
|  RH\$1PASSWORD  |  String  |  RHEL 訂閱管理員密碼  | 
|  RHEL\$1VERSION  |  String  |  要使用的 Rhel iso 版本。有效值為 `8` 或 `9`。  | 

 **Ubuntu** 

不需要 Ubuntu 專屬環境變數。

 **vSphere** 

如果您要建置 VMware vSphere OVA，則必須設定下列環境變數。


| 環境變數 | Type | 說明 | 
| --- | --- | --- | 
|  VSPHERE\$1SERVER  |  String  |  vSphere 伺服器地址  | 
|  VSPHERE\$1USER  |  String  |  vSphere 使用者名稱  | 
|  VSPHERE\$1PASSWORD  |  String  |  vSphere 密碼  | 
|  VSPHERE\$1DATACENTER  |  String  |  vSphere 資料中心名稱  | 
|  VSPHERE\$1CLUSTER  |  String  |  vSphere 叢集名稱  | 
|  VSPHERE\$1DATASTORE  |  String  |  vSphere 資料儲存名稱  | 
|  VSPHERE\$1NETWORK  |  String  |  vSphere 網路名稱  | 
|  VSPHERE\$1OUTPUT\$1FOLDER  |  String  |  範本的 vSphere 輸出資料夾  | 

 **QEMU** 


| 環境變數 | Type | 說明 | 
| --- | --- | --- | 
|  PACKER\$1OUTPUT\$1FORMAT  |  String  |  QEMU 建置器的輸出格式。有效值為 `qcow2` 和 `raw`。  | 

 **驗證範本** 

執行建置之前，請設定環境變數，然後使用下列命令驗證範本。如果您對範本使用不同的名稱，請取代 `template.pkr.hcl`。

```
packer validate template.pkr.hcl
```

### 建置映像
<a name="_build_images"></a>

使用下列命令建置映像，並使用 `-only` 旗標來指定映像的目標和作業系統。如果您對範本使用不同的名稱，請取代 `template.pkr.hcl`。

 **vSphere OVA** 

**注意**  
如果您搭配 vSphere 使用 RHEL，您需要將啟動檔案轉換為 OEMDRV 映像，並將其作為 ISO 傳遞以進行引導。如需詳細資訊，請參閱 EKS 混合節點 GitHub 儲存庫中的 [Packer Readme](https://github.com/aws/eks-hybrid/tree/main/example/packer#utilizing-rhel-with-vsphere)。

 **Ubuntu 22.04 OVA** 

```
packer build -only=general-build.vsphere-iso.ubuntu22 template.pkr.hcl
```

 **Ubuntu 24.04 OVA** 

```
packer build -only=general-build.vsphere-iso.ubuntu24 template.pkr.hcl
```

 **RHEL 8 OVA** 

```
packer build -only=general-build.vsphere-iso.rhel8 template.pkr.hcl
```

 **RHEL 9 OVA** 

```
packer build -only=general-build.vsphere-iso.rhel9 template.pkr.hcl
```

 **QEMU** 

**注意**  
如果您要為與建置器主機不相符的特定主機 CPU 建置映像，請參閱 [QEMU](https://www.qemu.org/docs/master/system/qemu-cpu-models.html) 文件以取得與您主機 CPU 相符的名稱，並在執行下列命令時，使用具有主機 CPU 名稱的 `-cpu` 旗標。

 **Ubuntu 22.04 Qcow2 / Raw** 

```
packer build -only=general-build.qemu.ubuntu22 template.pkr.hcl
```

 **Ubuntu 24.04 Qcow2 / Raw** 

```
packer build -only=general-build.qemu.ubuntu24 template.pkr.hcl
```

 **RHEL 8 Qcow2 / Raw** 

```
packer build -only=general-build.qemu.rhel8 template.pkr.hcl
```

 **RHEL 9 Qcow2 / Raw** 

```
packer build -only=general-build.qemu.rhel9 template.pkr.hcl
```

### 透過使用者資料傳遞 nodeadm 組態
<a name="_pass_nodeadm_configuration_through_user_data"></a>

您可以透過 cloud-init 傳遞使用者資料中 `nodeadm` 的組態，以在主機啟動時設定混合節點並自動將其連接至 EKS 叢集。以下範例說明如何在使用 VMware vSphere 作為混合節點的基礎結構時完成此操作。

1. 遵循 GitHub 上 [govc readme](https://github.com/vmware/govmomi/blob/main/govc/README.md) 中的指示安裝 `govc` CLI。

1. 在上一節中執行 Packer 建置並佈建範本後，您可以使用下列內容複製範本，進而建立多個不同的節點。對於要建立且將用於混合節點的每個新 VM，您必須複製相應的範本。使用您環境的值取代以下命令中的變數。當您透過 `metadata.yaml` 檔案插入 VM 的名稱時，以下命令中的 `VM_NAME` 可用作您的 `NODE_NAME`。

   ```
   govc vm.clone -vm "/PATH/TO/TEMPLATE" -ds="YOUR_DATASTORE" \
       -on=false -template=false -folder=/FOLDER/TO/SAVE/VM "VM_NAME"
   ```

1. 複製每個新 VM 的範本之後，請為您的 VM 建立 `userdata.yaml` 和 `metadata.yaml`。在以下步驟中，您的 VM 可以共用相同的 `userdata.yaml` 和 `metadata.yaml`，並且您將以每個 VM 為基礎填入。`nodeadm` 組態可由 `userdata.yaml` 的 `write_files` 區段建立並定義。以下範例使用 AWS SSM 混合啟用做為混合節點的內部部署憑證提供者。如需有關 `nodeadm` 組態的詳細資訊，請參閱 [混合節點 `nodeadm` 參考](hybrid-nodes-nodeadm.md)。

    **userdata.yaml：**

   ```
   #cloud-config
   users:
     - name: # username for login. Use 'builder' for RHEL or 'ubuntu' for Ubuntu.
       passwd: # password to login. Default is 'builder' for RHEL.
       groups: [adm, cdrom, dip, plugdev, lxd, sudo]
       lock-passwd: false
       sudo: ALL=(ALL) NOPASSWD:ALL
       shell: /bin/bash
   
   write_files:
     - path: /usr/local/bin/nodeConfig.yaml
       permissions: '0644'
       content: |
         apiVersion: node.eks.aws/v1alpha1
         kind: NodeConfig
         spec:
             cluster:
                 name: # Cluster Name
                 region: # AWS region
             hybrid:
                 ssm:
                     activationCode: # Your ssm activation code
                     activationId: # Your ssm activation id
   
   runcmd:
     - /usr/local/bin/nodeadm init -c file:///usr/local/bin/nodeConfig.yaml >> /var/log/nodeadm-init.log 2>&1
   ```

    **metadata.yaml：**

   為您的環境建立 `metadata.yaml`。在檔案中保留 `"$NODE_NAME"` 變數格式，因為會在後續步驟中填入這些值。

   ```
   instance-id: "$NODE_NAME"
   local-hostname: "$NODE_NAME"
   network:
     version: 2
     ethernets:
       nics:
         match:
           name: ens*
         dhcp4: yes
   ```

1. 使用下列命令將 `userdata.yaml` 和 `metadata.yaml` 檔案新增為 `gzip+base64` 字串。應該為您建立的每個 VM 執行下列命令。使用您要更新的 VM 的名稱取代 `VM_NAME`。

   ```
   export NODE_NAME="VM_NAME"
   export USER_DATA=$(gzip -c9 <userdata.yaml | base64)
   
   govc vm.change -dc="YOUR_DATASTORE" -vm "$NODE_NAME" -e guestinfo.userdata="${USER_DATA}"
   govc vm.change -dc="YOUR_DATASTORE" -vm "$NODE_NAME" -e guestinfo.userdata.encoding=gzip+base64
   
   envsubst '$NODE_NAME' < metadata.yaml > metadata.yaml.tmp
   export METADATA=$(gzip -c9 <metadata.yaml.tmp | base64)
   
   govc vm.change -dc="YOUR_DATASTORE" -vm "$NODE_NAME" -e guestinfo.metadata="${METADATA}"
   govc vm.change -dc="YOUR_DATASTORE" -vm "$NODE_NAME" -e guestinfo.metadata.encoding=gzip+base64
   ```

1. 開啟新 VM 的電源，而這應該會自動連接到您設定的 EKS 叢集。

   ```
   govc vm.power -on "${NODE_NAME}"
   ```

# 準備混合節點的憑證
<a name="hybrid-nodes-creds"></a>

Amazon EKS 混合節點使用由 AWS SSM 混合啟用或 IAM Roles Anywhere AWS 佈建的臨時 IAM 登入資料來驗證 Amazon EKS 叢集。您必須將 AWS SSM 混合啟用或 AWS IAM Roles Anywhere 與 Amazon EKS 混合節點 CLI () 搭配使用`nodeadm`。您不應該同時使用 AWS SSM 混合啟用和 AWS IAM Roles Anywhere。如果您現有的公有金鑰基礎設施 (PKI) 沒有憑證授權機構 (CA) 和內部部署環境的憑證，建議您使用 AWS SSM 混合啟用。如果您有現有的 PKI 和現場部署憑證，請使用 AWS IAM Roles Anywhere。

## 混合節點 IAM 角色
<a name="hybrid-nodes-role"></a>

在將混合節點連接到 Amazon EKS 叢集之前，您必須建立 IAM 角色，以搭配混合節點憑證的 AWS SSM 混合啟用或 AWS IAM Roles Anywhere 使用。建立叢集後，您將搭配 Amazon EKS 存取項目或 `aws-auth` ConfigMap 項目使用此角色，以將 IAM 角色映射至 Kubernetes 角色型存取控制 (RBAC)。如需建立混合節點 IAM 角色與 Kubernetes RBAC 的關聯的詳細資訊，請參閱 [準備混合節點的叢集存取](hybrid-nodes-cluster-prep.md)。

混合節點 IAM 角色必須具有下列許可。
+ `nodeadm` 使用 `eks:DescribeCluster`動作來收集您要連接混合節點之叢集相關資訊的許可。如果您未啟用 `eks:DescribeCluster`動作，則必須在傳遞給`nodeadm init`命令的節點組態中傳遞 Kubernetes API 端點、叢集 CA 套件和服務 IPv4 CIDR。
+ `nodeadm` 使用 `eks:ListAccessEntries`動作列出您要連接混合節點之叢集上存取項目的許可。如果您未啟用 `eks:ListAccessEntries`動作，則必須在執行 `nodeadm init`命令時傳遞 `--skip cluster-access-validation`旗標。
+ kubelet 使用 Amazon Elastic Container Registry (Amazon ECR) 中容器映像的許可，如 [AmazonEC2ContainerRegistryPullOnly](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonEC2ContainerRegistryPullOnly.html) 政策所定義。
+ 如果使用 AWS SSM，`nodeadm init`則允許 使用[https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonSSMManagedInstanceCore.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonSSMManagedInstanceCore.html)政策中定義的 AWS SSM 混合啟用。
+ 如果使用 AWS SSM，則使用 `ssm:DeregisterManagedInstance`動作和 `ssm:DescribeInstanceInformation`動作`nodeadm uninstall`取消註冊執行個體的許可。
+ (選用) Amazon EKS Pod 身分識別代理程式使用 `eks-auth:AssumeRoleForPodIdentity` 動作擷取 Pod 憑證的許可。

## 設定 AWS SSM 混合啟用
<a name="hybrid-nodes-ssm"></a>

在設定 AWS SSM 混合啟用之前，您必須建立並設定混合節點 IAM 角色。如需詳細資訊，請參閱[建立混合節點 IAM 角色](#hybrid-nodes-create-role)。遵循 Systems [Manager 使用者指南中的建立混合啟用中的指示，向 Systems Manager 註冊節點](https://docs.aws.amazon.com/systems-manager/latest/userguide/hybrid-activation-managed-nodes.html)，為您的混合節點建立 AWS SSM 混合啟用。 AWS 當您將主機作為混合節點註冊到 Amazon EKS 叢集時，請搭配 `nodeadm` 使用您收到的啟用碼和 ID。在您為混合節點建立及準備好 Amazon EKS 叢集後，您可以稍後再返回此步驟。

**重要**  
Systems Manager 會立即將啟用代碼和 ID 傳回主控台或命令視窗，視您如何建立啟用而定。複製此資訊，並將其存放在安全的地方。如果您離開主控台或關閉命令視窗，您可能會遺失此資訊。如果您遺失此資訊，您必須建立新的啟用。

根據預設， AWS SSM 混合啟用會處於作用中狀態 24 小時。或者，您亦可在以時間戳格式建立混合啟用時指定 `--expiration-date`，例如 `2024-08-01T00:00:00`。當您使用 AWS SSM 做為登入資料提供者時，混合節點的節點名稱無法設定，且由 AWS SSM 自動產生。您可以在 Fleet Manager 下的 AWS Systems Manager 主控台中檢視和管理 AWS SSM 受管執行個體。每個 AWS 區域每個帳戶最多可註冊 1，000 個標準[混合啟用節點](https://docs.aws.amazon.com/systems-manager/latest/userguide/activations.html)，無需額外費用。不過，登錄超過 1,000 個混合節點需要啟用進階執行個體層。使用 advanced-instances 方案會產生費用，而且 [Amazon EKS 混合節點定價](https://aws.amazon.com/eks/pricing/)中未包含該方案。如需詳細資訊，請參閱 [AWS Systems Manager 定價](https://aws.amazon.com/systems-manager/pricing/)。

請參閱以下範例，了解如何使用混合節點 IAM 角色建立 AWS SSM 混合啟用。當您針對混合節點登入資料使用 AWS SSM 混合啟用時，混合節點的名稱將具有 格式，`mi-012345678abcdefgh`且 AWS SSM 佈建的臨時登入資料有效期為 1 小時。使用 AWS SSM 做為登入資料提供者時，您無法變更節點名稱或登入資料持續時間。SSM AWS 會自動輪換臨時登入資料，輪換不會影響節點或應用程式的狀態。

我們建議您每個 EKS 叢集使用一個 AWS SSM 混合啟用，將混合節點 IAM 角色的 AWS SSM `ssm:DeregisterManagedInstance`許可範圍限定為只能取消註冊與您的 AWS SSM 混合啟用相關聯的執行個體。在此頁面上的範例中，使用具有 EKS 叢集 ARN 的標籤，可用於將您的 AWS SSM 混合啟用映射至 EKS 叢集。或者，您也可以根據您的許可界限和要求，使用您偏好的標籤和方法來擴展 AWS SSM 許可。以下命令中的 `REGISTRATION_LIMIT`選項是整數，用於限制可使用 AWS SSM 混合啟用的機器數量 （例如 `10`)

```
aws ssm create-activation \
     --region AWS_REGION \
     --default-instance-name eks-hybrid-nodes \
     --description "Activation for EKS hybrid nodes" \
     --iam-role AmazonEKSHybridNodesRole \
     --tags Key=EKSClusterARN,Value=arn:aws: eks:AWS_REGION:AWS_ACCOUNT_ID:cluster/CLUSTER_NAME \
     --registration-limit REGISTRATION_LIMIT
```

如需 AWS SSM [混合啟用可用組態設定的詳細資訊，請參閱建立混合啟用以向 Systems Manager 註冊節點](https://docs.aws.amazon.com/systems-manager/latest/userguide/hybrid-activation-managed-nodes.html)的說明。

## 隨處設定 AWS IAM 角色
<a name="hybrid-nodes-iam-roles-anywhere"></a>

請遵循《IAM Roles Anywhere 使用者指南》中 [IAM Roles Anywhere 入門](https://docs.aws.amazon.com/rolesanywhere/latest/userguide/getting-started.html)上的指示，設定您要用於混合節點 IAM 角色的臨時 IAM 憑證的信任錨和設定檔。建立設定檔時，您可以選擇建立時不新增任何角色。您可以建立此設定檔，返回可建立混合節點 IAM 角色的步驟，然後在建立角色後，將其新增至您的設定檔。或者，您可以在此頁面稍後使用 AWS CloudFormation 步驟來完成混合節點的 IAM Roles Anywhere 設定。

當您將混合節點 IAM 角色新增至設定檔時，請在 **IAM Roles Anywhere 主控台的編輯設定檔頁面底部的自訂角色工作階段名稱面板中選取接受**自訂角色工作階段名稱。 **** **** AWS 這會對應至 `CreateProfile` API 的 [acceptRoleSessionName](https://docs.aws.amazon.com/rolesanywhere/latest/APIReference/API_CreateProfile.html#rolesanywhere-CreateProfile-request-acceptRoleSessionName) 欄位。這可讓您在引導程序過程中，於傳遞給 `nodeadm` 的組態中，為混合節點提供自訂節點名稱。需要在 `nodeadm init` 過程中傳遞自訂節點名稱。建立設定檔後，您可以更新您的設定檔，以接受自訂角色工作階段名稱。

您可以透過 IAM Roles Anywhere AWS 設定檔的 [durationSeconds](https://docs.aws.amazon.com/rolesanywhere/latest/userguide/authentication-create-session#credentials-object) 欄位，使用 IAM Roles Anywhere AWS 設定憑證有效性持續時間。預設持續時間為 1 小時，最長為 12 小時。混合節點 IAM 角色上的`MaxSessionDuration`設定必須大於 IAM Roles Anywhere AWS 設定檔上的`durationSeconds`設定。如需有關 `MaxSessionDuration` 的詳細資訊，請參閱 [UpdateRole API 文件](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_UpdateRole.html)。

從憑證認證機構 (CA) 產生的每個機器憑證和金鑰，必須放置在每個混合節點的 `/etc/iam/pki` 目錄中，其中包含的檔案名稱 `server.pem` 指代憑證，`server.key` 指代金鑰。

## 建立混合節點 IAM 角色
<a name="hybrid-nodes-create-role"></a>

若要執行本節中的步驟，使用 AWS 主控台或 CLI 的 IAM AWS 主體必須具有下列許可。
+  `iam:CreatePolicy` 
+  `iam:CreateRole` 
+  `iam:AttachRolePolicy` 
+ 如果使用 AWS IAM Roles Anywhere
  +  `rolesanywhere:CreateTrustAnchor` 
  +  `rolesanywhere:CreateProfile` 
  +  `iam:PassRole` 

### AWS CloudFormation
<a name="hybrid-nodes-creds-cloudformation"></a>

如果您尚未安裝和設定 AWS CLI。請參閱[安裝或更新至最新版本的 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

 ** AWS SSM 混合啟用的步驟** 

CloudFormation 堆疊會使用上述許可來建立混合節點 IAM 角色。CloudFormation 範本不會建立 AWS SSM 混合啟用。

1. 下載混合節點的 AWS SSM CloudFormation 範本：

   ```
   curl -OL 'https://raw.githubusercontent.com/aws/eks-hybrid/refs/heads/main/example/hybrid-ssm-cfn.yaml'
   ```

1. 使用下列選項建立 `cfn-ssm-parameters.json`：

   1. 使用混合節點 IAM 角色的名稱取代 `ROLE_NAME`。根據預設，如果您未指定名稱，CloudFormation 範本會使用 `AmazonEKSHybridNodesRole` 作為其建立的角色的名稱。

   1. `TAG_KEY` 將 取代為您在建立 AWS SSM 混合啟用時使用的 AWS SSM 資源標籤金鑰。標籤索引鍵和標籤值的組合用於 的條件`ssm:DeregisterManagedInstance`，只允許混合節點 IAM 角色取消註冊與您的 AWS SSM 混合啟用相關聯的 AWS SSM 受管執行個體。在 CloudFormation 範本中，`TAG_KEY` 預設為 `EKSClusterARN`。

   1. `TAG_VALUE` 將 取代為您建立 AWS SSM 混合啟用時使用的 AWS SSM 資源標籤值。標籤索引鍵和標籤值的組合用於 的條件`ssm:DeregisterManagedInstance`，只允許混合節點 IAM 角色取消註冊與您的 AWS SSM 混合啟用相關聯的 AWS SSM 受管執行個體。如果您使用 `EKSClusterARN` 的預設值 `TAG_KEY`，則請將您的 EKS 叢集 ARN 作為 `TAG_VALUE` 進行傳遞。EKS 叢集 ARN 的格式為 ` arn:aws: eks:AWS_REGION:AWS_ACCOUNT_ID:cluster/CLUSTER_NAME`。

      ```
      {
        "Parameters": {
          "RoleName": "ROLE_NAME",
          "SSMDeregisterConditionTagKey": "TAG_KEY",
          "SSMDeregisterConditionTagValue": "TAG_VALUE"
        }
      }
      ```

1. 部署 CloudFormation 堆疊。使用 CloudFormation 堆疊的名稱取代 `STACK_NAME`。

   ```
   aws cloudformation deploy \
       --stack-name STACK_NAME \
       --template-file hybrid-ssm-cfn.yaml \
       --parameter-overrides file://cfn-ssm-parameters.json \
       --capabilities CAPABILITY_NAMED_IAM
   ```

 ** AWS IAM Roles Anywhere 的步驟** 

CloudFormation 堆疊會使用您設定的憑證授權機構 AWS (CA) 建立 IAM Roles Anywhere 信任錨點、建立 AWS IAM Roles Anywhere 設定檔，以及使用先前概述的許可建立混合節點 IAM 角色。

1. 設定憑證認證機構 (CA)

   1. 若要使用 AWS Private CA 資源，請開啟 [AWS Private Certificate Authority 主控台](https://console.aws.amazon.com/acm-pca/home)。請遵循《[AWS 私有 CA 使用者指南](https://docs.aws.amazon.com/privateca/latest/userguide/PcaWelcome.html)》中的指示。

   1. 若要使用外部 CA，請遵循 CA 提供的指示。您將在後續步驟中提供憑證內文。

   1. 從公有 CA 核發的憑證不能用作信任錨。

1. 下載混合節點的 AWS IAM Roles Anywhere CloudFormation 範本

   ```
   curl -OL 'https://raw.githubusercontent.com/aws/eks-hybrid/refs/heads/main/example/hybrid-ira-cfn.yaml'
   ```

1. 使用下列選項建立 `cfn-iamra-parameters.json`：

   1. 使用混合節點 IAM 角色的名稱取代 `ROLE_NAME`。根據預設，如果您未指定名稱，CloudFormation 範本會使用 `AmazonEKSHybridNodesRole` 作為其建立的角色的名稱。

   1. 使用可唯一識別您主機的每個機器憑證屬性取代 `CERT_ATTRIBUTE`。在您將混合節點連接至叢集時，您使用的憑證屬性必須與您用於 `nodeadm` 組態的 nodeName 相符。如需更多資訊，請參閱[混合節點 `nodeadm` 參考](hybrid-nodes-nodeadm.md)。根據預設，CloudFormation 範本會將 `${aws:PrincipalTag/x509Subject/CN}` 用作 `CERT_ATTRIBUTE`，而其會對應至每個機器憑證的 CN 欄位。或者，您可以將 `$(aws:PrincipalTag/x509SAN/Name/CN}` 作為 `CERT_ATTRIBUTE` 進行傳遞。

   1. 使用您 CA 的憑證內文取代 `CA_CERT_BODY`，且沒有分行符號。`CA_CERT_BODY` 必須是隱私權增強式郵件 (PEM) 格式。如果您的 CA 憑證採用 PEM 格式，則請先移除分行符號以及 BEGIN CERTIFICATE 和 END CERTIFICATE 行，然後再將 CA 憑證內文放入 `cfn-iamra-parameters.json` 檔案中。

      ```
      {
        "Parameters": {
          "RoleName": "ROLE_NAME",
          "CertAttributeTrustPolicy": "CERT_ATTRIBUTE",
          "CABundleCert": "CA_CERT_BODY"
        }
      }
      ```

1. 部署 CloudFormation 範本。使用 CloudFormation 堆疊的名稱取代 `STACK_NAME`。

   ```
   aws cloudformation deploy \
       --stack-name STACK_NAME \
       --template-file hybrid-ira-cfn.yaml \
       --parameter-overrides file://cfn-iamra-parameters.json
       --capabilities CAPABILITY_NAMED_IAM
   ```

### AWS CLI
<a name="hybrid-nodes-creds-awscli"></a>

如果您尚未安裝和設定 AWS CLI。請參閱[安裝或更新至最新版本的 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

 **建立 EKS 描述叢集政策** 

1. 使用下列內容建立名為 `eks-describe-cluster-policy.json` 的檔案：

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "eks:DescribeCluster"
               ],
               "Resource": "*"
           }
       ]
   }
   ```

1. 使用下列命令建立政策：

   ```
   aws iam create-policy \
       --policy-name EKSDescribeClusterPolicy \
       --policy-document file://eks-describe-cluster-policy.json
   ```

 ** AWS SSM 混合啟用的步驟** 

1. 使用下列內容建立名為 `eks-hybrid-ssm-policy.json` 的檔案。此政策會將授與兩個動作 (`ssm:DescribeInstanceInformation` 和 `ssm:DeregisterManagedInstance`) 的許可。此政策會根據您在信任政策中指定的資源標籤，將`ssm:DeregisterManagedInstance`許可限制為與您的 SSM 混合啟用相關聯的 AWS SSM AWS 受管執行個體。

   1. `AWS_REGION` 將 取代為 AWS SSM 混合啟用 AWS 的區域。

   1. 將 取代`AWS_ACCOUNT_ID`為 AWS 您的帳戶 ID。

   1. `TAG_KEY` 將 取代為您在建立 AWS SSM 混合啟用時使用的 AWS SSM 資源標籤金鑰。標籤索引鍵和標籤值的組合用於 的條件`ssm:DeregisterManagedInstance`，只允許混合節點 IAM 角色取消註冊與您的 AWS SSM 混合啟用相關聯的 AWS SSM 受管執行個體。在 CloudFormation 範本中，`TAG_KEY` 預設為 `EKSClusterARN`。

   1. `TAG_VALUE` 將 取代為您建立 AWS SSM 混合啟用時使用的 AWS SSM 資源標籤值。標籤索引鍵和標籤值的組合用於 的條件`ssm:DeregisterManagedInstance`，只允許混合節點 IAM 角色取消註冊與您的 AWS SSM 混合啟用相關聯的 AWS SSM 受管執行個體。如果您使用 `EKSClusterARN` 的預設值 `TAG_KEY`，則請將您的 EKS 叢集 ARN 作為 `TAG_VALUE` 進行傳遞。EKS 叢集 ARN 的格式為 ` arn:aws: eks:AWS_REGION:AWS_ACCOUNT_ID:cluster/CLUSTER_NAME`。

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": "ssm:DescribeInstanceInformation",
                  "Resource": "*"
              },
              {
                  "Effect": "Allow",
                  "Action": "ssm:DeregisterManagedInstance",
                  "Resource": "arn:aws:ssm:us-east-1:123456789012:managed-instance/*",
                  "Condition": {
                      "StringEquals": {
                          "ssm:resourceTag/TAG_KEY": "TAG_VALUE"
                      }
                  }
              }
          ]
      }
      ```

1. 使用下列命令建立政策

   ```
   aws iam create-policy \
       --policy-name EKSHybridSSMPolicy \
       --policy-document file://eks-hybrid-ssm-policy.json
   ```

1. 建立名為 `eks-hybrid-ssm-trust.json` 的檔案。`AWS_REGION` 將 取代為 AWS SSM 混合啟用 AWS 的區域，並將 `AWS_ACCOUNT_ID`取代為 AWS 您的帳戶 ID。

   ```
   {
      "Version":"2012-10-17",		 	 	 
      "Statement":[
         {
            "Sid":"",
            "Effect":"Allow",
            "Principal":{
               "Service":"ssm.amazonaws.com"
            },
            "Action":"sts:AssumeRole",
            "Condition":{
               "StringEquals":{
                  "aws:SourceAccount":"123456789012"
               },
               "ArnEquals":{
                  "aws:SourceArn":"arn:aws:ssm:us-east-1:123456789012:*"
               }
            }
         }
      ]
   }
   ```

1. 使用下列命令建立角色。

   ```
   aws iam create-role \
       --role-name AmazonEKSHybridNodesRole \
       --assume-role-policy-document file://eks-hybrid-ssm-trust.json
   ```

1. 連接 `EKSHybridSSMPolicy` 和您在先前步驟中建立的 `EKSDescribeClusterPolicy`。將 取代`AWS_ACCOUNT_ID`為 AWS 您的帳戶 ID。

   ```
   aws iam attach-role-policy \
       --role-name AmazonEKSHybridNodesRole \
       --policy-arn arn:aws: iam::AWS_ACCOUNT_ID:policy/EKSDescribeClusterPolicy
   ```

   ```
   aws iam attach-role-policy \
       --role-name AmazonEKSHybridNodesRole \
       --policy-arn arn:aws: iam::AWS_ACCOUNT_ID:policy/EKSHybridSSMPolicy
   ```

1. 連接 `AmazonEC2ContainerRegistryPullOnly`和 `AmazonSSMManagedInstanceCore` AWS 受管政策。

   ```
   aws iam attach-role-policy \
       --role-name AmazonEKSHybridNodesRole \
       --policy-arn arn:aws: iam::aws:policy/AmazonEC2ContainerRegistryPullOnly
   ```

   ```
   aws iam attach-role-policy \
       --role-name AmazonEKSHybridNodesRole \
       --policy-arn arn:aws: iam::aws:policy/AmazonSSMManagedInstanceCore
   ```

 **IAM Roles Anywhere AWS 的步驟** 

若要使用 AWS IAM Roles Anywhere，您必須在建立混合節點 AWS IAM 角色之前設定 IAM Roles Anywhere 信任錨點。如需說明，請參閱 [隨處設定 AWS IAM 角色](#hybrid-nodes-iam-roles-anywhere)。

1. 建立名為 `eks-hybrid-iamra-trust.json` 的檔案。使用您在 [隨處設定 AWS IAM 角色](#hybrid-nodes-iam-roles-anywhere) 步驟中建立的信任錨的 ARN 取代 `TRUST_ANCHOR ARN`。此信任政策中的 條件會限制 AWS IAM Roles Anywhere 擔任混合節點 IAM 角色的能力，只有在角色工作階段名稱符合安裝在混合節點上 x509 憑證中的 CN 時，才能交換臨時 IAM 憑證。或者，您也可以使用其他憑證屬性來唯一識別您的節點。您在信任政策中使用的憑證屬性必須對應至您在 `nodeadm` 組態中設定的 `nodeName`。如需更多資訊，請參閱[混合節點 `nodeadm` 參考](hybrid-nodes-nodeadm.md)。

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Principal": {
                   "Service": "rolesanywhere.amazonaws.com"
               },
               "Action": [
                   "sts:TagSession",
                   "sts:SetSourceIdentity"
               ],
               "Condition": {
                   "StringEquals": {
                       "aws:PrincipalTag/x509Subject/CN": "${aws:PrincipalTag/x509Subject/CN}"
                   },
                   "ArnEquals": {
                       "aws:SourceArn": "arn:aws:rolesanywhere:us-east-1:123456789012:trust-anchor/TA_ID"
                   }
               }
           },
           {
               "Effect": "Allow",
               "Principal": {
                   "Service": "rolesanywhere.amazonaws.com"
               },
               "Action": "sts:AssumeRole",
               "Condition": {
                   "StringEquals": {
                       "sts:RoleSessionName": "${aws:PrincipalTag/x509Subject/CN}",
                       "aws:PrincipalTag/x509Subject/CN": "${aws:PrincipalTag/x509Subject/CN}"
                   },
                   "ArnEquals": {
                       "aws:SourceArn": "arn:aws:rolesanywhere:us-east-1:123456789012:trust-anchor/TA_ID"
                   }
               }
           }
       ]
   }
   ```

1. 使用下列命令建立角色。

   ```
   aws iam create-role \
       --role-name AmazonEKSHybridNodesRole \
       --assume-role-policy-document file://eks-hybrid-iamra-trust.json
   ```

1. 連接您在先前步驟中建立的 `EKSDescribeClusterPolicy`。將 取代`AWS_ACCOUNT_ID`為 AWS 您的帳戶 ID。

   ```
   aws iam attach-role-policy \
       --role-name AmazonEKSHybridNodesRole \
       --policy-arn arn:aws: iam::AWS_ACCOUNT_ID:policy/EKSDescribeClusterPolicy
   ```

1. 連接 `AmazonEC2ContainerRegistryPullOnly` AWS 受管政策

   ```
   aws iam attach-role-policy \
       --role-name AmazonEKSHybridNodesRole \
       --policy-arn arn:aws: iam::aws:policy/AmazonEC2ContainerRegistryPullOnly
   ```

### AWS 管理主控台
<a name="hybrid-nodes-creds-console"></a>

 **建立 EKS 描述叢集政策** 

1. 開啟 [Amazon IAM 主控台](https://console.aws.amazon.com/iam/home) 

1. 在左側導覽窗格中選擇 **Policies** (政策)。

1. 在**政策**頁面上，選擇**建立政策**。

1. 在指定許可頁面，在選取服務面板中，選擇 EKS。

   1. 篩選 **DescribeCluster** 的動作，然後選取 **DescribeCluster** Read 動作。

   1. 選擇**下一步**。

1. 在**檢閱和建立**頁面上

   1. 輸入政策的**政策名稱**，例如 `EKSDescribeClusterPolicy`。

   1. 選擇**建立政策**。

 ** AWS SSM 混合啟用的步驟** 

1. 開啟 [Amazon IAM 主控台](https://console.aws.amazon.com/iam/home) 

1. 在左側導覽窗格中選擇 **Policies** (政策)。

1. 在**政策**頁面上，選擇**建立政策**。

1. 在**指定許可**頁面上，在**政策編輯器**右上角導覽中，選擇 **JSON**。貼上下列程式碼片段。`AWS_REGION` 將 取代為 AWS SSM 混合啟用 AWS 的區域，並將 取代`AWS_ACCOUNT_ID`為 AWS 您的帳戶 ID。`TAG_VALUE` 使用您在建立 AWS SSM 混合啟用時使用的 AWS SSM 資源標籤金鑰取代 `TAG_KEY`和 。

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "ssm:DescribeInstanceInformation",
               "Resource": "*"
           },
           {
               "Effect": "Allow",
               "Action": "ssm:DeregisterManagedInstance",
               "Resource": "arn:aws:ssm:us-east-1:123456789012:managed-instance/*",
               "Condition": {
                   "StringEquals": {
                       "ssm:resourceTag/TAG_KEY": "TAG_VALUE"
                   }
               }
           }
       ]
   }
   ```

   1. 選擇**下一步**。

1. 在**檢閱和建立**頁面上。

   1. 輸入政策的**政策**名稱，例如 `EKSHybridSSMPolicy` 

   1. 選擇**建立政策**。

1. 在左側導覽窗格中，選擇 **Roles** (角色)。

1. 在 **Roles** (角色) 頁面上，選擇 **Create role** (建立角色)。

1. 在 **Select trusted entity** (選取信任的實體) 頁面上，執行以下作業：

   1. 在**可信實體類型區段**中，選擇**自訂信任政策**。將下列政策貼到自訂信任政策編輯器。`AWS_REGION` 將 取代為 AWS SSM 混合啟用 AWS 的區域，並將 `AWS_ACCOUNT_ID`取代為 AWS 您的帳戶 ID。

      ```
      {
         "Version":"2012-10-17",		 	 	 
         "Statement":[
            {
               "Sid":"",
               "Effect":"Allow",
               "Principal":{
                  "Service":"ssm.amazonaws.com"
               },
               "Action":"sts:AssumeRole",
               "Condition":{
                  "StringEquals":{
                     "aws:SourceAccount":"123456789012"
                  },
                  "ArnEquals":{
                     "aws:SourceArn":"arn:aws:ssm:us-east-1:123456789012:*"
                  }
               }
            }
         ]
      }
      ```

   1. 選擇下一步。

1. 在**新增許可**頁面上，連接自訂政策或執行下列動作：

   1. 在**篩選政策**方塊中，輸入 `EKSDescribeClusterPolicy` 或您在上文建立的政策名稱。勾選搜尋結果中您的政策名稱左側的核取方塊。

   1. 在**篩選政策**方塊中，輸入 `EKSHybridSSMPolicy` 或您在上文建立的政策名稱。勾選搜尋結果中您的政策名稱左側的核取方塊。

   1. 在 **Filter policies** (篩選政策) 方塊中，輸入 `AmazonEC2ContainerRegistryPullOnly`。勾選搜尋結果中 `AmazonEC2ContainerRegistryPullOnly` 左側的核取方塊。

   1. 在 **Filter policies** (篩選政策) 方塊中，輸入 `AmazonSSMManagedInstanceCore`。勾選搜尋結果中 `AmazonSSMManagedInstanceCore` 左側的核取方塊。

   1. 選擇**下一步**。

1. 在 **Name, review, and create** (命名、檢閱和建立) 頁面上，執行以下作業：

   1. 針對 **Role name** (角色名稱)，為您的角色輸入唯一名稱 (例如 `AmazonEKSHybridNodesRole`)。

   1. 針對 **Description** (描述)，請以描述性文字 (例如 `Amazon EKS - Hybrid Nodes role`) 取代目前的文字。

   1. 選擇建**立角色**。

 **IAM Roles Anywhere AWS 的步驟** 

若要使用 AWS IAM Roles Anywhere，您必須在建立混合節點 AWS IAM 角色之前設定 IAM Roles Anywhere 信任錨點。如需說明，請參閱 [隨處設定 AWS IAM 角色](#hybrid-nodes-iam-roles-anywhere)。

1. 開啟 [Amazon IAM 主控台](https://console.aws.amazon.com/iam/home) 

1. 在左側導覽窗格中，選擇 **Roles** (角色)。

1. 在 **Roles** (角色) 頁面上，選擇 **Create role** (建立角色)。

1. 在 **Select trusted entity** (選取信任的實體) 頁面上，執行以下作業：

   1. 在**可信實體類型區段**中，選擇**自訂信任政策**。將下列政策貼到自訂信任政策編輯器。使用您在 [隨處設定 AWS IAM 角色](#hybrid-nodes-iam-roles-anywhere) 步驟中建立的信任錨的 ARN 取代 `TRUST_ANCHOR ARN`。此信任政策中的 條件會限制 AWS IAM Roles Anywhere 擔任混合節點 IAM 角色的能力，只有在角色工作階段名稱符合安裝在混合節點上 x509 憑證中的 CN 時，才能交換臨時 IAM 憑證。或者，您也可以使用其他憑證屬性來唯一識別您的節點。您在信任政策中使用的憑證屬性必須對應至您在 nodeadm 組態中設定的 nodeName。如需更多資訊，請參閱[混合節點 `nodeadm` 參考](hybrid-nodes-nodeadm.md)。

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Principal": {
                      "Service": "rolesanywhere.amazonaws.com"
                  },
                  "Action": [
                      "sts:TagSession",
                      "sts:SetSourceIdentity"
                  ],
                  "Condition": {
                      "StringEquals": {
                          "aws:PrincipalTag/x509Subject/CN": "${aws:PrincipalTag/x509Subject/CN}"
                      },
                      "ArnEquals": {
                          "aws:SourceArn": "arn:aws:rolesanywhere:us-east-1:123456789012:trust-anchor/TA_ID"
                      }
                  }
              },
              {
                  "Effect": "Allow",
                  "Principal": {
                      "Service": "rolesanywhere.amazonaws.com"
                  },
                  "Action": "sts:AssumeRole",
                  "Condition": {
                      "StringEquals": {
                          "sts:RoleSessionName": "${aws:PrincipalTag/x509Subject/CN}",
                          "aws:PrincipalTag/x509Subject/CN": "${aws:PrincipalTag/x509Subject/CN}"
                      },
                      "ArnEquals": {
                          "aws:SourceArn": "arn:aws:rolesanywhere:us-east-1:123456789012:trust-anchor/TA_ID"
                      }
                  }
              }
          ]
      }
      ```

   1. 選擇下一步。

1. 在**新增許可**頁面上，連接自訂政策或執行下列動作：

   1. 在**篩選政策**方塊中，輸入 `EKSDescribeClusterPolicy` 或您在上文建立的政策名稱。勾選搜尋結果中您的政策名稱左側的核取方塊。

   1. 在 **Filter policies** (篩選政策) 方塊中，輸入 `AmazonEC2ContainerRegistryPullOnly`。勾選搜尋結果中 `AmazonEC2ContainerRegistryPullOnly` 左側的核取方塊。

   1. 選擇**下一步**。

1. 在 **Name, review, and create** (命名、檢閱和建立) 頁面上，執行以下作業：

   1. 針對 **Role name** (角色名稱)，為您的角色輸入唯一名稱 (例如 `AmazonEKSHybridNodesRole`)。

   1. 針對 **Description** (描述)，請以描述性文字 (例如 `Amazon EKS - Hybrid Nodes role`) 取代目前的文字。

   1. 選擇建**立角色**。

# 建立具有混合節點的 Amazon EKS 叢集
<a name="hybrid-nodes-cluster-create"></a>

本主題提供可用選項的概觀，並介紹建立已啟用混合節點的 Amazon EKS 叢集時需要考量的事項。EKS 混合節點與包含雲端節點的 Amazon EKS 叢集具有相同的 [Kubernetes 版本支援](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)，包括標準支援和延長支援。

如果您未打算使用 EKS 混合節點，請參閱 [建立 Amazon EKS 叢集](create-cluster.md) 中的主要 Amazon EKS 建立叢集文件。

## 先決條件
<a name="hybrid-nodes-cluster-create-prep"></a>
+ [混合節點的先決條件設定](hybrid-nodes-prereqs.md) 已完成。建立已啟用混合節點的叢集之前，您必須識別出內部部署節點和選用的 Pod CIDR，根據 EKS 要求和混合節點要求建立 VPC 和子網路，以及建立具有適用於內部部署和選用 Pod CIDR 的傳入規則的安全群組。如需有關這些先決條件的詳細資訊，請參閱 [準備混合節點的聯網](hybrid-nodes-networking.md)。
+ 在您裝置上安裝和設定的最新版本 AWS 命令列界面 (AWS CLI)。若要檢查您目前的版本，請使用 `aws --version`。適用於 macOS 的 yum、apt-get 或 Homebrew 等套件管理員通常是最新版本 CLI AWS 後面的幾個版本。若要安裝最新版本，請參閱《 AWS 命令列界面使用者指南》中的[安裝或更新至最新版本的 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) 和[設定 AWS CLI 的設定](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config)。
+ 具有建立 IAM 角色和連接政策以及建立和描述 EKS 叢集之許可的 IAM [主體](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles#iam-term-principal)

## 考量事項
<a name="hybrid-nodes-cluster-create-consider"></a>
+ 您的叢集必須使用 `API` 或 `API_AND_CONFIG_MAP` 作為叢集身分驗證模式。
+ 您的叢集必須使用 IPv4 位址系列。
+ 您的叢集必須使用公有或私有叢集端點連線。您的叢集無法使用「公有和私有」叢集端點連線，因為 Amazon EKS Kubernetes API 伺服器端點會解析為在您的 VPC 外部執行的混合節點的公共 IP。
+ 具有混合節點的 EKS 叢集支援 OIDC 身分驗證。
+ 您可以新增、變更或移除現有叢集的混合節點組態。如需詳細資訊，請參閱[在現有的 Amazon EKS 叢集上啟用混合節點或修改組態](hybrid-nodes-cluster-update.md)。

## 步驟 1：建立叢集 IAM 角色
<a name="hybrid-nodes-cluster-create-iam"></a>

如果您已有叢集 IAM 角色，或者您要使用 `eksctl` or AWS CloudFormation 建立叢集，則可以略過此步驟。根據預設，`eksctl` AWS CloudFormation 範本會為您建立叢集 IAM 角色。

1. 執行下列命令以建立 IAM 信任政策 JSON 檔案。

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "Service": "eks.amazonaws.com"
         },
         "Action": "sts:AssumeRole"
       }
     ]
   }
   ```

1. 建立 Amazon EKS 叢集 IAM 角色。如有必要，請在 eks-cluster-role-trust-policy.json 前面加上您在上一步中寫入檔案的電腦的路徑。命令會將您在上一步驟中建立的信任策略與角色相關聯。若要建立 IAM 角色，必須為建立角色的 [IAM 主體](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles#iam-term-principal)指派以下 `iam:CreateRole` 動作 (許可)。

   ```
   aws iam create-role \
       --role-name myAmazonEKSClusterRole \
       --assume-role-policy-document file://"eks-cluster-role-trust-policy.json"
   ```

1. 您可以指派 Amazon EKS 受管政策或建立自己的自訂政策。如需了解在自訂政策中必須使用的最低許可，請參閱 [Amazon EKS 節點 IAM 角色](create-node-role.md)。將名為 `AmazonEKSClusterPolicy` 的 Amazon EKS 受管 IAM 政策連接到角色。若要將 IAM 政策連接至 [IAM 主體](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles#iam-term-principal)，必須為連接政策的 IAM 實體指派以下 IAM 動作之一 (許可)：`iam:AttachUserPolicy` 或 `iam:AttachRolePolicy`。

   ```
   aws iam attach-role-policy \
       --policy-arn arn:aws: iam::aws:policy/AmazonEKSClusterPolicy \
       --role-name myAmazonEKSClusterRole
   ```

## 步驟 2：建立已啟用混合節點的叢集
<a name="hybrid-nodes-cluster-create-cluster"></a>

您可以透過以下方式建立叢集：
+  [eksctl](#hybrid-nodes-cluster-create-eksctl) 
+  [AWS CloudFormation](#hybrid-nodes-cluster-create-cfn) 
+  [AWS CLI](#hybrid-nodes-cluster-create-cli) 
+  [AWS 管理主控台](#hybrid-nodes-cluster-create-console) 

### 建立已啟用混合節點的叢集 - eksctl
<a name="hybrid-nodes-cluster-create-eksctl"></a>

您需要安裝最新版本的 `eksctl` 命令列工具。如需有關安裝或更新 `eksctl` 的指示，請參閱 `eksctl` 文件中的[安裝](https://eksctl.io/installation)一節。

1. 建立 `cluster-config.yaml` 以定義已啟用混合節點的 Amazon EKS IPv4 叢集。請在您的 `cluster-config.yaml` 中執行下列取代。如需設定的完整清單，請參閱 [eksctl 文件](https://eksctl.io/getting-started/)。

   1. 使用您的叢集名稱取代 `CLUSTER_NAME`。此名稱僅能使用英數字元 (區分大小寫) 和連字號。必須以英數字元開頭，且長度不可超過 100 個字元。名稱在您要建立叢集 AWS 的區域和 AWS 帳戶中必須是唯一的。

   1. `AWS_REGION` 將 取代為您要在其中建立叢集 AWS 的區域。

   1. 使用任何 [Amazon EKS 支援的版本](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)取代 `K8S_VERSION`。

   1. 使用 `ssm` 或 `ira` 取代 `CREDS_PROVIDER`，具體取決於您在 [準備混合節點的憑證](hybrid-nodes-creds.md) 步驟中設定的憑證提供者。

   1. `CA_BUNDLE_CERT` 如果您的登入資料提供者設定為 `ira`，則取代 ，這會使用 AWS IAM Roles Anywhere 做為登入資料提供者。CA\$1BUNDLE\$1CERT 是憑證認證機構 (CA) 憑證內文，取決於您選擇的 CA。憑證必須是隱私權增強式郵件 (PEM) 格式。

   1. 使用要連接到 VPC 的虛擬私有閘道或傳輸閘道的 ID 取代 `GATEWAY_ID`。

   1. 使用混合節點的內部部署節點 CIDR 取代 `REMOTE_NODE_CIDRS`。

   1. 對於在混合節點上執行的工作負載，使用內部部署 Pod CIDR 取代為 `REMOTE_POD_CIDRS`；或者如果您未在混合節點上執行 Webhook，則請從組態中移除該行。如果在 Pod 流量離開您的內部部署主機時，您的 CNI 未使用網路位址轉譯 (NAT) 或偽裝 Pod IP 位址，您必須設定您的 `REMOTE_POD_CIDRS`。如果您在混合節點上執行 Webhook，您必須設定 `REMOTE_POD_CIDRS`，如需詳細資訊，請參閱 [設定混合節點的 Webhook](hybrid-nodes-webhooks.md)。

   1. 您的內部部署節點和 Pod CIDR 區塊必須符合下列要求：

      1. 在其中一個 IPv4 RFC-1918 範圍內：`10.0.0.0/8`、 `172.16.0.0/12`或 `192.168.0.0/16` ，或在 RFC 6598 定義的 CGNAT 範圍內：`100.64.0.0/10`。

      1. 您叢集的 `VPC CIDR` 或您的 Kubernetes Service IPv4 CIDR 不會彼此重疊

         ```
         apiVersion: eksctl.io/v1alpha5
         kind: ClusterConfig
         
         metadata:
           name: CLUSTER_NAME
           region: AWS_REGION
           version: "K8S_VERSION"
         
         remoteNetworkConfig:
           iam:
             provider: CREDS_PROVIDER # default SSM, can also be set to IRA
             # caBundleCert: CA_BUNDLE_CERT
           vpcGatewayID: GATEWAY_ID
           remoteNodeNetworks:
           - cidrs: ["REMOTE_NODE_CIDRS"]
           remotePodNetworks:
           - cidrs: ["REMOTE_POD_CIDRS"]
         ```

1. 執行以下命令：

   ```
   eksctl create cluster -f cluster-config.yaml
   ```

   叢集佈建需要幾分鐘的時間。建立叢集時，會出現幾行輸出。輸出的最後一行類似於下面的範例行。

   ```
   [✓]  EKS cluster "CLUSTER_NAME" in "REGION" region is ready
   ```

1. 繼續進行 [步驟 3：更新 kubeconfig](#hybrid-nodes-cluster-create-kubeconfig)。

### 建立啟用混合節點的叢集 - AWS CloudFormation
<a name="hybrid-nodes-cluster-create-cfn"></a>

CloudFormation 堆疊會使用您指定的 `RemoteNodeNetwork` 和 `RemotePodNetwork` 來建立 EKS 叢集 IAM 角色和 EKS 叢集。修改 CloudFormation 範本 如果您需要自訂 CloudFormation 範本中未公開的 EKS 叢集的設定。

1. 下載 CloudFormation 範本。

   ```
   curl -OL 'https://raw.githubusercontent.com/aws/eks-hybrid/refs/heads/main/example/hybrid-eks-cfn.yaml'
   ```

1. 建立 `cfn-eks-parameters.json`，並為每個值指定您的組態。

   1.  `CLUSTER_NAME`：要建立的 EKS 叢集的名稱

   1.  `CLUSTER_ROLE_NAME`：要建立的 EKS 叢集 IAM 角色的名稱。範本中的預設值為 "EKSClusterRole"。

   1.  `SUBNET1_ID`：您在先決條件步驟中建立的第一個子網路的 ID

   1.  `SUBNET2_ID`：您在先決條件步驟中建立的第二個子網路的 ID

   1.  `SG_ID`：您在先決條件步驟中建立的安全群組 ID

   1.  `REMOTE_NODE_CIDRS`：混合節點的內部部署節點 CIDR

   1.  `REMOTE_POD_CIDRS`：在混合節點上執行的工作負載的內部部署 Pod CIDR。如果在 Pod 流量離開您的內部部署主機時，您的 CNI 未使用網路位址轉譯 (NAT) 或偽裝 Pod IP 位址，您必須設定您的 `REMOTE_POD_CIDRS`。如果您在混合節點上執行 Webhook，您必須設定 `REMOTE_POD_CIDRS`，如需詳細資訊，請參閱 [設定混合節點的 Webhook](hybrid-nodes-webhooks.md)。

   1. 您的內部部署節點和 Pod CIDR 區塊必須符合下列要求：

      1. 在其中一個 IPv4 RFC-1918 範圍內：`10.0.0.0/8`、 `172.16.0.0/12`或 `192.168.0.0/16`，或在 RFC 6598 定義的 CGNAT 範圍內：`100.64.0.0/10`。

      1. 您叢集的 `VPC CIDR` 或您的 Kubernetes Service IPv4 CIDR 不會彼此重疊。

   1.  `CLUSTER_AUTH`：您的叢集的叢集身分驗證模式。有效值為 `API` 和 `API_AND_CONFIG_MAP`。範本中的預設值為 `API_AND_CONFIG_MAP`。

   1.  `CLUSTER_ENDPOINT`：您叢集的叢集端點連線。有效值為 "Public" 或 "Private"。範本中的預設值為私有，這表示您只能從 VPC 內連接至 Kubernetes API 端點。

   1.  `K8S_VERSION`：要用於您叢集的 Kubernetes 版本。請參閱 [Amazon EKS 支援的版本](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)。

      ```
      {
        "Parameters": {
          "ClusterName": "CLUSTER_NAME",
          "ClusterRoleName": "CLUSTER_ROLE_NAME",
          "SubnetId1": "SUBNET1_ID",
          "SubnetId2": "SUBNET2_ID",
          "SecurityGroupId" "SG_ID",
          "RemoteNodeCIDR": "REMOTE_NODE_CIDRS",
          "RemotePodCIDR": "REMOTE_POD_CIDRS",
          "ClusterAuthMode": "CLUSTER_AUTH",
          "ClusterEndpointConnectivity": "CLUSTER_ENDPOINT",
          "K8sVersion": "K8S_VERSION"
        }
       }
      ```

1. 部署 CloudFormation 堆疊。`STACK_NAME` 將 取代為 CloudFormation 堆疊的名稱，並將 `AWS_REGION`取代為建立叢集的 AWS 區域。

   ```
   aws cloudformation deploy \
       --stack-name STACK_NAME \
       --region AWS_REGION \
       --template-file hybrid-eks-cfn.yaml \
       --parameter-overrides file://cfn-eks-parameters.json \
       --capabilities CAPABILITY_NAMED_IAM
   ```

   叢集佈建需要幾分鐘的時間。您可以使用下列命令來檢查堆疊的狀態。`STACK_NAME` 將 取代為 CloudFormation 堆疊的名稱，並將 `AWS_REGION`取代為建立叢集的 AWS 區域。

   ```
   aws cloudformation describe-stacks \
       --stack-name STACK_NAME \
       --region AWS_REGION \
       --query 'Stacks[].StackStatus'
   ```

1. 繼續進行 [步驟 3：更新 kubeconfig](#hybrid-nodes-cluster-create-kubeconfig)。

### 建立啟用混合節點的叢集 - AWS CLI
<a name="hybrid-nodes-cluster-create-cli"></a>

1. 執行下列命令以建立已啟用混合節點的 EKS 叢集和節點。執行命令之前，請使用您的設定取代下列內容。如需設定的完整清單，請參閱 [建立 Amazon EKS 叢集](create-cluster.md) 文件。

   1.  `CLUSTER_NAME`：要建立的 EKS 叢集的名稱

   1.  `AWS_REGION`：建立叢集 AWS 的區域。

   1.  `K8S_VERSION`：要用於您叢集的 Kubernetes 版本。請參閱 Amazon EKS 支援的版本。

   1.  `ROLE_ARN`：您為叢集設定的 Amazon EKS 叢集角色。如需詳細資訊，請參閱 Amazon EKS 叢集 IAM 角色。

   1.  `SUBNET1_ID`：您在先決條件步驟中建立的第一個子網路的 ID

   1.  `SUBNET2_ID`：您在先決條件步驟中建立的第二個子網路的 ID

   1.  `SG_ID`：您在先決條件步驟中建立的安全群組 ID

   1. 您可以使用 `API` 和 `API_AND_CONFIG_MAP` 作為叢集存取身分驗證模式。在以下命令中，叢集存取身分驗證模式設定為 `API_AND_CONFIG_MAP`。

   1. 您可以使用 `endpointPublicAccess` 和 `endpointPrivateAccess` 參數來啟用或停用叢集的 Kubernetes API 伺服器端點的公有和私有存取。在以下命令中，`endpointPublicAccess` 設定為 false，而 `endpointPrivateAccess` 設定為 true。

   1.  `REMOTE_NODE_CIDRS`：混合節點的內部部署節點 CIDR。

   1.  `REMOTE_POD_CIDRS` (選用)：在混合節點上執行的工作負載的內部部署 Pod CIDR。

   1. 您的內部部署節點和 Pod CIDR 區塊必須符合下列要求：

      1. 在其中一個 IPv4 RFC-1918 範圍內：`10.0.0.0/8`、 `172.16.0.0/12`或 `192.168.0.0/16`，或在 RFC 6598 定義的 CGNAT 範圍內：`100.64.0.0/10`。

      1. Amazon EKS 叢集的 `VPC CIDR` 或您的 Kubernetes Service IPv4 CIDR 不會彼此重疊。

         ```
         aws eks create-cluster \
             --name CLUSTER_NAME \
             --region AWS_REGION \
             --kubernetes-version K8S_VERSION \
             --role-arn ROLE_ARN \
             --resources-vpc-config subnetIds=SUBNET1_ID,SUBNET2_ID,securityGroupIds=SG_ID,endpointPrivateAccess=true,endpointPublicAccess=false \
             --access-config authenticationMode=API_AND_CONFIG_MAP \
             --remote-network-config '{"remoteNodeNetworks":[{"cidrs":["REMOTE_NODE_CIDRS"]}],"remotePodNetworks":[{"cidrs":["REMOTE_POD_CIDRS"]}]}'
         ```

1. 佈建叢集需要幾分鐘才能完成。您可以使用下列命令來查詢叢集的狀態。`CLUSTER_NAME` 將 取代為您建立的叢集名稱，並將 `AWS_REGION`取代為您建立叢集的 AWS 區域。在傳回的輸出為 `ACTIVE` 之前，請勿進行下一個步驟。

   ```
   aws eks describe-cluster \
       --name CLUSTER_NAME \
       --region AWS_REGION \
       --query "cluster.status"
   ```

1. 繼續進行 [步驟 3：更新 kubeconfig](#hybrid-nodes-cluster-create-kubeconfig)。

### 建立啟用混合節點的叢集 - AWS 管理主控台
<a name="hybrid-nodes-cluster-create-console"></a>

1. 在 [Amazon EKS 主控台](https://console.aws.amazon.com/eks/home#/clusters)開啟 Amazon EKS 主控台。

1. 選取 Add cluster (新增叢集)，然後選取 Create (建立)。

1. 在 Configure cluster (設定叢集) 頁面上，輸入下列欄位：

   1.  **Name** (名稱)：叢集的名稱。名稱僅包含英數字元 (區分大小寫)、連字號和底線。必須以英數字元開頭，且長度不可超過 100 個字元。名稱在您要建立叢集 AWS 的區域和 AWS 帳戶中必須是唯一的。

   1.  **叢集 IAM 角色** – 選擇您建立的 Amazon EKS 叢集 IAM 角色，以允許 Kubernetes 控制平面代表您管理 AWS 資源。

   1.  **Kubernetes version** (Kubernetes 版本) – 您的叢集使用的 Kubernetes 版本。我們建議選取最新版本，除非您需要較早版本。

   1.  **升級政策**：選擇延長或標準。

      1.  **延長：**此選項會在 Kubernetes 版本發布日期後持續為其提供 26 個月的支援。延長支援期間產生額外的每小時成本，該成本會從標準支援期間結束後開始計費。延長支援結束時，您的叢集將會自動升級至下一個版本。

      1.  **延伸：**此選項會在 Kubernetes 版本發布日期後持續為其提供 14 個月的支援。無需額外付費。標準支援結束時，您的叢集將會自動升級至下一個版本。

   1.  **叢集存取** - 選擇允許或不允許叢集管理員存取，然後選取身分驗證模式。已啟用混合節點的叢集支援下列身分驗證模式。

      1.  **EKS API**：叢集將僅從 EKS 存取項目 API 取得已經過身分驗證的 IAM 主體。

      1.  **EKS API 和 ConfigMap**：叢集將從 EKS 存取項目 API 和 `aws-auth` ConfigMap 取得已經過身分驗證的 IAM 主體。

   1.  **Secrets encryption** (秘密加密)：(選用) 選擇使用 KMS 金鑰啟用 Kubernetes 秘密的秘密加密。您也可以在建立叢集後啟用此功能。啟用此功能之前，請確定您已熟悉 [在現有叢集上使用 KMS 加密 Kubernetes 秘密](enable-kms.md) 中的資訊。

   1.  **ARC 區域轉移**：如果啟用，EKS 將向 ARC 區域轉移註冊您的叢集，以讓您能夠使用區域轉移將應用程式流量從可用區域轉移。

   1.  **Tags** (標籤) – (選用) 將任何標籤新增到您的叢集。如需詳細資訊，請參閱[使用標籤組織 Amazon EKS 資源](eks-using-tags.md)。

   1. 完成此頁面後，請選擇**下一步**。

1. 在 **Specify networking (指定網路)** 頁面上，選取下列欄位的值：

   1.  **VPC**：選擇符合 [檢視 VPC 和子網路的 Amazon EKS 聯網需求](network-reqs.md) 和 [Amazon EKS 混合節點要求](hybrid-nodes-prereqs.md) 的現有 VPC。選擇 VPC 之前，建議您先熟悉檢視 VPC、子網路和混合節點的 Amazon EKS 聯網需求中的所有要求和考量事項。建立叢集後，您無法變更要使用的 VPC。如果沒有列出 VPC，則您需要先建立一個。如需詳細資訊，請參閱 [為您的 Amazon EKS 叢集建立 Amazon VPC](creating-a-vpc.md) 和 [Amazon EKS 混合節點聯網需求](hybrid-nodes-prereqs.md)。

   1.  **Subnets** (子網路)：根據預設，前一個欄位指定的 VPC 中的所有可用子網路會預先選取。您必須選取至少兩個。

   1.  **安全群組**:(選用) 指定一或多個您希望 Amazon EKS 與其建立的網路介面相關聯的安全群組。您指定的安全群組中至少有一個必須具有適用於內部部署節點和 (選用) Pod CIDR 的傳入規則。如需詳細資訊，請參閱 [Amazon EKS 混合節點聯網需求](hybrid-nodes-networking.md)。無論您是否選擇任何安全群組，Amazon EKS 都會建立一個安全群組，以支援您的叢集和 VPC 之間的通訊。Amazon EKS 將此安全群組及您選擇的任何群組與其建立的網路介面相關聯。如需有關 Amazon EKS 建立的叢集安全群組的詳細資訊，請參閱 [檢視叢集的 Amazon EKS 安全群組要求](sec-group-reqs.md) 您可以修改 Amazon EKS 建立的叢集安全群組中的規則。

   1.  **選擇叢集 IP 位址系列**：您必須為已啟用混合節點的叢集選擇 IPv4。

   1. (選用) 選擇**設定 Kubernetes 服務 IP 位址範圍**，並指定**服務 IPv4 範圍**。

   1.  **選擇設定遠端網路以啟用混合節點**，然後為混合節點指定您的內部部署節點和 Pod CIDR。

   1. 如果在 Pod 流量離開您的內部部署主機時，您的 CNI 未使用網路位址轉譯 (NAT) 或偽裝 Pod IP 位址，您必須設定您的遠端 Pod CIDR。如果您在混合節點上執行 Webhook，則必須設定遠端 Pod CIDR。

   1. 您的內部部署節點和 Pod CIDR 區塊必須符合下列要求：

      1. 在其中一個 IPv4 RFC-1918 範圍內：`10.0.0.0/8`、 `172.16.0.0/12`或 `192.168.0.0/16`，或在 RFC 6598 定義的 CGNAT 範圍內：`100.64.0.0/10`。

      1. 您叢集的 `VPC CIDR` 或您的 Kubernetes Service IPv4 CIDR 不會彼此重疊

   1. 針對 **Cluster endpoint access** (叢集端點存取)，選取一個選項。建立叢集後，您可以變更此選項。對於已啟用混合節點的叢集，您必須選擇公有或私有。在選取非預設選項之前，請務必熟悉這些選項及其含義。如需詳細資訊，請參閱[叢集 API 伺服器端點](cluster-endpoint.md)。

   1. 完成此頁面後，請選擇**下一步**。

1. (選用) 在**設定**可觀測性頁面上，選擇要開啟的指標和控制平面記錄選項。根據預設，系統會關閉每個日誌類型。

   1. 如需有關 Prometheus 指標選項的詳細資訊，請參閱 [藉助 Prometheus 監控叢集指標](prometheus.md)。

   1. 如需 EKS 控制記錄選項的詳細資訊，請參閱 [將控制平面日誌傳送至 CloudWatch Logs](control-plane-logs.md)。

   1. 完成此頁面後，請選擇**下一步**。

1. 在 **Select add-ons** (選取附加元件) 頁面上，選擇您要新增至叢集的附加元件。

   1. 您可以視需要選擇任意數量的 **Amazon EKS 附加元件**和 ** AWS Marketplace 附加元件**。與混合節點不相容的 Amazon EKS 附加元件會標記為「與混合節點不相容」，並且附加元件具有反親和性規則，可防止其在混合節點上執行。如需詳細資訊，請參閱設定混合節點的附加元件。如果您想要安裝的 ** AWS Marketplace** 附加元件未列出，您可以在搜尋方塊中輸入文字來搜尋可用的 ** AWS Marketplace 附加元件**。您也可以依 **category** (類別)、**vendor** (廠商) 或 **pricing model** (定價模式) 進行搜尋，然後從搜尋結果中選擇附加元件。

   1. 一些附加元件，例如 CoreDNS 和 kube-proxy，是預設安裝的。如果停用任何預設附加元件，可能會影響您執行 Kubernetes 應用程式的能力。

   1. 完成此頁面後，請選擇 `Next`。

1. 在**設定選取的附加元件設定**頁面上，選取您要安裝的版本。

   1. 建立叢集後，您隨時皆可更新至更新版本。您可以在建立叢集後更新每個附加元件的組態。如需有關設定附加元件的詳細資訊，請參閱[更新 Amazon EKS 附加元件](updating-an-add-on.md)。如需與混合節點相容的附加元件版本，請參閱 [設定混合節點的附加元件](hybrid-nodes-add-ons.md)。

   1. 完成此頁面後，請選擇下一步。

1. 在 **Review and create (檢閱並建立)** 頁面上，檢閱您在先前頁面上輸入或選取的資訊。如需變更，請選擇 **Edit** (編輯)。當您感到滿意時，請選擇**建立**。在佈建叢集時，**Status** (狀態) 欄位顯示 **CREATING** (正在建立)。叢集佈建需要幾分鐘的時間。

1. 繼續進行 [步驟 3：更新 kubeconfig](#hybrid-nodes-cluster-create-kubeconfig)。

## 步驟 3：更新 kubeconfig
<a name="hybrid-nodes-cluster-create-kubeconfig"></a>

如果您使用 `eksctl` 建立叢集，則可以略過此步驟。這是因為 `eksctl` 已為您完成此步驟。透過向 `kubectl` 組態檔案新增內容，使 `kubectl` 能夠與您的叢集通訊。如需建立和更新檔案的詳細資訊，請參閱 [透過建立 kubeconfig 檔案將 kubectl 連線至 EKS 叢集](create-kubeconfig.md)。

```
aws eks update-kubeconfig --name CLUSTER_NAME --region AWS_REGION
```

範例輸出如下。

```
Added new context arn:aws: eks:AWS_REGION:111122223333:cluster/CLUSTER_NAME to /home/username/.kube/config
```

透過執行以下命令確認與叢集的通訊。

```
kubectl get svc
```

範例輸出如下。

```
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.100.0.1   <none>        443/TCP   28h
```

## 步驟 4：叢集設定
<a name="_step_4_cluster_setup"></a>

下一步，請參閱 [準備混合節點的叢集存取](hybrid-nodes-cluster-prep.md)，以啟用對混合節點的存取，進而加入叢集。

# 在現有的 Amazon EKS 叢集上啟用混合節點或修改組態
<a name="hybrid-nodes-cluster-update"></a>

本主題提供可用選項的概觀，並介紹您建立新增、變更或移除 Amazon EKS 叢集的混合節點組態時需要考量的問題。

若要讓 Amazon EKS 叢集使用混合節點，請在 `RemoteNetworkConfig` 組態中新增內部部署節點的 IP 位址 CIDR 範圍和選用的 Pod 網路。EKS 使用此 CIDR 清單來啟用叢集與內部部署網路之間的連線。如需更新叢集組態時選項的完整清單，請參閱《*Amazon EKS API 參考*》中的 [UpdateClusterConfig](https://docs.aws.amazon.com/eks/latest/APIReference/API_UpdateClusterConfig.html)。

您可以對叢集中的 EKS 混合節點聯網組態執行下列任何動作：
+  [新增遠端網路組態，以在現有叢集中啟用 EKS 混合節點。](#hybrid-nodes-cluster-enable-existing)
+  [在現有叢集中新增、變更或移除遠端節點網路或遠端 Pod 網路。](#hybrid-nodes-cluster-update-config)
+  [移除所有遠端節點網路 CIDR 範圍，以在現有叢集中停用 EKS 混合節點。](#hybrid-nodes-cluster-disable)

## 先決條件
<a name="hybrid-nodes-cluster-enable-prep"></a>
+ 為混合節點啟用 Amazon EKS 叢集之前，請確保您的環境符合 [混合節點的先決條件設定](hybrid-nodes-prereqs.md) 中概述的要求以及 [準備混合節點的聯網](hybrid-nodes-networking.md)、 [準備混合節點的作業系統](hybrid-nodes-os.md) 和 [準備混合節點的憑證](hybrid-nodes-creds.md) 中詳細說明的要求。
+ 您的叢集必須使用 IPv4 位址系列。
+ 您的叢集必須使用 `API` 或 `API_AND_CONFIG_MAP` 作為叢集身分驗證模式。修改叢集身分驗證模式的程序在 [變更驗證模式以使用存取項目](setting-up-access-entries.md) 中說明。
+ 建議您對 Amazon EKS Kubernetes API 伺服器端點使用公有或私有端點存取，但不能同時使用兩者。如果您選擇「公有和私有」，Amazon EKS Kubernetes API 伺服器端點一律會解析為在 VPC 外部執行的混合節點的公有 IP，以防止您的混合節點加入叢集。修改叢集網路存取的程序在 [叢集 API 伺服器端點](cluster-endpoint.md) 中說明。
+ 在您裝置上安裝和設定的最新版本 AWS 命令列界面 (AWS CLI)。若要檢查您目前的版本，請使用 `aws --version`。適用於 macOS 的 yum、apt-get 或 Homebrew 等套件管理員通常是最新版本 CLI AWS 後面的幾個版本。若要安裝最新版本，請參閱《 AWS 命令列界面使用者指南》中的[安裝或更新至最新版本的 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) 和[設定 AWS CLI 的設定](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config)。
+ 具有在您的 Amazon EKS 叢集上呼叫 [UpdateClusterConfig](https://docs.aws.amazon.com/eks/latest/APIReference/API_UpdateClusterConfig.html) 的許可的 [IAM 主體](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles#iam-term-principal)。
+ 將附加元件更新為與混合節點相容的版本。如需與混合節點相容的附加元件版本，請參閱 [設定混合節點的附加元件](hybrid-nodes-add-ons.md)。
+ 如果您執行的附加元件與混合節點不相容，請確保附加元件 [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) 或[部署](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)具有下列親和性規則，以防止部署到混合節點。如果尚未存在，請新增下列親和性規則。

  ```
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: eks.amazonaws.com/compute-type
            operator: NotIn
            values:
            - hybrid
  ```

## 考量事項
<a name="hybrid-nodes-cluster-enable-consider"></a>

`remoteNetworkConfig` JSON 物件在更新期間具有下列行為：
+ 您未指定的任何現有組態部分均未變更。如果您未指定 `remoteNodeNetworks` 或 `remotePodNetworks`，則該部分將保持不變。
+ 如果您要修改 CIDR 的 `remoteNodeNetworks` 或 `remotePodNetworks` 清單，則必須在最終組態中指定您想要的完整 CIDR 清單。當您指定對 `remoteNodeNetworks` 或 `remotePodNetworks` CIDR 清單的變更時，EKS 會在更新期間取代原始清單。
+ 您的內部部署節點和 Pod CIDR 區塊必須符合下列要求：

  1. 在其中一個 IPv4 RFC-1918 範圍內：10.0.0.0/8、172.16.0.0/12 或 192.168.0.0/16，或在 RFC 6598 定義的 CGNAT 範圍內： `100.64.0.0/10`

  1. Amazon EKS 叢集的 VPC 的所有 CIDR 或您的 Kubernetes Service IPv4 CIDR 不會彼此重疊。

## 在現有叢集上啟用混合節點
<a name="hybrid-nodes-cluster-enable-existing"></a>

您可以使用下列方式，在現有叢集中啟用 EKS 混合節點：
+  [AWS CloudFormation](#hybrid-nodes-cluster-enable-cfn) 
+  [AWS CLI](#hybrid-nodes-cluster-enable-cli) 
+  [AWS 管理主控台](#hybrid-nodes-cluster-enable-console) 

### 在現有叢集中啟用 EKS 混合節點 - AWS CloudFormation
<a name="hybrid-nodes-cluster-enable-cfn"></a>

1. 若要在叢集中啟用 EKS 混合節點，請將 `RemoteNodeNetwork` 和 (選用) `RemotePodNetwork` 新增至 CloudFormation 範本並更新堆疊。請注意，`RemoteNodeNetwork` 是最多包含一個 `Cidrs` 項目的清單，而 `Cidrs` 是多個 IP CIDR 範圍的清單。

   ```
   RemoteNetworkConfig:
     RemoteNodeNetworks:
       - Cidrs: [RemoteNodeCIDR]
     RemotePodNetworks:
       - Cidrs: [RemotePodCIDR]
   ```

1. 繼續進行[準備混合節點的叢集存取](hybrid-nodes-cluster-prep.md)。

### 在現有叢集中啟用 EKS 混合節點 - AWS CLI
<a name="hybrid-nodes-cluster-enable-cli"></a>

1. 執行下列命令以為您的 EKS 叢集啟用 EKS 混合節點的 `RemoteNetworkConfig`。執行命令之前，請使用您的設定取代下列內容。如需設定的完整清單，請參閱《*Amazon EKS API 參考*》中的 [UpdateClusterConfig](https://docs.aws.amazon.com/eks/latest/APIReference/API_UpdateClusterConfig.html)。

   1.  `CLUSTER_NAME`：要更新的 EKS 叢集的名稱。

   1.  `AWS_REGION`：EKS 叢集執行所在的 AWS 區域。

   1.  `REMOTE_NODE_CIDRS`：混合節點的內部部署節點 CIDR。

   1.  `REMOTE_POD_CIDRS` (選用)：在混合節點上執行的工作負載的內部部署 Pod CIDR。

      ```
      aws eks update-cluster-config \
          --name CLUSTER_NAME \
          --region AWS_REGION \
          --remote-network-config '{"remoteNodeNetworks":[{"cidrs":["REMOTE_NODE_CIDRS"]}],"remotePodNetworks":[{"cidrs":["REMOTE_POD_CIDRS"]}]}'
      ```

1. 更新叢集需要幾分鐘才能完成。您可以使用下列命令來查詢叢集的狀態。`CLUSTER_NAME` 將 取代為您修改的叢集名稱，並將 `AWS_REGION`取代為您執行叢集的 AWS 區域。在傳回的輸出為 `ACTIVE` 之前，請勿進行下一個步驟。

   ```
   aws eks describe-cluster \
       --name CLUSTER_NAME \
       --region AWS_REGION \
       --query "cluster.status"
   ```

1. 繼續進行[準備混合節點的叢集存取](hybrid-nodes-cluster-prep.md)。

### 在現有叢集中啟用 EKS 混合節點 - AWS 管理主控台
<a name="hybrid-nodes-cluster-enable-console"></a>

1. 在 [Amazon EKS 主控台](https://console.aws.amazon.com/eks/home#/clusters)開啟 Amazon EKS 主控台。

1. 選擇叢集名稱以顯示您叢集的資訊。

1. 選擇**聯網**索引標籤，然後選擇**管理**。

1. 在下拉式清單中，選擇**遠端網路**。

1.  **選擇設定遠端網路以啟用混合節點**，然後為混合節點指定您的內部部署節點和 Pod CIDR。

1. 選擇 **Save changes** (儲存變更) 以完成操作。等待叢集狀態變回**作用中**。

1. 繼續進行[準備混合節點的叢集存取](hybrid-nodes-cluster-prep.md)。

## 在現有叢集中更新混合節點組態
<a name="hybrid-nodes-cluster-update-config"></a>

您可以使用下列任何一種方式，在現有混合叢集中修改 `remoteNetworkConfig`：
+  [AWS CloudFormation](#hybrid-nodes-cluster-update-cfn) 
+  [AWS CLI](#hybrid-nodes-cluster-update-cli) 
+  [AWS 管理主控台](#hybrid-nodes-cluster-update-console) 

### 更新現有叢集 - AWS CloudFormation 中的混合組態
<a name="hybrid-nodes-cluster-update-cfn"></a>

1. 使用新的網路 CIDR 值更新您的 CloudFormation 範本。

   ```
   RemoteNetworkConfig:
     RemoteNodeNetworks:
       - Cidrs: [NEW_REMOTE_NODE_CIDRS]
     RemotePodNetworks:
       - Cidrs: [NEW_REMOTE_POD_CIDRS]
   ```
**注意**  
更新 `RemoteNodeNetworks` 或 `RemotePodNetworks` CIDR 清單時，請包含所有 CIDR (新的和現有的)。EKS 會在更新期間取代整個清單。從更新請求省略這些欄位將會保留其現有組態。

1. 使用修改過的範本更新 CloudFormation 堆疊，並等待堆疊更新完成。

### 更新現有叢集 - AWS CLI 中的混合組態
<a name="hybrid-nodes-cluster-update-cli"></a>

1. 若要修改遠端網路 CIDR，請執行下列命令。使用您的設定取代這些值：

   ```
   aws eks update-cluster-config
   --name CLUSTER_NAME
   --region AWS_REGION
   --remote-network-config '{"remoteNodeNetworks":[{"cidrs":["NEW_REMOTE_NODE_CIDRS"]}],"remotePodNetworks":[{"cidrs":["NEW_REMOTE_POD_CIDRS"]}]}'
   ```
**注意**  
更新 `remoteNodeNetworks` 或 `remotePodNetworks` CIDR 清單時，請包含所有 CIDR (新的和現有的)。EKS 會在更新期間取代整個清單。從更新請求省略這些欄位將會保留其現有組態。

1. 等待叢集狀態變回「作用中」，然後再繼續。

### 更新現有叢集中的混合組態 - AWS 管理主控台
<a name="hybrid-nodes-cluster-update-console"></a>

1. 在 [Amazon EKS 主控台](https://console.aws.amazon.com/eks/home#/clusters)開啟 Amazon EKS 主控台。

1. 選擇叢集名稱以顯示您叢集的資訊。

1. 選擇**聯網**索引標籤，然後選擇**管理**。

1. 在下拉式清單中，選擇**遠端網路**。

1. 視需要更新 `Remote node networks` 和 `Remote pod networks - Optional` 下的 CIDR。

1. 選擇**儲存變更**，然後等待叢集狀態返回**作用中**。

## 在現有叢集中停用混合節點
<a name="hybrid-nodes-cluster-disable"></a>

您可以使用下列方式，在現有叢集中停用 EKS 混合節點：
+  [AWS CloudFormation](#hybrid-nodes-cluster-disable-cfn) 
+  [AWS CLI](#hybrid-nodes-cluster-disable-cli) 
+  [AWS 管理主控台](#hybrid-nodes-cluster-disable-console) 

### 在現有叢集中停用 EKS 混合節點 - AWS CloudFormation
<a name="hybrid-nodes-cluster-disable-cfn"></a>

1. 若要停用叢集中的 EKS 混合節點，請在 CloudFormation 範本中將 `RemoteNodeNetworks` 和 `RemotePodNetworks` 設定為空陣列，並更新堆疊。

   ```
   RemoteNetworkConfig:
     RemoteNodeNetworks: []
     RemotePodNetworks: []
   ```

### 在現有叢集中停用 EKS 混合節點 - AWS CLI
<a name="hybrid-nodes-cluster-disable-cli"></a>

1. 執行下列命令以從 EKS 叢集中移除 `RemoteNetworkConfig`。執行命令之前，請使用您的設定取代下列內容。如需設定的完整清單，請參閱《*Amazon EKS API 參考*》中的 [UpdateClusterConfig](https://docs.aws.amazon.com/eks/latest/APIReference/API_UpdateClusterConfig.html)。

   1.  `CLUSTER_NAME`：要更新的 EKS 叢集的名稱。

   1.  `AWS_REGION`：EKS 叢集執行所在的 AWS 區域。

      ```
      aws eks update-cluster-config \
          --name CLUSTER_NAME \
          --region AWS_REGION \
          --remote-network-config '{"remoteNodeNetworks":[],"remotePodNetworks":[]}'
      ```

1. 更新叢集需要幾分鐘才能完成。您可以使用下列命令來查詢叢集的狀態。`CLUSTER_NAME` 將 取代為您修改的叢集名稱，並將 `AWS_REGION`取代為您執行叢集的 AWS 區域。在傳回的輸出為 `ACTIVE` 之前，請勿進行下一個步驟。

   ```
   aws eks describe-cluster \
       --name CLUSTER_NAME \
       --region AWS_REGION \
       --query "cluster.status"
   ```

### 在現有叢集中停用 EKS 混合節點 - AWS 管理主控台
<a name="hybrid-nodes-cluster-disable-console"></a>

1. 在 [Amazon EKS 主控台](https://console.aws.amazon.com/eks/home#/clusters)開啟 Amazon EKS 主控台。

1. 選擇叢集名稱以顯示您叢集的資訊。

1. 選擇**聯網**索引標籤，然後選擇**管理**。

1. 在下拉式清單中，選擇**遠端網路**。

1. 選擇**設定遠端網路以啟用混合節點**，然後移除 `Remote node networks` 和 `Remote pod networks - Optional` 下的所有 CIDR。

1. 選擇 **Save changes** (儲存變更) 以完成操作。等待叢集狀態變回**作用中**。

# 準備混合節點的叢集存取
<a name="hybrid-nodes-cluster-prep"></a>

將混合節點連線至 Amazon EKS 叢集之前，您必須啟用具有 Kubernetes 許可的混合節點 IAM 角色，才能加入叢集。如需如何建立混合節點 IAM 角色的資訊，請參閱 [準備混合節點的憑證](hybrid-nodes-creds.md)。Amazon EKS 支援兩種方式將 IAM 主體與 Kubernetes 角色型存取控制 (RBAC)、Amazon EKS 存取項目和 `aws-auth` ConfigMap 建立關聯。如需有關 Amazon EKS 存取管理的詳細資訊，請參閱 [授予 IAM 使用者和角色對 Kubernetes APIs存取權](grant-k8s-access.md)。

使用以下程序，以將您的混合節點 IAM 角色與 Kubernetes 許可建立關聯。若要使用 Amazon EKS 存取項目，您的叢集必須已使用 `API` 或 `API_AND_CONFIG_MAP` 身分驗證模式建立。若要使用 `aws-auth` ConfigMap，您的叢集必須已使用 `API_AND_CONFIG_MAP` 身分驗證模式建立。已啟用混合節點的 Amazon EKS 叢集不支援僅限 `CONFIG_MAP` 的身分驗證模式。

## 使用混合節點的 Amazon EKS 存取項目 IAM 角色
<a name="_using_amazon_eks_access_entries_for_hybrid_nodes_iam_role"></a>

名為 HYBRID\$1LINUX 的混合節點 Amazon EKS 存取項目類型，可與 IAM 角色搭配使用。使用此存取項目類型時，使用者名稱會自動設定為 system:node:\$1\$1SessionName\$1\$1。如需建立存取項目的詳細資訊，請參閱 [建立存取項目](creating-access-entries.md)。

### AWS CLI
<a name="shared_aws_cli"></a>

1. 您必須在裝置上安裝並設定最新版本的 AWS CLI。若要檢查您目前的版本，請使用 `aws --version`。適用於 macOS 的 yum、apt-get 或 Homebrew 等套件管理員通常是最新版本 CLI AWS 後面的幾個版本。若要安裝最新版本，請參閱《 AWS 命令列界面使用者指南》中的使用 aws 設定安裝 和快速組態。

1. 使用下列命令建立您的存取項目。將 CLUSTER\$1NAME 取代為您的叢集名稱，並將 HYBRID\$1NODES\$1ROLE\$1ARN 取代為您在 [準備混合節點的憑證](hybrid-nodes-creds.md) 的步驟中建立的角色的 ARN。

   ```
   aws eks create-access-entry --cluster-name CLUSTER_NAME \
       --principal-arn HYBRID_NODES_ROLE_ARN \
       --type HYBRID_LINUX
   ```

### AWS 管理主控台
<a name="hybrid-nodes-cluster-prep-console"></a>

1. 在 [Amazon EKS 主控台](https://console.aws.amazon.com/eks/home#/clusters)開啟 Amazon EKS 主控台。

1. 選擇已啟用混合節點的叢集的名稱。

1. 選擇**存取**索引標籤。

1. 選擇**建立存取項目**。

1. 針對 **IAM 主體**，選取您在 [準備混合節點的憑證](hybrid-nodes-creds.md) 的步驟中建立的混合節點 IAM 角色。

1. 針對**類型**，選取**混合 Linux**。

1. (選用) 您可以使用**標籤**為存取項目指派標籤。例如，為了更輕鬆地找到具有相同標籤的所有資源而指定標籤。

1. 選擇**跳至檢閱和建立**。您無法將政策新增至混合 Linux 存取項目或變更其存取範圍。

1. 檢查存取項目的組態。如果有任何內容看起來不正確，請選擇**上一步**以返回上一步並修正錯誤。如果組態正確，請選擇**建立**。

## 針對混合節點 IAM 角色,使用 aws-auth ConfigMap
<a name="_using_aws_auth_configmap_for_hybrid_nodes_iam_role"></a>

在下列步驟中，您將使用您在 `aws-auth` 的步驟中建立的混合節點 IAM 角色的 ARN 來建立或更新 [準備混合節點的憑證](hybrid-nodes-creds.md) ConfigMap。

1. 檢查您的叢集是否已有現有的 `aws-auth` ConfigMap。請注意，如果您使用特定 `kubeconfig` 檔案，則請使用 `--kubeconfig` 旗標。

   ```
   kubectl describe configmap -n kube-system aws-auth
   ```

1. 如果看到 `aws-auth` ConfigMap，則請視需要進行更新。

   1. 開啟 ConfigMap 進行編輯。

      ```
      kubectl edit -n kube-system configmap/aws-auth
      ```

   1. 視需要新增 `mapRoles` 個項目。使用混合節點 IAM 角色的 ARN 取代 `HYBRID_NODES_ROLE_ARN`。請注意，`{{SessionName}}` 是在 ConfigMap 中儲存的正確範本格式。請勿將其取代為其他值。

      ```
      data:
        mapRoles: |
        - groups:
          - system:bootstrappers
          - system:nodes
          rolearn: HYBRID_NODES_ROLE_ARN
          username: system:node:{{SessionName}}
      ```

   1. 儲存檔案並結束您的文字編輯器。

1. 如果您的叢集沒有現有的 `aws-auth` ConfigMap，則請使用下列命令予以建立。使用混合節點 IAM 角色的 ARN 取代 `HYBRID_NODES_ROLE_ARN`。請注意，`{{SessionName}}` 是在 ConfigMap 中儲存的正確範本格式。請勿將其取代為其他值。

   ```
   kubectl apply -f=/dev/stdin <<-EOF
   apiVersion: v1
   kind: ConfigMap
   metadata:
     name: aws-auth
     namespace: kube-system
   data:
     mapRoles: |
     - groups:
       - system:bootstrappers
       - system:nodes
       rolearn: HYBRID_NODES_ROLE_ARN
       username: system:node:{{SessionName}}
   EOF
   ```

# 在混合節點上執行內部部署工作負載
<a name="hybrid-nodes-tutorial"></a>

在已啟用混合節點的 EKS 叢集中，您可以使用您在 AWS 雲端中使用的相同 Amazon EKS 叢集、功能和工具，在自己的基礎結構上執行內部部署和邊緣應用程式。

下列各節包含使用混合節點的逐步說明。

**Topics**
+ [連接混合節點](hybrid-nodes-join.md)
+ [使用 Bottlerocket 連接混合節點](hybrid-nodes-bottlerocket.md)
+ [升級混合節點](hybrid-nodes-upgrade.md)
+ [修補程式混合節點](hybrid-nodes-security.md)
+ [刪除混合節點](hybrid-nodes-remove.md)

# 連接混合節點
<a name="hybrid-nodes-join"></a>

**注意**  
下列步驟適用於執行 Bottlerocket 以外的相容作業系統的混合節點。如需連線執行 Bottlerocket 的混合節點的步驟，請參閱 [使用 Bottlerocket 連接混合節點](hybrid-nodes-bottlerocket.md)。

本主題會說明如何將混合節點連接至 Amazon EKS 叢集。混合節點加入叢集後，其即會在 Amazon EKS 主控台和 Kubernetes 相容工具 (例如 kubectl) 中顯示為「未就緒」狀態。完成此頁面上的步驟後，請繼續 [設定混合節點的 CNI](hybrid-nodes-cni.md)，以讓您的混合節點準備好執行應用程式。

## 先決條件
<a name="_prerequisites"></a>

將混合節點連接至 Amazon EKS 叢集之前，請確保您已完成先決條件步驟。
+ 您的內部部署環境與託管您的 Amazon EKS 叢集的 AWS 區域之間已建立網路連線。如需詳細資訊，請參閱「[準備混合節點的聯網](hybrid-nodes-networking.md)」。
+ 您已在內部部署主機上安裝了適用於混合節點的相容作業系統。如需詳細資訊，請參閱「[準備混合節點的作業系統](hybrid-nodes-os.md)」。
+ 您已建立混合節點 IAM 角色，並設定內部部署憑證提供者 (AWS Systems Manager 混合啟用或 AWS IAM Roles Anywhere)。如需詳細資訊，請參閱「[準備混合節點的憑證](hybrid-nodes-creds.md)」。
+ 您已建立了已啟用混合節點的 Amazon EKS 叢集。如需詳細資訊，請參閱「[建立具有混合節點的 Amazon EKS 叢集](hybrid-nodes-cluster-create.md)」。
+ 您已將混合節點 IAM 角色與 Kubernetes 角色型存取控制 (RBAC) 許可建立關聯。如需詳細資訊，請參閱「[準備混合節點的叢集存取](hybrid-nodes-cluster-prep.md)」。

## 步驟 1：在每個內部部署主機上安裝混合節點 CLI (`nodeadm`)
<a name="_step_1_install_the_hybrid_nodes_cli_nodeadm_on_each_on_premises_host"></a>

如果您在預先建置的作業系統映像中包含 Amazon EKS 混合節點 CLI (`nodeadm`)，則可以略過此步驟。如需 `nodeadm` 混合節點版本的詳細資訊，請參閱 [混合節點 `nodeadm` 參考](hybrid-nodes-nodeadm.md)。

`nodeadm` 的混合節點版本託管於前端為 Amazon CloudFront 的 Amazon S3 中。若要在每個內部部署主機上安裝 `nodeadm`，您可以從內部部署主機執行下列命令。

 **對於 x86\$164 主機：**

```
curl -OL 'https://hybrid-assets.eks.amazonaws.com/releases/latest/bin/linux/amd64/nodeadm'
```

 **對於 ARM 主機** 

```
curl -OL 'https://hybrid-assets.eks.amazonaws.com/releases/latest/bin/linux/arm64/nodeadm'
```

在每個主機上，為下載的二進位檔新增可執行檔許可。

```
chmod +x nodeadm
```

## 步驟 2：使用 `nodeadm` 安裝混合節點相依性
<a name="_step_2_install_the_hybrid_nodes_dependencies_with_nodeadm"></a>

如果您要在預先建置的作業系統映像中安裝混合節點相依性，則可以略過此步驟。`nodeadm install` 命令可用於安裝混合節點所需的所有相依性。混合節點相依性包括 containerd、kubelet、kubectl 和 AWS SSM 或 AWS IAM Roles Anywhere 元件。如需 `nodeadm install` 所安裝元件和檔案位置的詳細資訊，請參閱 [混合節點 `nodeadm` 參考](hybrid-nodes-nodeadm.md)。如需 `nodeadm install` 程序必須在內部部署防火牆中允許的網域的詳細資訊，請參閱混合節點的 [準備混合節點的聯網](hybrid-nodes-networking.md)。

執行以下命令，以在您的內部部署主機上安裝混合節點相依性。以下命令必須由主機上具有 sudo/root 存取權的使用者執行。

**重要**  
混合節點 CLI (`nodeadm`) 必須由主機上具有 sudo/root 存取權的使用者執行。
+ 使用 Amazon EKS 叢集的 Kubernetes 次要版本取代 `K8S_VERSION`，例如 `1.31`。如需支援的 Kubernetes 版本的清單，請參閱 [Amazon EKS 支援的版本](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)。
+ 使用您正在使用的內部部署憑證提供者取代 `CREDS_PROVIDER`。AWS SSM 的有效值為 `ssm`，而 AWS IAM Roles Anywhere 的有效值為 `iam-ra`。

```
nodeadm install K8S_VERSION --credential-provider CREDS_PROVIDER
```

## 步驟 3：將混合節點連接至您的叢集
<a name="_step_3_connect_hybrid_nodes_to_your_cluster"></a>

將混合節點連接至您的叢集之前，請確保您已獲得內部部署防火牆和叢集的安全群組中的必要存取權，允許往返 Amazon EKS 控制平面與混合節點之間的通訊。此步驟中的大多數問題都與防火牆組態、安全群組組態或混合節點 IAM 角色組態相關。

**重要**  
混合節點 CLI (`nodeadm`) 必須由主機上具有 sudo/root 存取權的使用者執行。

1. 在每個主機上建立包含部署值的 `nodeConfig.yaml` 檔案。如需可用組態設定的完整說明，請參閱 [混合節點 `nodeadm` 參考](hybrid-nodes-nodeadm.md)。如果您的混合節點 IAM 角色沒有 `eks:DescribeCluster` 動作的許可，您必須在 `nodeConfig.yaml` 的叢集區段中傳遞 Kubernetes API 端點、叢集 CA 套件和 Kubernetes Service IPv4 CIDR。

   1. 如果您為內部部署憑證提供者使用 AWS SSM 混合啟用，請使用下列 `nodeConfig.yaml` 範例。

      1. 使用您叢集的名稱取代 `CLUSTER_NAME`。

      1. 使用託管叢集的 AWS 區域取代 `AWS_REGION`。例如 `us-west-2`。

      1. 使用您在建立 AWS SSM 混合啟用時收到的啟用代碼取代 `ACTIVATION_CODE`。如需詳細資訊，請參閱「[準備混合節點的憑證](hybrid-nodes-creds.md)」。

      1. 使用您在建立 AWS SSM 混合啟用時收到的啟用 ID 取代 `ACTIVATION_ID`。您可以從 AWS Systems Manager 主控台或 AWS CLI `aws ssm describe-activations` 命令擷取此資訊。

         ```
         apiVersion: node.eks.aws/v1alpha1
         kind: NodeConfig
         spec:
           cluster:
             name: CLUSTER_NAME
             region: AWS_REGION
           hybrid:
             ssm:
               activationCode: ACTIVATION_CODE
               activationId: ACTIVATION_ID
         ```

   1. 如果您為內部部署憑證提供者使用 AWS IAM Roles Anywhere，請使用下列 `nodeConfig.yaml` 範例。

      1. 使用您叢集的名稱取代 `CLUSTER_NAME`。

      1. 使用託管叢集的 AWS 區域取代 `AWS_REGION`。例如 `us-west-2`。

      1. 使用您節點的名稱取代 `NODE_NAME`。如果您已使用 `"sts:RoleSessionName": "${aws:PrincipalTag/x509Subject/CN}"` 資源條件設定混合節點 IAM 角色的信任政策，則節點名稱必須與主機上的憑證的 CN 相符。您使用的 `nodeName` 不可超過 64 個字元。

      1. 使用您在準備混合節點憑證的步驟中設定的信任錨的 ARN 取代 `TRUST_ANCHOR_ARN`。

      1. 使用您在 [準備混合節點的憑證](hybrid-nodes-creds.md) 的步驟中設定的信任錨的 ARN 取代 `PROFILE_ARN`。

      1. 使用混合節點 IAM 角色的 ARN 取代 `ROLE_ARN`。

      1. 使用磁碟中節點憑證的路徑取代 `CERTIFICATE_PATH`。如未指定，預設為 `/etc/iam/pki/server.pem`。

      1. 使用磁碟中憑證私有金鑰的路徑取代 `KEY_PATH`。如未指定，預設為 `/etc/iam/pki/server.key`。

         ```
         apiVersion: node.eks.aws/v1alpha1
         kind: NodeConfig
         spec:
           cluster:
             name: CLUSTER_NAME
             region: AWS_REGION
           hybrid:
             iamRolesAnywhere:
               nodeName: NODE_NAME
               trustAnchorArn: TRUST_ANCHOR_ARN
               profileArn: PROFILE_ARN
               roleArn: ROLE_ARN
               certificatePath: CERTIFICATE_PATH
               privateKeyPath: KEY_PATH
         ```

1. 使用您的 `nodeConfig.yaml` 執行 `nodeadm init` 命令，以將混合節點連接至 Amazon EKS 叢集。

   ```
   nodeadm init -c file://nodeConfig.yaml
   ```

如果上述命令成功完成，則您的混合節點已加入您的 Amazon EKS 叢集。您可以在 Amazon EKS 主控台中透過導覽至叢集的 Compute (運算) 索引標籤 ([確保 IAM 主體具有檢視許可](view-kubernetes-resources.md#view-kubernetes-resources-permissions)) 或使用 `kubectl get nodes` 來驗證這一點。

**重要**  
您的節點將處於 `Not Ready` 狀態，這在意料之中，因為您的混合節點上並未執行 CNI。如果您的節點未加入叢集，請參閱 [故障診斷混合節點](hybrid-nodes-troubleshooting.md)。

## 步驟 4：設定混合節點的 CNI
<a name="_step_4_configure_a_cni_for_hybrid_nodes"></a>

要讓您的混合節點準備好執行應用程式，請繼續執行 [設定混合節點的 CNI](hybrid-nodes-cni.md) 上的步驟。

# 使用 Bottlerocket 連接混合節點
<a name="hybrid-nodes-bottlerocket"></a>

本主題會說明如何將執行 Bottlerocket 的混合節點連接至 Amazon EKS 叢集。[Bottlerocket](https://aws.amazon.com/bottlerocket/) 是由 贊助和支援的開放原始碼 Linux 發行版本 AWS。Bottlerocket 專為託管容器工作負載而打造。利用 Bottlerocket，您可以自動化容器基礎結構的更新，進而改善容器化部署的可用性並降低營運成本。Bottlerocket 僅包含執行容器的基本軟體，可改善資源用量、減少安全威脅，並降低管理開銷。

EKS 混合節點僅支援 Bottlerocket 版本 1.37.0 及更新版本的 VMware 變體。Bottlerocket 的 VMware 變體適用於 Kubernetes 版本 1.28 及更新版本。這些變體的作業系統映像包括 kubelet、containerd、aws-iam-authenticator 和 EKS 混合節點的其他軟體先決條件。您可以使用 Bottlerocket [設定](https://github.com/bottlerocket-os/bottlerocket#settings)檔案來設定這些元件，其中該檔案包含 Bottlerocket 引導和管理員容器的 base64 編碼使用者資料。設定這些設定可讓 Bottlerocket 使用您的混合節點憑證提供者，進而驗證叢集的混合節點。混合節點加入叢集後，其即會在 Amazon EKS 主控台和 Kubernetes 相容工具 (例如 `kubectl`) 中顯示為「`Not Ready`」狀態。完成此頁面上的步驟後，請繼續 [設定混合節點的 CNI](hybrid-nodes-cni.md)，以讓您的混合節點準備好執行應用程式。

## 先決條件
<a name="_prerequisites"></a>

將混合節點連接至 Amazon EKS 叢集之前，請確保您已完成先決條件步驟。
+ 您可以從內部部署環境連線至託管 Amazon EKS 叢集 AWS 的區域。如需詳細資訊，請參閱[準備混合節點的聯網](hybrid-nodes-networking.md)。
+ 您已建立混合節點 IAM 角色，並設定內部部署憑證提供者 (AWS Systems Manager 混合啟用或 AWS IAM Roles Anywhere)。如需詳細資訊，請參閱[準備混合節點的憑證](hybrid-nodes-creds.md)。
+ 您已建立了已啟用混合節點的 Amazon EKS 叢集。如需詳細資訊，請參閱[建立具有混合節點的 Amazon EKS 叢集](hybrid-nodes-cluster-create.md)。
+ 您已將混合節點 IAM 角色與 Kubernetes 角色型存取控制 (RBAC) 許可建立關聯。如需詳細資訊，請參閱[準備混合節點的叢集存取](hybrid-nodes-cluster-prep.md)。

## 步驟 1：建立 Bottlerocket 設定 TOML 檔案
<a name="_step_1_create_the_bottlerocket_settings_toml_file"></a>

若要為混合節點設定 Bottlerocket，您需要建立具有必要組態的 `settings.toml` 檔案。TOML 檔案的內容會根據您使用的憑證提供者 (SSM 或 IAM Roles Anywhere) 而有所不同。佈建 Bottlerocket 執行個體時，此檔案將會作為使用者資料傳遞。

**注意**  
以下提供的 TOML 檔案僅代表將 Bottlerocket VMWare 機器初始化為 EKS 叢集上的節點所需的最低設定。Bottlerocket 提供廣泛的設定，可處理多種不同的使用案例，因此對於混合節點初始化以外的其他組態選項，請參閱 [Bottlerocket 文件](https://bottlerocket.dev/en)，以取得您使用之 Bottlerocket 版本的所有文件化設定的完整清單 （例如，[以下](https://bottlerocket.dev/en/os/1.51.x/api/settings-index)是 Bottlerocket 1.51.x 可用的所有設定）。

### SSM
<a name="_ssm"></a>

如果您使用 AWS Systems Manager 做為登入資料提供者，請使用下列內容建立`settings.toml`檔案：

```
[settings.kubernetes]
cluster-name = "<cluster-name>"
api-server = "<api-server-endpoint>"
cluster-certificate = "<cluster-certificate-authority>"
hostname-override = "<hostname>"
provider-id = "eks-hybrid:///<region>/<cluster-name>/<hostname>"
authentication-mode = "aws"
cloud-provider = ""
server-tls-bootstrap = true

[settings.network]
hostname = "<hostname>"

[settings.aws]
region = "<region>"

[settings.kubernetes.credential-providers.ecr-credential-provider]
enabled = true
cache-duration = "12h"
image-patterns = [
    "*.dkr.ecr.*.amazonaws.com",
    "*.dkr.ecr.*.amazonaws.com.rproxy.govskope.ca.cn",
    "*.dkr.ecr.*.amazonaws.eu",
    "*.dkr.ecr-fips.*.amazonaws.com",
    "*.dkr.ecr-fips.*.amazonaws.eu",
    "public.ecr.aws"
]

[settings.kubernetes.node-labels]
"eks.amazonaws.com/compute-type" = "hybrid"
"eks.amazonaws.com/hybrid-credential-provider" = "ssm"

[settings.host-containers.admin]
enabled = true
user-data = "<base64-encoded-admin-container-userdata>"

[settings.bootstrap-containers.eks-hybrid-setup]
mode = "always"
user-data = "<base64-encoded-bootstrap-container-userdata>"

[settings.host-containers.control]
enabled = true
```

使用下列值取代預留位置：
+  `<cluster-name>`：Amazon EKS 叢集的名稱。
+  `<api-server-endpoint>`：叢集的 API 伺服器端點。
+  `<cluster-certificate-authority>`：叢集的 base64 編碼 CA 套件。
+  `<region>`：託管叢集 AWS 的區域，例如 "us-east-1"。
+  `<hostname>`：Bottlerocket 執行個體的主機名稱，其也會設定為節點名稱。這可以是您選擇的任何唯一值，不過必須遵循 [Kubernetes 物件命名慣例](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names)。此外，您使用的主機名稱不可超過 64 個字元。注意：使用 SSM 提供商時，在向 SSM 註冊執行個體之後，此主機名稱和節點名稱將會取代為受管執行個體 ID (例如 `mi-*` ID)。
+  `<base64-encoded-admin-container-userdata>`：Bottlerocket 管理員容器組態的 base64 編碼內容。啟用管理員容器可讓您使用 SSH 連接至 Bottlerocket 執行個體，以進行系統勘探和偵錯。雖然這並非必要的設定，但我們建議您將其啟用，以便進行故障診斷。如需使用管理員容器進行身分驗證的詳細資訊，請參閱 [Bottlerocket 管理員容器文件](https://github.com/bottlerocket-os/bottlerocket-admin-container#authenticating-with-the-admin-container)。管理員容器採用 JSON 格式的 SSH 使用者和金鑰輸入，例如：

```
{
  "user": "<ssh-user>",
  "ssh": {
    "authorized-keys": [
      "<ssh-authorized-key>"
    ]
  }
}
```
+  `<base64-encoded-bootstrap-container-userdata>`：Bottlerocket 引導容器組態的 base64 編碼內容。如需其組態的詳細資訊，請參閱 [Bottlerocket 引導容器文件](https://github.com/bottlerocket-os/bottlerocket-bootstrap-container)。引導容器負責將執行個體註冊為 AWS SSM 受管執行個體，並將其聯結為 Amazon EKS 叢集上的 Kubernetes 節點。傳遞至引導容器的使用者資料採用命令調用的形式，而其接受您先前建立的 SSM 混合啟用代碼和 ID 作為輸入：

```
eks-hybrid-ssm-setup --activation-id=<activation-id> --activation-code=<activation-code> --region=<region>
```

### IAM Roles Anywhere
<a name="_iam_roles_anywhere"></a>

如果您使用 AWS IAM Roles Anywhere 做為登入資料提供者，請使用下列內容建立`settings.toml`檔案：

```
[settings.kubernetes]
cluster-name = "<cluster-name>"
api-server = "<api-server-endpoint>"
cluster-certificate = "<cluster-certificate-authority>"
hostname-override = "<hostname>"
provider-id = "eks-hybrid:///<region>/<cluster-name>/<hostname>"
authentication-mode = "aws"
cloud-provider = ""
server-tls-bootstrap = true

[settings.network]
hostname = "<hostname>"

[settings.aws]
region = "<region>"
config = "<base64-encoded-aws-config-file>"

[settings.kubernetes.credential-providers.ecr-credential-provider]
enabled = true
cache-duration = "12h"
image-patterns = [
    "*.dkr.ecr.*.amazonaws.com",
    "*.dkr.ecr.*.amazonaws.com.rproxy.govskope.ca.cn",
    "*.dkr.ecr.*.amazonaws.eu",
    "*.dkr.ecr-fips.*.amazonaws.com",
    "*.dkr.ecr-fips.*.amazonaws.eu",
    "public.ecr.aws"
]

[settings.kubernetes.node-labels]
"eks.amazonaws.com/compute-type" = "hybrid"
"eks.amazonaws.com/hybrid-credential-provider" = "iam-ra"

[settings.host-containers.admin]
enabled = true
user-data = "<base64-encoded-admin-container-userdata>"

[settings.bootstrap-containers.eks-hybrid-setup]
mode = "always"
user-data = "<base64-encoded-bootstrap-container-userdata>"
```

使用下列值取代預留位置：
+  `<cluster-name>`：Amazon EKS 叢集的名稱。
+  `<api-server-endpoint>`：叢集的 API 伺服器端點。
+  `<cluster-certificate-authority>`：叢集的 base64 編碼 CA 套件。
+  `<region>`：託管叢集 AWS 的區域，例如 "us-east-1"
+  `<hostname>`：Bottlerocket 執行個體的主機名稱，其也會設定為節點名稱。這可以是您選擇的任何唯一值，不過必須遵循 [Kubernetes 物件命名慣例](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names)。此外，您使用的主機名稱不可超過 64 個字元。注意：使用 IAM-RA 提供商時，如果您已使用 `"sts:RoleSessionName": "${aws:PrincipalTag/x509Subject/CN}"` 資源條件設定混合節點 IAM 角色的信任政策，則節點名稱必須與主機上的憑證的 CN 相符。
+  `<base64-encoded-aws-config-file>`：組態檔案的 base64 AWS 編碼內容。檔案的內容應如下所示：

```
[default]
credential_process = aws_signing_helper credential-process --certificate /root/.aws/node.crt --private-key /root/.aws/node.key --profile-arn <profile-arn> --role-arn <role-arn> --trust-anchor-arn <trust-anchor-arn> --role-session-name <role-session-name>
```
+  `<base64-encoded-admin-container-userdata>`：Bottlerocket 管理員容器組態的 base64 編碼內容。啟用管理員容器可讓您使用 SSH 連接至 Bottlerocket 執行個體，以進行系統勘探和偵錯。雖然這並非必要的設定，但我們建議您將其啟用，以便進行故障診斷。如需使用管理員容器進行身分驗證的詳細資訊，請參閱 [Bottlerocket 管理員容器文件](https://github.com/bottlerocket-os/bottlerocket-admin-container#authenticating-with-the-admin-container)。管理員容器採用 JSON 格式的 SSH 使用者和金鑰輸入，例如：

```
{
  "user": "<ssh-user>",
  "ssh": {
    "authorized-keys": [
      "<ssh-authorized-key>"
    ]
  }
}
```
+  `<base64-encoded-bootstrap-container-userdata>`：Bottlerocket 引導容器組態的 base64 編碼內容。如需其組態的詳細資訊，請參閱 [Bottlerocket 引導容器文件](https://github.com/bottlerocket-os/bottlerocket-bootstrap-container)。引導容器負責在執行個體上建立 IAM Roles Anywhere 主機憑證和憑證私有金鑰檔案。然後，`aws_signing_helper` 會使用這些憑證來取得臨時憑證，以便與您的 Amazon EKS 叢集進行身分驗證。傳遞至引導容器的使用者資料採用命令調用的形式，而其接受您先前建立的憑證和私有金鑰的內容作為輸入：

```
eks-hybrid-iam-ra-setup --certificate=<certificate> --key=<private-key>
```

## 步驟 2：使用使用者資料佈建 Bottlerocket vSphere VM
<a name="_step_2_provision_the_bottlerocket_vsphere_vm_with_user_data"></a>

建構 TOML 檔案後，請在 vSphere VM 建立期間將其作為使用者資料進行傳遞。請記住，必須在 VM 第一次開機之前設定使用者資料。因此，您需要在建立執行個體時提供它，或者如果您想要提前建立 VM，則 VM 必須處於關機狀態，直到您為其設定使用者資料為止。例如，如果使用 `govc` CLI：

### 第一次建立 VM
<a name="_creating_vm_for_the_first_time"></a>

```
govc vm.create \
  -on=true \
  -c=2 \
  -m=4096 \
  -net.adapter=<network-adapter> \
  -net=<network-name> \
  -e guestinfo.userdata.encoding="base64" \
  -e guestinfo.userdata="$(base64 -w0 settings.toml)" \
  -template=<template-name> \
  <vm-name>
```

### 更新現有 VM 的使用者資料
<a name="_updating_user_data_for_an_existing_vm"></a>

```
govc vm.create \
    -on=false \
    -c=2 \
    -m=4096 \
    -net.adapter=<network-adapter> \
    -net=<network-name> \
    -template=<template-name> \
    <vm-name>

govc vm.change
    -vm <vm-name> \
    -e guestinfo.userdata="$(base64 -w0 settings.toml)" \
    -e guestinfo.userdata.encoding="base64"

govc vm.power -on <vm-name>
```

在上述區段中，`-e guestinfo.userdata.encoding="base64"` 選項會指定使用者資料採用 base64 編碼。`-e guestinfo.userdata` 選項會將 `settings.toml` 檔案的 base64 編碼內容作為使用者資料傳遞至 Bottlerocket 執行個體。使用特定值取代預留位置，例如 Bottlerocket OVA 範本和聯網詳細資訊。

## 步驟 3：驗證混合節點連線
<a name="_step_3_verify_the_hybrid_node_connection"></a>

Bottlerocket 執行個體啟動後，其會嘗試加入您的 Amazon EKS 叢集。您可以導覽至叢集的「運算」索引標籤，或執行下列命令，以在 Amazon EKS 主控台中驗證連線：

```
kubectl get nodes
```

**重要**  
您的節點將處於 `Not Ready` 狀態，這在意料之中，因為您的混合節點上並未執行 CNI。如果您的節點未加入叢集，請參閱 [故障診斷混合節點](hybrid-nodes-troubleshooting.md)。

## 步驟 4：設定混合節點的 CNI
<a name="_step_4_configure_a_cni_for_hybrid_nodes"></a>

要讓您的混合節點準備好執行應用程式，請繼續執行 [設定混合節點的 CNI](hybrid-nodes-cni.md) 上的步驟。

# 升級叢集的混合節點
<a name="hybrid-nodes-upgrade"></a>

升級混合節點的指引類似於在 Amazon EC2 中執行的自我管理的 Amazon EKS 節點。我們建議您在目標 Kubernetes 版本上建立新的混合節點、將現有的應用程式從容移轉至新 Kubernetes 版本上的混合節點，接著從叢集移除舊 Kubernetes 版本上的混合節點。開始升級之前，請務必檢閱 [Amazon EKS 最佳實務](https://docs.aws.amazon.com/eks/latest/best-practices/cluster-upgrades.html)，以了解升級的相關資訊。Amazon EKS 混合節點對包含雲端節點的 Amazon EKS 叢集具有相同的 [Kubernetes 版本支援](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)，包括標準支援和延長支援。

Amazon EKS 混合節點遵循與上游 Kubernetes 相同的[節點版本差異政策](https://kubernetes.io/releases/version-skew-policy/#supported-version-skew)。Amazon EKS 混合節點不能使用比 Amazon EKS 控制平面更新的版本，而混合節點最多可能比 Amazon EKS 控制平面次要版本低三個 Kubernetes 次要版本。

如果您沒有備用容量，可在目標 Kubernetes 版本上建立新的混合節點以進行切換移轉升級策略，則您也可以使用 Amazon EKS 混合節點 CLI (`nodeadm`) 來就地升級混合節點的 Kubernetes 版本。

**重要**  
如果您要使用 `nodeadm` 就地升級混合節點，則在關閉舊版 Kubernetes 元件以及安裝和啟動新的 Kubernetes 版本元件的過程中，節點可能會出現停機時間。

## 先決條件
<a name="_prerequisites"></a>

升級之前，請確認您已完成下列先決條件。
+ 混合節點升級的目標 Kubernetes 版本必須等於或小於 Amazon EKS 控制平面版本。
+ 如果您遵循切換移轉升級策略，則在目標 Kubernetes 版本上安裝的新混合節點必須符合 [混合節點的先決條件設定](hybrid-nodes-prereqs.md) 要求。這包括您在 Amazon EKS 叢集建立期間傳遞的遠端節點網路 CIDR 內的 IP 位址。
+ 對於切換移轉和就地升級，混合節點必須能夠存取[必要網域](hybrid-nodes-networking.md#hybrid-nodes-networking-on-prem)，以提取混合節點相依性的新版本。
+ 您必須在用來與 Amazon EKS Kubernetes API 端點互動的本機電腦或執行個體上安裝 kubectl。
+ 您的 CNI 版本必須支援您要升級到的 Kubernetes 版本。如果不能，則請在先升級 CNI 版本，然後再升級您的混合節點。如需詳細資訊，請參閱「[設定混合節點的 CNI](hybrid-nodes-cni.md)」。

## 切換移轉 (藍綠) 升級
<a name="hybrid-nodes-upgrade-cutover"></a>

 *切換移轉升級*是指使用目標 Kubernetes 版本在新主機上建立新的混合節點、將現有的應用程式從容移轉至目標 Kubernetes 版本上的新混合節點，以及從叢集移除舊 Kubernetes 版本上的混合節點的過程。此策略也稱為藍綠移轉。

1. 請遵循 [連接混合節點](hybrid-nodes-join.md) 步驟，將您的新主機連接為混合節點。執行 `nodeadm install` 命令時，請使用您的目標 Kubernetes 版本。

1. 啟用目標 Kubernetes 版本上的新混合節點與舊 Kubernetes 版本上的混合節點之間的通訊。此組態可讓您在將工作負載移轉至目標 Kubernetes 版本上的混合節點時，Pod 之間能夠彼此進行通訊。

1. 確認目標 Kubernetes 版本上的混合節點已成功加入叢集，且狀態為就緒。

1. 使用下列命令，將每個您想要移除的節點標記為不可排程。這樣就不會在您要取代的節點上排程或重新排程新的 Pod。如需詳細資訊，請參閱 Kubernetes 文件中的 [kubectl cordon](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_cordon/)。使用舊 Kubernetes 版本上的混合節點的名稱取代 `NODE_NAME`。

   ```
   kubectl cordon NODE_NAME
   ```

   您可以使用下列程式碼片段來識別及包圍隔離特定 Kubernetes 版本 (在此情況下為 `1.28`) 的所有節點。

   ```
   K8S_VERSION=1.28
   for node in $(kubectl get nodes -o json | jq --arg K8S_VERSION "$K8S_VERSION" -r '.items[] | select(.status.nodeInfo.kubeletVersion | match("\($K8S_VERSION)")).metadata.name')
   do
       echo "Cordoning $node"
       kubectl cordon $node
   done
   ```

1. 如果您目前的部署在混合節點上執行的 CoreDNS 複本少於兩個，請將部署擴增為至少兩個複本。我們建議您在混合節點上執行至少兩個 CoreDNS 複本，以在正常操作期間實現彈性。

   ```
   kubectl scale deployments/coredns --replicas=2 -n kube-system
   ```

1. 使用下列命令，耗盡清空您想要從叢集移除的舊 Kubernetes 版本上的每個混合節點。如需耗盡節點的詳細資訊，請參閱 Kubernetes 文件中的[安全地耗盡節點](https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/)。使用舊 Kubernetes 版本上的混合節點的名稱取代 `NODE_NAME`。

   ```
   kubectl drain NODE_NAME --ignore-daemonsets --delete-emptydir-data
   ```

   您可以使用下列程式碼片段來識別及耗盡特定 Kubernetes 版本 (在此情況下為 `1.28`) 的所有節點。

   ```
   K8S_VERSION=1.28
   for node in $(kubectl get nodes -o json | jq --arg K8S_VERSION "$K8S_VERSION" -r '.items[] | select(.status.nodeInfo.kubeletVersion | match("\($K8S_VERSION)")).metadata.name')
   do
       echo "Draining $node"
       kubectl drain $node --ignore-daemonsets --delete-emptydir-data
   done
   ```

1. 您可以使用 `nodeadm` 從主機停止和移除混合節點成品。您必須與擁有 root/sudo 權限的使用者一同執行 `nodeadm`。根據預設，如果節點上還有剩餘的 Pod，則 `nodeadm uninstall` 不會繼續。如需更多資訊，請參閱[混合節點 `nodeadm` 參考](hybrid-nodes-nodeadm.md)。

   ```
   nodeadm uninstall
   ```

1. 若停止並解除安裝混合節點成品，則請從您的叢集中移除節點資源。

   ```
   kubectl delete node node-name
   ```

   您可以使用下列程式碼片段來識別及刪除特定 Kubernetes 版本 (在此情況下為 `1.28`) 的所有節點。

   ```
   K8S_VERSION=1.28
   for node in $(kubectl get nodes -o json | jq --arg K8S_VERSION "$K8S_VERSION" -r '.items[] | select(.status.nodeInfo.kubeletVersion | match("\($K8S_VERSION)")).metadata.name')
   do
       echo "Deleting $node"
       kubectl delete node $node
   done
   ```

1. 視您選擇的 CNI 而定，在執行上述步驟後，您的混合節點上可能會有成品剩餘。如需詳細資訊，請參閱「[設定混合節點的 CNI](hybrid-nodes-cni.md)」。

## 就地升級
<a name="hybrid-nodes-upgrade-inplace"></a>

就地升級程序是指使用 `nodeadm upgrade` 來升級混合節點的 Kubernetes 版本，而無需使用新的實體或虛擬主機和切換移轉策略。`nodeadm upgrade` 程序會關閉在混合節點上執行的現有的較舊 Kubernetes 元件、解除安裝現有的較舊 Kubernetes 元件、安裝新的目標 Kubernetes 元件，以及啟動新的目標 Kubernetes 元件。強烈建議您一次升級一個節點，以最大限度地降低對混合節點上執行的應用程式的影響。此程序的持續時間取決於您的網路頻寬和延遲。

1. 使用下列命令，將您要升級的節點標記為不可排程。這樣就不會在您要升級的節點上排程或重新排程新的 Pod。如需詳細資訊，請參閱 Kubernetes 文件中的 [kubectl cordon](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_cordon/)。使用您要升級的混合節點的名稱取代 `NODE_NAME`

   ```
   kubectl cordon NODE_NAME
   ```

1. 使用下列命令，耗盡您要升級的節點。如需耗盡節點的詳細資訊，請參閱 Kubernetes 文件中的[安全地耗盡節點](https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/)。使用您要升級的混合節點的名稱取代 `NODE_NAME`。

   ```
   kubectl drain NODE_NAME --ignore-daemonsets --delete-emptydir-data
   ```

1. 在您要升級的混合節點上執行 `nodeadm upgrade`。您必須與擁有 root/sudo 權限的使用者一同執行 `nodeadm`。節點的名稱會透過 AWS SSM 和 IAM Roles Anywhere AWS 憑證提供者的升級加以保留。您無法在升級程序期間變更憑證提供者。如需 `nodeConfig.yaml` 的組態值，請參閱 [混合節點 `nodeadm` 參考](hybrid-nodes-nodeadm.md)。使用您要升級的目標 Kubernetes 版本取代 `K8S_VERSION`。

   ```
   nodeadm upgrade K8S_VERSION -c file://nodeConfig.yaml
   ```

1. 若要允許於升級之後在節點上排程 Pod，請輸入下列內容。使用節點的名稱取代 `NODE_NAME`。

   ```
   kubectl uncordon NODE_NAME
   ```

1. 觀察混合節點的狀態，等待節點關閉，然後以就緒狀態重新啟動新的 Kubernetes 版本。

   ```
   kubectl get nodes -o wide -w
   ```

# 混合節點的修補程式安全更新
<a name="hybrid-nodes-security"></a>

本主題會說明針對混合節點上執行的特定套件和相依性，就地執行安全更新修補的程序。基於最佳實務，我們建議您定期更新您的混合節點，以接收 CVE 和安全修補程式。

如需升級 Kubernetes 版本的步驟，請參閱 [升級叢集的混合節點](hybrid-nodes-upgrade.md)。

可能需要安全修補的軟體範例之一是 `containerd`。

## `Containerd`
<a name="_containerd"></a>

 `containerd` 是 EKS 混合節點的標準 Kubernetes 容器執行時期和核心相依性，可用於管理容器生命週期，包括提取映像和管理容器執行。在混合節點上，您可以透過 [nodeadm CLI](https://docs.aws.amazon.com/eks/latest/userguide/hybrid-nodes-nodeadm.html) 或手動安裝 `containerd`。視節點的作業系統而定，`nodeadm` 會從作業系統分散式套件或 Docker 套件安裝 `containerd`。

當 `containerd` 中的 CVE 發布後，您可透過下列選項將您混合節點上的 `containerd` 升級至修補程式版本。

## 步驟 1：檢查修補程式是否已發布至套件管理工具
<a name="_step_1_check_if_the_patch_published_to_package_managers"></a>

您可以參考對應的安全公告，檢查 CVE `containerd` 修補程式是否已發布至每個各自的作業系統套件管理工具：
+  [Amazon Linux 2023](https://alas.aws.amazon.com/alas2023.html) 
+  [RHEL](https://access.redhat.com/security/security-updates/security-advisories) 
+  [Ubuntu 20.04](https://ubuntu.com/security/notices?order=newest&release=focal) 
+  [Ubuntu 22.04](https://ubuntu.com/security/notices?order=newest&release=jammy) 
+  [Ubuntu 24.04](https://ubuntu.com/security/notices?order=newest&release=noble) 

如果您使用 Docker 儲存庫作為 `containerd` 的來源，您可以檢查 [Docker 安全公告](https://docs.docker.com/security/security-announcements/)，以識別 Docker 儲存庫中提供的修補版本。

## 步驟 2：選擇安裝修補程式的方法
<a name="_step_2_choose_the_method_to_install_the_patch"></a>

您可以透過三種方法來在節點上就地修補和安裝安全升級。您可使用哪種方法取決於套件管理工具中的作業系統是否提供該修補程式：

1. 使用發布至套件管理工具的 `nodeadm upgrade` 安裝修補程式，請參閱[步驟 2 a](#hybrid-nodes-security-nodeadm)。

1. 使用套件管理工具直接安裝修補程式，請參閱[步驟 2 b](#hybrid-nodes-security-package)。

1. 安裝尚未在套件管理工具中發布的自訂修補程式。請注意，對於 `containerd` 的自訂修補程式，存在特殊考量，請參閱[步驟 2 c](#hybrid-nodes-security-manual)。

## 步驟 2 a：使用 `nodeadm upgrade` 進行修補
<a name="hybrid-nodes-security-nodeadm"></a>

確認 `containerd` CVE 修補程式已發布至作業系統或 Docker 儲存庫 (Apt 或 RPM) 後，您可以使用 `nodeadm upgrade` 命令升級至 `containerd` 的最新版本。由於這並非 Kubernetes 版本升級，您必須將目前的 Kubernetes 版本傳遞至 `nodeadm` 升級命令。

```
nodeadm upgrade K8S_VERSION --config-source file:///root/nodeConfig.yaml
```

## 步驟 2 b：使用作業系統套件管理工具進行修補
<a name="hybrid-nodes-security-package"></a>

或者，您也可以透過各自的套件管理工具進行更新，並使用它來升級 `containerd` 套件，如下所示。

 **Amazon Linux 2023** 

```
sudo yum update -y
sudo yum install -y containerd
```

 **RHEL** 

```
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo
sudo yum update -y
sudo yum install -y containerd
```

 **Ubuntu** 

```
sudo mkdir -p /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update -y
sudo apt install -y --only-upgrade containerd.io
```

## 步驟 2 c：套件管理工具中尚未發布的 `Containerd` CVE 修補程式
<a name="hybrid-nodes-security-manual"></a>

如果 `containerd` 的修補程式版本僅可透過套件管理工具以外的其他方式獲得，例如在 GitHub 發行版本中，則您可以從官方 GitHub 網站安裝 `containerd`。

1. 如果機器已將叢集加入為混合節點，則需要執行 `nodeadm uninstall` 命令。

1. 安裝官方 `containerd` 二進位檔。您可以使用 GitHub 上的步驟[官方安裝步驟](https://github.com/containerd/containerd/blob/main/docs/getting-started.md#option-1-from-the-official-binaries)。

1. 執行 `nodeadm install` 命令，並將 `--containerd-source` 引數設定為 `none`，因此可透過 `nodeadm` 略過 `containerd` 安裝。對於節點正在執行的任何作業系統，您可以使用 `containerd` 來源中的 `none` 值。

   ```
   nodeadm install K8S_VERSION --credential-provider CREDS_PROVIDER --containerd-source none
   ```

# 移除混合節點
<a name="hybrid-nodes-remove"></a>

本主題會說明如何從 Amazon EKS 叢集中刪除混合節點。您必須使用您選擇的 Kubernetes 相容工具 (例如 [kubectl](https://kubernetes.io/docs/reference/kubectl/)) 刪除混合節點。節點物件從 Amazon EKS 叢集移除時，即會停止收取混合節點的費用。如需混合節點定價的詳細資訊，請參閱 [Amazon EKS 定價](https://aws.amazon.com/eks/pricing/)。

**重要**  
移除節點會對節點上執行的工作負載產生干擾。刪除混合節點之前，建議您先耗盡節點，以將 Pod 移動至另一個作用中的節點。如需耗盡節點的詳細資訊，請參閱 Kubernetes 文件中的[安全地耗盡節點](https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/)。

從您用來與 Amazon EKS 叢集的 Kubernetes API 端點互動的本機機器或執行個體，執行下列 kubectl 步驟。如果您使用特定 `kubeconfig` 檔案，則請使用 `--kubeconfig` 旗標。

## 步驟 1：列出您的節點
<a name="_step_1_list_your_nodes"></a>

```
kubectl get nodes
```

## 步驟 2：耗盡您的節點
<a name="_step_2_drain_your_node"></a>

如需 `kubectl drain` 命令的詳細資訊，請參閱 Kubernetes 文件中的 [kubectl 耗盡](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_drain/)。

```
kubectl drain --ignore-daemonsets <node-name>
```

## 步驟 3：停止並解除安裝混合節點成品
<a name="_step_3_stop_and_uninstall_hybrid_nodes_artifacts"></a>

您可以使用 Amazon EKS 混合節點 CLI (`nodeadm`)，以從主機停止和移除混合節點成品。您必須與擁有 root/sudo 權限的使用者一同執行 `nodeadm`。根據預設，如果節點上還有剩餘的 Pod，則 `nodeadm uninstall` 不會繼續。如果您使用 AWS Systems Manager (SSM) 作為憑證提供者，則 `nodeadm uninstall` 命令會將主機取消註冊為 AWS SSM 受管執行個體。如需詳細資訊，請參閱 [混合節點 `nodeadm` 參考](hybrid-nodes-nodeadm.md)。

```
nodeadm uninstall
```

## 步驟 4：從叢集中刪除節點
<a name="_step_4_delete_your_node_from_the_cluster"></a>

若停止並解除安裝混合節點成品，則請從您的叢集中移除節點資源。

```
kubectl delete node <node-name>
```

## 步驟 5：檢查剩餘的成品
<a name="_step_5_check_for_remaining_artifacts"></a>

視您選擇的 CNI 而定，在執行上述步驟後，您的混合節點上可能會有成品剩餘。如需詳細資訊，請參閱「[設定混合節點的 CNI](hybrid-nodes-cni.md)」。

# 設定混合節點的應用程式聯網、附加元件和 Webhook
<a name="hybrid-nodes-configure"></a>

為混合節點建立 EKS 叢集後，請設定應用程式聯網的其他功能 (CNI、BGP、傳入、負載平衡、網路政策)、附加元件、Webhook 和代理設定。如需與混合節點相容的 EKS 和社群附加元件的完整清單，請參閱 [設定混合節點的附加元件](hybrid-nodes-add-ons.md)。

 **EKS 叢集洞察** EKS 包括混合節點設定中錯誤組態的洞察檢查，這些設定可能會使叢集或工作負載的功能受損。如需有關叢集洞察的詳細資訊，請參閱 [利用叢集洞見為 Kubernetes 版本升級做好準備，並為錯誤組態進行故障診斷](cluster-insights.md)。

以下清單列出了您可與混合節點搭配使用的常見功能和附加元件：
+  **容器聯網介面 (CNI)**：AWS 支援 [Cilium](https://docs.cilium.io/en/stable/index.html) 作為混合節點的 CNI。如需詳細資訊，請參閱 [設定混合節點的 CNI](hybrid-nodes-cni.md)。請注意，AWS VPC CNI 無法與混合節點搭配使用。
+  **CoreDNS 和 `kube-proxy` **：CoreDNS 和 `kube-proxy` 會在混合節點加入 EKS 叢集時自動安裝。這些附加元件可以在叢集建立後作為 EKS 附加元件進行管理。
+  **傳入及負載平衡**：您可以將 AWS Load Balancer 控制器和 Application Load Balancer (ALB) 或 Network Load Balancer (NLB) 與在混合節點上執行的工作負載的目標類型 `ip` 搭配使用。針對在混合節點上執行的工作負載，AWS 支援 Cilium 的內建傳入、閘道和 Kubernetes Service 負載平衡功能。如需詳細資訊，請參閱[設定混合節點的 Kubernetes Ingress](hybrid-nodes-ingress.md)及[為混合節點設定 LoadBalancer 類型的服務](hybrid-nodes-load-balancing.md)。
+  **指標**：您可以使用 Amazon Managed Service for Prometheus (AMP) 無代理程式湊集器、AWS Ditro for Open Telemetry (ADOT) 和具有混合節點的 Amazon CloudWatch 可觀測性代理程式。若要對混合節點上的 Pod 指標使用 AMP 無代理程式湊集器，您的 Pod 必須可從您用於 EKS 叢集的 VPC 存取。
+  **日誌**：您可以為已啟用混合節點的叢集啟用 EKS 控制平面記錄。您可以使用 ADOT EKS 附加元件和 Amazon CloudWatch 可觀測性代理程式 EKS 附加元件進行混合節點和 Pod 記錄。
+  **Pod 身分識別和 IRSA**：您可以搭配混合節點上執行的應用程式使用 EKS Pod 身分識別和服務帳戶的 IAM 角色 (IRSA)，以為在混合節點上執行的 Pod 與其他 AWS 服務啟用精細存取。
+  **Webhook**：如果您正在執行 Webhook，請參閱 [設定混合節點的 Webhook](hybrid-nodes-webhooks.md) 以了解相關考量事項和步驟，即如果您無法讓內部部署 Pod 網路可路由，則可選擇在雲端節點上執行 Webhook。
+  **代理**：如果您在內部部署環境中為離開資料中心或邊緣環境的流量使用代理伺服器，則您可以將混合節點和叢集設定為使用代理伺服器。如需詳細資訊，請參閱 [設定混合節點的代理](hybrid-nodes-proxy.md)。

**Topics**
+ [設定混合節點的 CNI](hybrid-nodes-cni.md)
+ [設定混合節點的附加元件](hybrid-nodes-add-ons.md)
+ [設定混合節點的 Webhook](hybrid-nodes-webhooks.md)
+ [設定混合節點的代理](hybrid-nodes-proxy.md)
+ [設定混合節點的 Cilium BGP](hybrid-nodes-cilium-bgp.md)
+ [設定混合節點的 Kubernetes Ingress](hybrid-nodes-ingress.md)
+ [為混合節點設定 LoadBalancer 類型的服務](hybrid-nodes-load-balancing.md)
+ [設定混合節點的 Kubernetes 網路政策](hybrid-nodes-network-policies.md)

# 設定混合節點的 CNI
<a name="hybrid-nodes-cni"></a>

Cilium 是 AWS Amazon EKS 混合節點支援的容器聯網界面 (CNI)。您必須為混合節點安裝 CNI，才能做好準備以為工作負載提供服務。在 CNI 執行之前，混合節點會顯示為 `Not Ready` 狀態。您可以使用您選擇的工具 (例如 Helm) 來管理 CNI。此頁面的說明涵蓋 Cilium 生命週期管理 (安裝、升級、刪除)。如需如何為傳入、載入平衡和網路政策設定 Cilium，請參閱 [Cilium Ingress 和 Cilium Gateway 概觀](hybrid-nodes-ingress.md#hybrid-nodes-ingress-cilium)、[服務類型 LoadBalancer](hybrid-nodes-ingress.md#hybrid-nodes-ingress-cilium-loadbalancer) 和 [設定混合節點的 Kubernetes 網路政策](hybrid-nodes-network-policies.md)。

在 AWS 雲端節點上執行 AWS 時，不支援 Cilium。Amazon VPC CNI 與混合節點不相容，且 VPC CNI 已針對 `eks.amazonaws.com/compute-type: hybrid` 標籤設定反親和性。

此頁面上先前的 Calico 文件已移至 [EKS 混合範例儲存庫](https://github.com/aws-samples/eks-hybrid-examples)。

## 版本相容性
<a name="hybrid-nodes-cilium-version-compatibility"></a>

Amazon EKS 支援的每個 Kubernetes 版本`v1.18.x`都支援 Cilium 版本 `v1.17.x`和 EKS 混合節點。

**注意**  
 **Cilium v1.18.3 核心需求**：由於核心需求 (Linux 核心 >= 5.10)，不支援 Cilium v1.18.3：
+ Ubuntu 20.04
+ Red Hat Enterprise Linux (RHEL) 8

如需系統需求，請參閱 [Cilium 系統需求](https://docs.cilium.io/en/stable/operations/system_requirements/)。

如需 Amazon EKS 支援的 Kubernetes 版本，請參閱 [Kubernetes 版本支援](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)。EKS 混合節點對包含雲端節點的 Amazon EKS 叢集具有相同的 Kubernetes 版本支援。

## 支援的功能
<a name="hybrid-nodes-cilium-support"></a>

 AWS 維護以開放原始碼 Cilium [專案為基礎的 EKS 混合節點的 Cilium](https://github.com/cilium/cilium) 組建。若要從 取得 Cilium AWS 的支援，您必須使用 AWS維護的 Cilium 組建和支援的 Cilium 版本。

 AWS 為下列 Cilium 功能的預設組態提供技術支援，以便與 EKS 混合節點搭配使用。如果您計劃在 AWS 支援範圍之外使用功能，建議您取得 Cilium 的替代商業支援，或擁有內部專業知識來故障診斷並對 Cilium 專案提供修正。


| Cilium 功能 | 支援者 AWS  | 
| --- | --- | 
|  Kubernetes 網路一致性  |  是  | 
|  核心叢集連線  |  是  | 
|  IP 系列  |  IPv4  | 
|  生命週期管理  |  Helm  | 
|  聯網模式  |  VXLAN 封裝  | 
|  IP 位址管理 (IPAM)  |  Cilium IPAM 叢集範圍  | 
|  網路政策  |  Kubernetes 網路政策  | 
|  邊界閘道協定 (BGP)  |  Cilium BGP 控制平面  | 
|  Kubernetes Ingress  |  Cilium Ingress、Cilium Gateway  | 
|  Service LoadBalancer IP 配置  |  Cilium Load Balancer IPAM  | 
|  Service LoadBalancer IP 位址公告  |  Cilium BGP 控制平面  | 
|  kube-proxy 取代  |  是  | 

## Cilium 考量事項
<a name="hybrid-nodes-cilium-considerations"></a>
+  **Helm 儲存庫** - 在 Amazon EKS Cilium/Cilium 的 Amazon Elastic Container Registry Public (Amazon ECR Public) 中 AWS 託管 Cilium Helm Chart。 [https://gallery.ecr.aws/eks/cilium/cilium](https://gallery.ecr.aws/eks/cilium/cilium)可用的版本包括：
  + Cilium 1.17.9 版： `oci://public.ecr.aws/eks/cilium/cilium:1.17.9-0`
  + Cilium 1.18.3 版： `oci://public.ecr.aws/eks/cilium/cilium:1.18.3-0`

    本主題中的命令使用此儲存庫。請注意，某些 `helm repo` 命令不適用於 Amazon ECR Public 中的 Helm 儲存庫，因此您無法從本機 Helm 儲存庫名稱引用此儲存庫。反之，大多數命令中會使用完整的 URI。
+ 根據預設，Cilium 已設定為以覆蓋/通道模式執行，並以 VXLAN 作為[封裝法](https://docs.cilium.io/en/stable/network/concepts/routing/#encapsulation)。此模式對基礎實體網路的要求最低。
+ 根據預設，Cilium 會將離開叢集的所有 Pod 流量的來源 IP 位址[偽裝](https://docs.cilium.io/en/stable/network/concepts/masquerading/)為節點的 IP 位址。如果您停用偽裝，則您的 Pod CIDR 必須在內部部署網路上可路由。
+ 如果您在混合節點上執行 Webhook，您的 Pod CIDR 必須在內部部署網路上可路由。如果您的 Pod CIDR 在內部部署網路上不可路由，那麼建議您在相同叢集的雲端節點上執行 Webhook。如需詳細資訊，請參閱 [設定混合節點的 Webhook](hybrid-nodes-webhooks.md) 和 [準備混合節點的聯網](hybrid-nodes-networking.md)。
+  AWS 建議使用 Cilium 的內建 BGP 功能，讓您的 Pod CIDRs可在內部部署網路上路由。如需如何使用混合節點設定 Cilium BGP 的詳細資訊，請參閱 [設定混合節點的 Cilium BGP](hybrid-nodes-cilium-bgp.md)。
+ Cilium 中的預設 IP 位址管理 (IPAM) 稱為[叢集範圍](https://docs.cilium.io/en/stable/network/concepts/ipam/cluster-pool/)，而 Cilium 運算子會基於使用者設定的 Pod CIDR 為每個節點配置 IP 位址。

## 在混合節點上安裝 Cilium
<a name="hybrid-nodes-cilium-install"></a>

### 程序
<a name="_procedure"></a>

1. 建立稱為 `cilium-values.yaml` 的 YAML 檔案。下列範例透過為 Cilium 代理程式和運算子設定 `eks.amazonaws.com/compute-type: hybrid` 標籤的親和性，將 Cilium 設定為僅在混合節點上執行。
   + 使用您為 EKS 叢集*遠端 Pod 網路*設定的相同 Pod CIDR，進而設定 `clusterPoolIpv4PodCIDRList`。例如 `10.100.0.0/24`。Cilium 運算子會從設定的 `clusterPoolIpv4PodCIDRList` IP 空間內配置 IP 位址配量。您的 Pod CIDR 不得與內部部署節點 CIDR、VPC CIDR 或 Kubernetes Service CIDR 重疊。
   + 基於每個節點所需的 Pod 來設定 `clusterPoolIpv4MaskSize`。例如，對於每個節點 128 個 Pod 的 /25 區段大小，其值為 `25`。
   + 在叢集上部署 Cilium 之後，請勿變更 `clusterPoolIpv4PodCIDRList` 或 `clusterPoolIpv4MaskSize`，如需詳細資訊，請參閱[展開叢集集區](https://docs.cilium.io/en/stable/network/concepts/ipam/cluster-pool/#expanding-the-cluster-pool)。
   + 如果您以 kube-proxy 取代模式執行 Cilium，請在 Helm 值中設定 `kubeProxyReplacement: "true"`，並確保您並未在與 Cilium 相同的節點上執行現有的 kube-proxy 部署。
   + 以下範例會停用 Cilium 用於 L7 網路政策和傳入的 Envoy Layer 7 (L7) 代理。如需詳細資訊，請參閱[設定混合節點的 Kubernetes 網路政策](hybrid-nodes-network-policies.md)及[Cilium Ingress 和 Cilium Gateway 概觀](hybrid-nodes-ingress.md#hybrid-nodes-ingress-cilium)。
   + 以下範例會設定 `loadBalancer.serviceTopology`：如果您為服務設定服務流量分佈，其會正確運作，則此為 `true`。如需詳細資訊，請參閱[設定服務流量分佈](hybrid-nodes-webhooks.md#hybrid-nodes-mixed-service-traffic-distribution)。
   + 如需 Cilium 的 Helm 值的完整清單，請參閱 Cilium 文件中的 [Helm 參考](https://docs.cilium.io/en/stable/helm-reference/)。

     ```
     affinity:
       nodeAffinity:
         requiredDuringSchedulingIgnoredDuringExecution:
           nodeSelectorTerms:
           - matchExpressions:
             - key: eks.amazonaws.com/compute-type
               operator: In
               values:
               - hybrid
     ipam:
       mode: cluster-pool
       operator:
         clusterPoolIPv4MaskSize: 25
         clusterPoolIPv4PodCIDRList:
         - POD_CIDR
     loadBalancer:
       serviceTopology: true
     operator:
       affinity:
         nodeAffinity:
           requiredDuringSchedulingIgnoredDuringExecution:
             nodeSelectorTerms:
             - matchExpressions:
               - key: eks.amazonaws.com/compute-type
                 operator: In
                 values:
                   - hybrid
       unmanagedPodWatcher:
         restart: false
     loadBalancer:
       serviceTopology: true
     envoy:
       enabled: false
     kubeProxyReplacement: "false"
     ```

1. 在叢集上安裝 Cilium。
   + `CILIUM_VERSION` 將 取代為 Cilium 版本 （例如 `1.17.9-0`或 `1.18.3-0`)。建議為 Cilium 次要版本使用最新的修補程式版本。
   + 確保您的節點符合您所選版本的核心需求。Cilium v1.18.3 需要 Linux 核心 >= 5.10。
   + 如果您使用特定的 kubeconfig 檔案，請搭配 Helm 安裝命令使用 `--kubeconfig` 旗標。

     ```
     helm install cilium oci://public.ecr.aws/eks/cilium/cilium \
         --version CILIUM_VERSION \
         --namespace kube-system \
         --values cilium-values.yaml
     ```

1. 使用下列命令來確認您的 Cilium 安裝是否成功。您應該會看到 `cilium-operator` 部署和每個混合節點上執行的 `cilium-agent`。此外，您的混合節點現在應該處於狀態 `Ready`。如需如何設定 Cilium BGP 將 Pod CIDR 公告至內部部署網路的相關資訊，請繼續 [設定混合節點的 Cilium BGP](hybrid-nodes-cilium-bgp.md)。

   ```
   kubectl get pods -n kube-system
   ```

   ```
   NAME                              READY   STATUS    RESTARTS   AGE
   cilium-jjjn8                      1/1     Running   0          11m
   cilium-operator-d4f4d7fcb-sc5xn   1/1     Running   0          11m
   ```

   ```
   kubectl get nodes
   ```

   ```
   NAME                   STATUS   ROLES    AGE   VERSION
   mi-04a2cf999b7112233   Ready    <none>   19m   v1.31.0-eks-a737599
   ```

## 在混合節點上升級 Cilium
<a name="hybrid-nodes-cilium-upgrade"></a>

升級 Cilium 部署之前，請仔細檢閱 [Cilium 升級文件](https://docs.cilium.io/en/v1.17/operations/upgrade/)和升級備註，以了解目標 Cilium 版本中的變更。

1. 請確保您已在命令列環境中安裝了 `helm` CLI。如需安裝說明，請參閱 [Helm 文件](https://helm.sh/docs/intro/quickstart/)。

1. 執行 Cilium 升級預檢檢查。使用目標 Cilium 版本取代 `CILIUM_VERSION`。我們建議您為 Cilium 次要版本執行最新的修補程式版本。您可以在 Cilium 文件的[穩定版本部分](https://github.com/cilium/cilium#stable-releases)中找到指定次要 Cilium 版本的最新修補程式版本。

   ```
   helm install cilium-preflight oci://public.ecr.aws/eks/cilium/cilium --version CILIUM_VERSION \
     --namespace=kube-system \
     --set preflight.enabled=true \
     --set agent=false \
     --set operator.enabled=false
   ```

1. 套用 `cilium-preflight.yaml` 之後，請確保 `READY` Pod 的數量與執行的 Cilium Pod 數量相同。

   ```
   kubectl get ds -n kube-system | sed -n '1p;/cilium/p'
   ```

   ```
   NAME                      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
   cilium                    2         2         2       2            2           <none>          1h20m
   cilium-pre-flight-check   2         2         2       2            2           <none>          7m15s
   ```

1. 只要就緒 Pod 的數量相等，請確保 Cilium 預檢部署也標記為 READY 1/1。如果顯示 READY 0/1，請參閱 [CNP 驗證](https://docs.cilium.io/en/v1.17/operations/upgrade/#cnp-validation)部分並解決部署問題，然後再繼續升級。

   ```
   kubectl get deployment -n kube-system cilium-pre-flight-check -w
   ```

   ```
   NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
   cilium-pre-flight-check   1/1     1            0           12s
   ```

1. 刪除預檢

   ```
   helm uninstall cilium-preflight --namespace kube-system
   ```

1. 在執行 `helm upgrade` 命令之前，請保留 `existing-cilium-values.yaml` 中部署的值，或在執行升級命令時，使用 `--set` 命令列選項進行設定。升級操作會覆寫 Cilium ConfigMap，因此請務必在升級時傳遞您的組態值。

   ```
   helm get values cilium --namespace kube-system -o yaml > existing-cilium-values.yaml
   ```

1. 在一般叢集操作期間，所有 Cilium 元件都應執行相同的版本。下列步驟說明如何將所有元件從一個穩定版本升級至更新的穩定版本。從一個次要版本升級到另一個次要版本時，建議先升級到現有 Cilium 次要版本的最新修補程式版本。若要將中斷降至最低，請將 `upgradeCompatibility` 選項設定為您在此叢集中安裝的初始 Cilium 版本。

   ```
   helm upgrade cilium oci://public.ecr.aws/eks/cilium/cilium --version CILIUM_VERSION \
     --namespace kube-system \
     --set upgradeCompatibility=1.X \
     -f existing-cilium-values.yaml
   ```

1. (選用) 如果您因為問題而需要復原升級，請執行下列命令。

   ```
   helm history cilium --namespace kube-system
   helm rollback cilium [REVISION] --namespace kube-system
   ```

## 從混合節點中刪除 Cilium
<a name="hybrid-nodes-cilium-delete"></a>

1. 執行下列命令以從叢集中解除安裝所有 Cilium 元件。請注意，解除安裝 CNI 可能會影響節點和 Pod 的運作狀態，因此不應在生產叢集上執行。

   ```
   helm uninstall cilium --namespace kube-system
   ```

   從叢集移除 CNI 時，依預設不會移除 Cilium 設定的介面和路由，如需詳細資訊，請參閱 [GitHub 問題](https://github.com/cilium/cilium/issues/34289)。

1. 若要清除磁碟上的組態檔案和資源，如果您使用標準組態目錄，則可以移除 GitHub 上 Cilium 儲存庫中 [`cni-uninstall.sh` 指令碼](https://github.com/cilium/cilium/blob/main/plugins/cilium-cni/cni-uninstall.sh)顯示的檔案。

1. 若要從叢集中移除 Cilium 自訂資源定義 (CRD)，您可以執行下列命令。

   ```
   kubectl get crds -oname | grep "cilium" | xargs kubectl delete
   ```

# 設定混合節點的附加元件
<a name="hybrid-nodes-add-ons"></a>

此頁面說明在 Amazon EKS 混合節點上執行 AWS 附加元件和社群附加元件的考量。若要進一步了解 Amazon EKS 附加元件，以及從叢集建立、升級和移除附加元件的程序，請參閱 [Amazon EKS 附加元件](eks-add-ons.md)。除非此頁面另有說明，否則對於具有混合節點的 Amazon EKS 叢集，建立、升級和移除 Amazon EKS 附加元件的程序與在 AWS Cloud 中執行節點的 Amazon EKS 叢集相同。只有此頁面中包含的附加元件已經過驗證，可與 Amazon EKS 混合節點相容。

下列 AWS 附加元件與 Amazon EKS 混合節點相容。


|  AWS 附加元件 | 相容的附加元件版本 | 
| --- | --- | 
|  kube-proxy  |  v1.25.14-eksbuild.2 及更新版本  | 
|  CoreDNS  |  v1.9.3-eksbuild.7 及更新版本  | 
|   AWS Distro for OpenTelemetry (ADOT)  |  v0.102.1-eksbuild.2 及更新版本  | 
|  CloudWatch 可觀測性代理程式  |  v2.2.1-eksbuild.1 及更新版本  | 
|  EKS Pod 身分識別代理程式  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/hybrid-nodes-add-ons.html)  | 
|  節點監控代理程式  |  v1.2.0-eksbuild.1 及更新版本  | 
|  CSI 快照控制器  |  v8.1.0-eksbuild.1 及更新版本  | 
|   AWS Kubernetes 專用私有 CA 連接器  |  v1.6.0-eksbuild.1 及更新版本  | 
|  Amazon FSx CSI 驅動程式  |  v1.7.0-eksbuild.1 及更高版本  | 
|   AWS Secrets Store CSI 驅動程式提供者  |  v2.1.1-eksbuild.1 及更高版本  | 

下列社群附加元件與 Amazon EKS 混合節點相容。若要進一步了解社群附加元件，請參閱 [社群附加元件](community-addons.md)。


| 社群附加元件 | 相容的附加元件版本 | 
| --- | --- | 
|  Kubernetes 指標伺服器  |  v0.7.2-eksbuild.1 及更新版本  | 
|  cert-manager  |  v1.17.2-eksbuild.1 及更新版本  | 
|  Prometheus Node Exporter  |  v1.9.1-eksbuild.2 及更新版本  | 
|  kube-state-metrics  |  v2.15.0-eksbuild.4 及更新版本  | 
|  外部 DNS  |  v0.19.0-eksbuild.1 及更新版本  | 

除了上表中的 Amazon EKS 附加元件之外，[Amazon Managed Service for Prometheus 收集器](prometheus.md)及適用於[應用程式傳入](alb-ingress.md) (HTTP) 和[負載平衡](network-load-balancing.md) (TCP/UDP) 的 [AWS Load Balancer 控制器](aws-load-balancer-controller.md)可與混合節點相容。

有些 AWS 附加元件和社群附加元件與 Amazon EKS 混合節點不相容。這些附加元件的最新版本對套用至混合節點的預設 `eks.amazonaws.com/compute-type: hybrid` 標籤具有反親和性規則。這可以防止它們在叢集中部署時於混合節點上執行。如果您有在 AWS Cloud 中同時執行混合節點和節點的叢集，您可以將叢集中的這些附加元件部署到在 AWS Cloud 中執行的節點。Amazon VPC CNI 與混合節點不相容，並且支援 Cilium 和 Calico 作為 Amazon EKS 混合節點的容器聯網介面 (CNI)。如需詳細資訊，請參閱[設定混合節點的 CNI](hybrid-nodes-cni.md)。

## AWS 附加元件
<a name="hybrid-nodes-add-ons-aws-add-ons"></a>

以下各節說明在混合節點上執行相容 AWS 附加元件與其他 Amazon EKS 運算類型之間的差異。

## kube-proxy 和 CoreDNS
<a name="hybrid-nodes-add-ons-core"></a>

當您使用 AWS API 和 AWS SDKs 建立 EKS 叢集時，EKS 預設會將 kube-proxy 和 CoreDNS 安裝為自我管理附加元件，包括來自 AWS CLI 的 。建立叢集後，您可以使用 Amazon EKS 附加元件覆寫這些附加元件。如需有關 [在 Amazon EKS 叢集中管理 `kube-proxy`](managing-kube-proxy.md) 和 [在 Amazon EKS 叢集中管理 DNS 的 CoreDNS](managing-coredns.md) 的詳細資訊，請參閱 EKS 文件。如果您執行的混合模式叢集同時具有混合節點和 AWS Cloud 中的節點， AWS 建議在混合節點上至少有一個 CoreDNS 複本，並在 AWS Cloud 中的節點上至少有一個 CoreDNS 複本。如需組態步驟，請參閱 [設定 CoreDNS 複本](hybrid-nodes-webhooks.md#hybrid-nodes-mixed-coredns)。

## CloudWatch 可觀測性代理程式
<a name="hybrid-nodes-add-ons-cw"></a>

CloudWatch 可觀測性代理程式運算子使用 [Webhook](https://kubernetes.io/docs/reference/access-authn-authz/webhook/)。如果您在混合節點上執行運算子，您的內部部署 Pod CIDR 必須在內部部署網路上可路由，而且您必須使用遠端 Pod 網路設定 EKS 叢集。如需詳細資訊，請參閱[設定混合節點的 Webhook](hybrid-nodes-webhooks.md)。

節點層級指標不適用於混合節點，因為 [CloudWatch Container Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContainerInsights.html) 取決於節點層級指標的[執行個體中繼資料服務](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html) (IMDS) 的可用性。叢集、工作負載、Pod 和容器層級指標可供混合節點使用。

遵循[使用 Amazon CloudWatch 可觀測性安裝 CloudWatch 代理程式](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Observability-EKS-addon.html)中所述的步驟安裝附加元件後，必須先更新附加元件資訊清單，然後代理程式才能在混合節點上成功執行。編輯叢集上的 `amazoncloudwatchagents` 資源，以新增 `RUN_WITH_IRSA` 環境變數，如下所示。

```
kubectl edit amazoncloudwatchagents -n amazon-cloudwatch cloudwatch-agent
```

```
apiVersion: v1
items:
- apiVersion: cloudwatch.aws.amazon.com/v1alpha1
  kind: AmazonCloudWatchAgent
  metadata:
    ...
    name: cloudwatch-agent
    namespace: amazon-cloudwatch
    ...
  spec:
    ...
    env:
    - name: RUN_WITH_IRSA # <-- Add this
      value: "True" # <-- Add this
    - name: K8S_NODE_NAME
      valueFrom:
        fieldRef:
          fieldPath: spec.nodeName
          ...
```

## 適用於混合節點的 Amazon Managed Prometheus 受管收集器
<a name="hybrid-nodes-add-ons-amp"></a>

Amazon Managed Service for Prometheus (AMP) 受管收集器包含一個抓取器，並且可從 Amazon EKS 叢集中的資源探索和收集指標。AMP 會為您管理抓取器，而無需自行管理任何執行個體、代理程式或抓取器。

您可以使用 AMP 受管收集器，而無需任何其他專屬於混合節點的組態。不過，混合節點上應用程式的指標端點必須可從 VPC 連線，包括從 VPC 路由到遠端 Pod 網路 CIDR 及內部部署防火牆中開啟的連接埠。此外，您的叢集必須擁有[私有叢集端點存取權](cluster-endpoint.md)。

請遵循《Amazon Managed Service for Prometheus 使用者指南》中的[使用 AWS 受管收集器](https://docs.aws.amazon.com/prometheus/latest/userguide/AMP-collector-how-to.html)中的步驟。

## AWS Distro for OpenTelemetry (ADOT)
<a name="hybrid-nodes-add-ons-adot"></a>

您可以使用 AWS Distro for OpenTelemetry (ADOT) 附加元件，從混合節點上執行的應用程式收集指標、日誌和追蹤資料。ADOT 使用許可 [Webhook](https://kubernetes.io/docs/reference/access-authn-authz/webhook/) 來變更和驗證收集器自訂資源請求。如果您在混合節點上執行 ADOT 運算子，您的內部部署 Pod CIDR 必須在內部部署網路上可路由，而且您必須使用遠端 Pod 網路設定 EKS 叢集。如需詳細資訊，請參閱[設定混合節點的 Webhook](hybrid-nodes-webhooks.md)。

請遵循 [AWS Distro for OpenTelemetry 文件中的使用 EKS 附加元件的 Distro for OpenTelemetry 入門](https://aws-otel.github.io/docs/getting-started/adot-eks-add-on)中的步驟。 * AWS OpenTelemetry* 

## AWS Load Balancer控制器
<a name="hybrid-nodes-add-ons-lbc"></a>

您可以使用[AWS Load Balancer控制器](aws-load-balancer-controller.md)和 Application Load Balancer (ALB) 或 Network Load Balancer (NLB) 搭配混合節點上`ip`工作負載的目標類型。搭配 ALB 或 NLB 使用的 IP 目標必須可路由 AWS。The AWS Load Balancer 控制器也使用 [Webhook](https://kubernetes.io/docs/reference/access-authn-authz/webhook/)。如果您在混合節點上執行 AWS Load Balancer控制器運算子，您的內部部署 Pod CIDR 必須在內部部署網路上可路由，而且您必須使用遠端 Pod 網路設定 EKS 叢集。如需詳細資訊，請參閱[設定混合節點的 Webhook](hybrid-nodes-webhooks.md)。

若要安裝 AWS Load Balancer控制器，請遵循 [AWS Application Load Balancer](hybrid-nodes-ingress.md#hybrid-nodes-ingress-alb)或 中的步驟[AWS Network Load Balancer](hybrid-nodes-load-balancing.md#hybrid-nodes-service-lb-nlb)。

對於使用 ALB 的傳入，您必須指定以下註釋。如需詳細資訊，請參閱[透過 Application Load Balancer 路由應用程式與 HTTP 流量](alb-ingress.md)。

```
alb.ingress.kubernetes.io/target-type: ip
```

對於使用 NLB 的負載平衡，您必須指定以下註釋。如需詳細資訊，請參閱[透過 Network Load Balancer 路由 TCP 與 UDP 流量](network-load-balancing.md)。

```
service.beta.kubernetes.io/aws-load-balancer-type: "external"
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
```

## EKS Pod 身分識別代理程式
<a name="hybrid-nodes-add-ons-pod-id"></a>

**注意**  
若要在執行 Bottlerocket 的混合節點上成功部署 EKS Pod 身分識別代理程式附加元件，請確保您的 Bottlerocket 版本至少為 v1.39.0。在混合節點環境中，較早版本的 Bottlerocket 不支援 Pod 身分識別代理程式。

原始 Amazon EKS Pod Identity Agent DaemonSet 依賴節點上 EC2 IMDS 的可用性來取得所需的 AWS 登入資料。由於 IMDS 不適用於混合節點，因此從版本 1.3.3-eksbuild.1 開始，Pod 身分識別代理程式附加元件可選擇性地部署會掛載所需憑證的 DaemonSet。執行 Bottlerocket 的混合節點需要不同的方法來掛載憑證，並且版本 1.3.7-eksbuild.2 開始，Pod 身分識別代理程式附加元件可選擇性地部署專門以 Bottlerocket 混合節點為目標的 DaemonSet。下列各節說明啟用選用 DaemonSets 的程序。

### Ubuntu/RHEL/AL2023
<a name="_ubunturhelal2023"></a>

1. 若要在 Ubuntu/RHEL/Al2023 混合節點上使用 Pod 身分識別代理程式，請在 `nodeadm` 組態的混合區段中設定 `enableCredentialsFile: true`，如下所示：

   ```
   apiVersion: node.eks.aws/v1alpha1
   kind: NodeConfig
   spec:
       hybrid:
           enableCredentialsFile: true # <-- Add this
   ```

   這將設定 `nodeadm` 以建立憑證檔案，而該檔案可在 `/eks-hybrid/.aws/credentials` 下的節點上進行設定，且，在其將由 `eks-pod-identity-agent` Pod 使用。此登入資料檔案將包含將定期重新整理的臨時 AWS 登入資料。

1. 更新*每個*節點上的 `nodeadm` 組態後，請使用 `nodeConfig.yaml` 執行下列 `nodeadm init` 命令，以將混合節點加入 Amazon EKS 叢集。如果您的節點先前已加入叢集，仍請再次執行 `nodeadm init` 命令。

   ```
   nodeadm init -c file://nodeConfig.yaml
   ```

1. 使用 CLI 或 ，`eks-pod-identity-agent`在啟用混合節點支援的情況下安裝 AWS AWS 管理主控台。

   1.  AWS CLI：從您用來管理叢集的機器中，執行下列命令來安裝 `eks-pod-identity-agent`，並啟用混合節點的支援。使用您叢集的名稱取代 `my-cluster`。

      ```
      aws eks create-addon \
          --cluster-name my-cluster \
          --addon-name eks-pod-identity-agent \
          --configuration-values '{"daemonsets":{"hybrid":{"create": true}}}'
      ```

   1.  AWS 管理主控台：如果您透過 AWS 主控台安裝 Pod Identity Agent 附加元件，請將下列項目新增至選用組態，以部署以混合節點為目標的 DaemonSet。

      ```
      {"daemonsets":{"hybrid":{"create": true}}}
      ```

### Bottlerocket
<a name="_bottlerocket"></a>

1. 若要在 Bottlerocket 混合節點上使用 Pod 身分識別代理程式，請將 `--enable-credentials-file=true` 旗標新增至用於 Bottlerocket 引導容器使用者資料的命令，如 [使用 Bottlerocket 連接混合節點](hybrid-nodes-bottlerocket.md) 中所述。

   1. 如果您使用的是 SSM 憑證提供者，則您的命令應該如下所示：

      ```
      eks-hybrid-ssm-setup --activation-id=<activation-id> --activation-code=<activation-code> --region=<region> --enable-credentials-file=true
      ```

   1. 如果您使用的是 IAM Roles Anywhere 憑證提供者，則您的命令應該如下所示：

      ```
      eks-hybrid-iam-ra-setup --certificate=<certificate> --key=<private-key> --enable-credentials-file=true
      ```

      這將設定引導指令碼，以在 `/var/eks-hybrid/.aws/credentials` 下的節點上建立憑證，且其將由 `eks-pod-identity-agent` Pod 使用。此登入資料檔案將包含將定期重新整理的臨時 AWS 登入資料。

1. 使用 CLI 或 ，`eks-pod-identity-agent`在已啟用 Bottlerocket AWS 混合節點的支援下安裝 AWS 管理主控台。

   1.  AWS CLI：從您用來管理叢集的機器中，執行下列命令來安裝 `eks-pod-identity-agent` ，並啟用 Bottlerocket 混合節點的支援。使用您叢集的名稱取代 `my-cluster`。

      ```
      aws eks create-addon \
          --cluster-name my-cluster \
          --addon-name eks-pod-identity-agent \
          --configuration-values '{"daemonsets":{"hybrid-bottlerocket":{"create": true}}}'
      ```

   1.  AWS 管理主控台：如果您透過 AWS 主控台安裝 Pod Identity Agent 附加元件，請將下列項目新增至選用組態，以部署以 Bottlerocket 混合節點為目標的 DaemonSet。

      ```
      {"daemonsets":{"hybrid-bottlerocket":{"create": true}}}
      ```

## CSI 快照控制器
<a name="hybrid-nodes-add-ons-csi-snapshotter"></a>

從版本 開始`v8.1.0-eksbuild.2`，[CSI 快照控制器附加元件](csi-snapshot-controller.md)會套用混合節點的軟性反親和性規則，偏好控制器在與 Amazon EKS 控制平面相同的 AWS 區域中於 EC2 `deployment`上執行。在`deployment`與 Amazon EKS 控制平面相同的 AWS 區域中聯合放置 可改善延遲。

## 社群附加元件
<a name="hybrid-nodes-add-ons-community"></a>

以下各節說明在混合節點上執行相容的社群附加元件與其他 Amazon EKS 運算類型之間的差異。

## Kubernetes 指標伺服器
<a name="hybrid-nodes-add-ons-metrics-server"></a>

控制平面需要連接指標伺服器的 Pod IP (如果啟用 hostNetwork，則為節點 IP)。因此，除非您在 hostNetwork 模式下執行指標伺服器，否則您必須在建立 Amazon EKS 叢集時設定遠端 Pod 網路，而且必須使 Pod IP 位址可路由。使用 CNI 實作邊界閘道協定 (BGP) 是讓您的 Pod IP 位址可路由的常見方式之一。

## cert-manager
<a name="hybrid-nodes-add-ons-cert-manager"></a>

 `cert-manager` 會使用 [Webhook](https://kubernetes.io/docs/reference/access-authn-authz/webhook/)。如果您在混合節點上執行 `cert-manager`，您的內部部署 Pod CIDR 必須在內部部署網路上可路由，而且您必須使用遠端 Pod 網路設定 EKS 叢集。如需詳細資訊，請參閱[設定混合節點的 Webhook](hybrid-nodes-webhooks.md)。

# 設定混合節點的 Webhook
<a name="hybrid-nodes-webhooks"></a>

此頁面詳細說明使用混合節點執行 Webhook 的考量事項。Webhook 可用於 Kubernetes 應用程式和開放原始碼專案，例如 AWS Load Balancer 控制器和 CloudWatch 可觀測性代理程式，以在執行時期執行變更和驗證功能。

 **可路由的 Pod 網路** 

如果您能夠在內部部署網路上讓內部部署 Pod CIDR 可路由，則可在混合節點上執行 Webhook。您可以使用多種技術，讓您的內部部署 Pod CIDR 在內部部署網路上可路由，包括邊界閘道協定 (BGP)、靜態路由或其他自訂路由解決方案。BGP 是建議的解決方案，因為它比需要自訂或手動路由組態的替代解決方案更具可擴展性且更容易管理。AWS 支援 Cilium 和 Calico 的 BGP 功能，可用於公告 Pod CIDR，如需詳細資訊，請參閱 [設定混合節點的 CNI](hybrid-nodes-cni.md) 和 [可路由的遠端 Pod CIDR](hybrid-nodes-concepts-kubernetes.md#hybrid-nodes-concepts-k8s-pod-cidrs)。

 **不可路由的 Pod 網路** 

如果您*無法*在使內部部署 Pod CIDR 在內部部署網路上可路由並且需要執行 Webhook，則建議您在與混合節點相同的 EKS 叢集中的雲端節點上，執行所有 Webhook。

## 混合模式叢集的考量事項
<a name="hybrid-nodes-considerations-mixed-mode"></a>

 *混合模式叢集*定義為具有混合節點和在 AWS 雲端中執行的節點的 EKS 叢集。執行混合模式叢集時，請考量下列建議：
+ 在 AWS 雲端的節點上執行 VPC CNI，並在混合節點上執行 Cilium 或 Calico。在 AWS 雲端中的節點上執行時，AWS 不支援 Cilium 和 Calico。
+ 設定 Webhook 以在 AWS 雲端中的節點上執行。如需如何為 AWS 和社群附加元件設定 Webhook，請參閱 [為附加元件設定 Webhook](#hybrid-nodes-webhooks-add-ons)。
+ 如果您的應用程式需要在 AWS 雲端中的節點上執行的 Pod 以便直接與在混合節點上執行的 Pod 通訊 (「東西通訊」)，並且您在 AWS 雲端中的節點上使用 VPC CNI，以及在混合節點上使用 Cilium 或 Calico，則您的內部部署 Pod CIDR 必須在內部部署網路上可路由。
+ 在 AWS 雲端中的節點上執行至少一個 CoreDNS 複本，並在混合節點上執行至少一個 CoreDNS 複本。
+ 設定服務流量分佈，以將服務流量保持在其來源區域的本機。如需有關服務流量分佈的詳細資訊，請參閱 [設定服務流量分佈](#hybrid-nodes-mixed-service-traffic-distribution)。
+ 如果您針對混合節點上執行的工作負載流量使用 AWS Application Load Balancers (ALB) 或 Network Load Balancer (NLB)，則搭配 ALB 或 NLB 使用的 IP 目標必須可從 AWS 路由。
+ 指標伺服器附加元件需要從 EKS 控制平面連線至指標伺服器 Pod IP 位址。如果您在混合節點上執行指標伺服器附加元件，則您的內部部署 Pod CIDR 必須在內部部署網路上可路由。
+ 若要使用 Amazon Managed Service for Prometheus (AMP) 受管收集器收集混合節點的指標，您的內部部署 Pod CIDR 必須在內部部署網路上可路由。或者，您可以將 AMP 受管收集器用於在 AWS 雲端中執行的 EKS 控制平面指標和資源，並且使用 AWS Distro for OpenTelemetry (ADOT) 附加元件來收集混合節點的指標。

## 設定混合模式叢集
<a name="hybrid-nodes-mixed-mode"></a>

若要檢視叢集上執行的變更和驗證 Webhook，您可以在叢集的 EKS 主控台的**資源**面板中檢視**延伸模組**模源類型，或者也可以使用下列命令。EKS 還會在叢集可觀測性儀表板中報告 Webhook 指標，如需詳細資訊，請參閱 [使用可觀測性儀表板監控您的叢集](observability-dashboard.md)。

```
kubectl get mutatingwebhookconfigurations
```

```
kubectl get validatingwebhookconfigurations
```

### 設定服務流量分佈
<a name="hybrid-nodes-mixed-service-traffic-distribution"></a>

執行混合模式叢集時，建議您使用[https://kubernetes.io/docs/reference/networking/virtual-ips/#traffic-distribution](https://kubernetes.io/docs/reference/networking/virtual-ips/#traffic-distribution)，以將服務流量保持在其來源區域的本機。服務流量分佈 (適用於 EKS 中的 Kubernetes 版本 1.31 及更新版本) 是[拓撲感知路由](https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/)的建議解決方案，因為其可預測性更高。透過服務流量分佈，區域中運作狀態良好的端點將會接收該區域的所有流量。利用拓撲感知路由，每個服務都必須符合該區域中的數個條件，以套用自訂路由，否則其會將流量平均路由至所有端點。

如果您使用 Cilium 作為 CNI，則必須執行 CNI，並將 `enable-service-topology` 設定為 `true` 以啟用服務流量分佈。您可以使用 Helm 安裝旗標 `--set loadBalancer.serviceTopology=true` 傳遞此組態，或者，您也可以使用 Cilium CLI 命令 `cilium config set enable-service-topology true` 更新現有的安裝。更新現有安裝的組態後，必須重新啟動在每個節點上執行的 Cilium 代理程式。

下節會顯示如何為 CoreDNS 服務設定服務流量分佈的範例，並且建議您為叢集中的所有服務啟用相同的服務流量分佈，以避免意外的跨環境流量。

### 設定 CoreDNS 複本
<a name="hybrid-nodes-mixed-coredns"></a>

如果您執行具有混合節點和 AWS 雲端中的節點的混合模式叢集，則建議您在混合節點上至少有一個 CoreDNS 複本，並在 AWS 雲端中的節點上至少有一個 CoreDNS 複本。為了防止混合模式叢集設定中的延遲和網路問題，您可以將 CoreDNS 服務設定為偏好使用具有[服務流量分佈](https://kubernetes.io/docs/reference/networking/virtual-ips/#traffic-distribution)的最接近的 CoreDNS 複本。

 *服務流量分佈* (適用於 EKS 中的 Kubernetes 版本 1.31 及更新版本) 是[拓撲感知路由](https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/)的建議解決方案，因為其可預測性更高。在服務流量分佈中，區域中運作狀態良好的端點將會接收該區域的所有流量。在拓撲感知路由中，每個服務都必須符合該區域中的數個條件，以套用自訂路由，否則其會將流量平均路由至所有端點。下列步驟可設定服務流量分佈。

如果您使用 Cilium 作為 CNI，則必須執行 CNI，並將 `enable-service-topology` 設定為 `true` 以啟用服務流量分佈。您可以使用 Helm 安裝旗標 `--set loadBalancer.serviceTopology=true` 傳遞此組態，或者，您也可以使用 Cilium CLI 命令 `cilium config set enable-service-topology true` 更新現有的安裝。更新現有安裝的組態後，必須重新啟動在每個節點上執行的 Cilium 代理程式。

1. 為每個混合節點新增一個拓撲區域標籤，例如 `topology.kubernetes.io/zone: onprem`。或者，您可以在 `nodeadm` 組態中指定標籤，進而在 `nodeadm init` 階段設定標籤，請參閱 [用於自訂 kubelet 的節點組態 (選用)](hybrid-nodes-nodeadm.md#hybrid-nodes-nodeadm-kubelet)。請注意，在 AWS 雲端中執行的節點會自動取得套用至它們的拓撲區域標籤，而這些節點可對應至節點的可用區域 (AZ)。

   ```
   kubectl label node hybrid-node-name topology.kubernetes.io/zone=zone
   ```

1. 使用拓撲區域金鑰將 `podAntiAffinity` 新增至 CoreDNS 部署。或者，您可以在安裝過程中使用 EKS 附加元件設定 CoreDNS 部署。

   ```
   kubectl edit deployment coredns -n kube-system
   ```

   ```
   spec:
     template:
       spec:
         affinity:
          ...
           podAntiAffinity:
             preferredDuringSchedulingIgnoredDuringExecution:
             - podAffinityTerm:
                 labelSelector:
                   matchExpressions:
                   - key: k8s-app
                     operator: In
                     values:
                     - kube-dns
                 topologyKey: kubernetes.io/hostname
               weight: 100
             - podAffinityTerm:
                 labelSelector:
                   matchExpressions:
                   - key: k8s-app
                     operator: In
                     values:
                     - kube-dns
                 topologyKey: topology.kubernetes.io/zone
               weight: 50
         ...
   ```

1. 將設定 `trafficDistribution: PreferClose` 新增至 `kube-dns` 服務組態，以啟用服務流量分佈。

   ```
   kubectl patch svc kube-dns -n kube-system --type=merge -p '{
     "spec": {
       "trafficDistribution": "PreferClose"
     }
   }'
   ```

1. 您可以檢視 `kube-dns` 服務的端點配量，進而確認已啟用服務流量分佈。您的端點配量必須顯示拓撲區域標籤的 `hints`，進而確認已啟用服務流量分佈。如果您沒有看到每個端點地址的 `hints`，則不會啟用服務流量分佈。

   ```
   kubectl get endpointslice -A | grep "kube-dns"
   ```

   ```
   kubectl get endpointslice [.replaceable]`kube-dns-<id>`  -n kube-system -o yaml
   ```

   ```
   addressType: IPv4
   apiVersion: discovery.k8s.io/v1
   endpoints:
   - addresses:
     - <your-hybrid-node-pod-ip>
     hints:
       forZones:
       - name: onprem
     nodeName: <your-hybrid-node-name>
     zone: onprem
   - addresses:
     - <your-cloud-node-pod-ip>
     hints:
       forZones:
       - name: us-west-2a
     nodeName: <your-cloud-node-name>
     zone: us-west-2a
   ```

### 為附加元件設定 Webhook
<a name="hybrid-nodes-webhooks-add-ons"></a>

下列附加元件使用 Webhook 並支援與混合節點搭配使用。
+  AWS Load Balancer 控制器
+ CloudWatch 可觀測性代理程式
+  AWS Distro for OpenTelemetry (ADOT)
+  `cert-manager` 

請參閱下列各節，以了解如何設定這些附加元件所使用的 Webhook，以便在 AWS 雲端中的節點上執行。

#### AWS Load Balancer 控制器
<a name="hybrid-nodes-mixed-lbc"></a>

若要在混合模式叢集設定中使用 AWS Load Balancer 控制器，您必須在 AWS 雲端中的節點上執行控制器。為此，請將下列內容新增至 Helm 值組態，或使用 EKS 附加元件組態指定值。

```
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: eks.amazonaws.com/compute-type
          operator: NotIn
          values:
          - hybrid
```

#### CloudWatch 可觀測性代理程式
<a name="hybrid-nodes-mixed-cwagent"></a>

CloudWatch 可觀測性代理程式附加元件具有使用 Webhook 的 Kubernetes Operator。若要在混合模式叢集設定中對 AWS 雲端中的節點執行運算子，請編輯 CloudWatch 可觀測性代理程式運算子組態。您無法在安裝過程中使用 Helm 和 EKS 附加元件設定運算子親和性 (請參閱 [Container-roadmap 問題 \$12431](https://github.com/aws/containers-roadmap/issues/2431))。

```
kubectl edit -n amazon-cloudwatch deployment amazon-cloudwatch-observability-controller-manager
```

```
spec:
  ...
  template:
    ...
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: eks.amazonaws.com/compute-type
                operator: NotIn
                values:
                - hybrid
```

#### AWS Distro for OpenTelemetry (ADOT)
<a name="hybrid-nodes-mixed-adot"></a>

AWS Distro for OpenTelemetry (ADOT) 附加元件具有使用 Webhook 的 Kubernetes Operator。若要在混合模式叢集設定中對 AWS 雲端中的節點執行運算子，請將下列項目新增至 Helm 值組態，或使用 EKS 附加元件組態指定值。

```
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: eks.amazonaws.com/compute-type
          operator: NotIn
          values:
          - hybrid
```

如果您的 Pod CIDR 在內部部署網路上不可路由，則 ADOT 收集器必須在混合節點上執行，以從混合節點和在其上執行的工作負載中抓取指標。為此，請編輯自訂資源定義 (CRD)。

```
kubectl -n opentelemetry-operator-system edit opentelemetrycollectors.opentelemetry.io adot-col-prom-metrics
```

```
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: eks.amazonaws.com/compute-type
            operator: In
            values:
            - hybrid
```

您可以將下列 `relabel_configs` 新增至 ADOT 收集器 CRD 組態中的每個 `scrape_configs`，從而將 ADOT 收集器設定為僅從混合節點和混合節點上執行的資源抓取指標。

```
relabel_configs:
  - action: keep
    regex: hybrid
    source_labels:
    - __meta_kubernetes_node_label_eks_amazonaws_com_compute_type
```

ADOT 附加元件具有一個先決條件要求，即為 ADOT 運算子 Webhook 所使用的 TLS 憑證安裝 `cert-manager`。`cert-manager` 也會執行 Webhook，而且您可以使用下列 Helm 值組態，將其設定為在 AWS 雲端中的節點上執行。

```
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: eks.amazonaws.com/compute-type
          operator: NotIn
          values:
          - hybrid
webhook:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: eks.amazonaws.com/compute-type
            operator: NotIn
            values:
            - hybrid
cainjector:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: eks.amazonaws.com/compute-type
            operator: NotIn
            values:
            - hybrid
startupapicheck:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: eks.amazonaws.com/compute-type
            operator: NotIn
            values:
            - hybrid
```

#### `cert-manager`
<a name="hybrid-nodes-mixed-cert-manager"></a>

`cert-manager` 附加元件會執行 Webhook，並且您可以使用下列 Helm 值組態，將其設定為在 AWS 雲端中的節點上執行。

```
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: eks.amazonaws.com/compute-type
          operator: NotIn
          values:
          - hybrid
webhook:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: eks.amazonaws.com/compute-type
            operator: NotIn
            values:
            - hybrid
cainjector:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: eks.amazonaws.com/compute-type
            operator: NotIn
            values:
            - hybrid
startupapicheck:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: eks.amazonaws.com/compute-type
            operator: NotIn
            values:
            - hybrid
```

# 設定混合節點的代理
<a name="hybrid-nodes-proxy"></a>

如果您在內部部署環境中為離開資料中心或邊緣環境的流量使用代理伺服器，則您需要將節點和叢集分別設定為使用代理伺服器。

叢集  
在叢集上，您需要設定 `kube-proxy`，以使用您的代理伺服器。在建立 Amazon EKS 叢集後，您必須設定 `kube-proxy`。

節點  
在節點上，您必須設定作業系統、`containerd`、`kubelet` 和 Amazon SSM 代理程式，以使用您的代理伺服器。您可以在作業系統映像的建置程序期間或在每個混合節點上執行 `nodeadm init` 之前，進行這些變更。

## 節點層級組態
<a name="_node_level_configuration"></a>

您必須在作業系統映像中或在每個混合節點上執行 `nodeadm init` 之前，套用下列組態。

### `containerd` 代理組態
<a name="_containerd_proxy_configuration"></a>

 `containerd` 是 Kubernetes 的預設容器管理執行時期。如果您使用代理進行網際網路存取，則必須設定 `containerd`，如此才能提取 Kubernetes 和 Amazon EKS 所需的容器映像。

使用下列內容，在 `/etc/systemd/system/containerd.service.d` 目錄中稱為 `http-proxy.conf` 的每個混合節點上，建立檔案。將 `proxy-domain` 和 `port` 取代為您環境的值。

```
[Service]
Environment="HTTP_PROXY=http://proxy-domain:port"
Environment="HTTPS_PROXY=http://proxy-domain:port"
Environment="NO_PROXY=localhost"
```

#### 來自使用者資料的 `containerd` 組態
<a name="_containerd_configuration_from_user_data"></a>

需要為此檔案建立 `containerd.service.d` 目錄。您需要重新載入 systemd，才能在不重新啟動的情況下取得組態檔案。在 AL2023 中，當您的指令碼執行時，服務可能已在執行中，因此您還需要將其重新啟動。

```
mkdir -p /etc/systemd/system/containerd.service.d
echo '[Service]' > /etc/systemd/system/containerd.service.d/http-proxy.conf
echo 'Environment="HTTP_PROXY=http://proxy-domain:port"' >> /etc/systemd/system/containerd.service.d/http-proxy.conf
echo 'Environment="HTTPS_PROXY=http://proxy-domain:port"' >> /etc/systemd/system/containerd.service.d/http-proxy.conf
echo 'Environment="NO_PROXY=localhost"' >> /etc/systemd/system/containerd.service.d/http-proxy.conf
systemctl daemon-reload
systemctl restart containerd
```

### `kubelet` 代理組態
<a name="_kubelet_proxy_configuration"></a>

 `kubelet` 是在每個 Kubernetes 節點上執行的 Kubernetes 節點代理程式，且需負責管理其上執行的節點和 Pod。如果您在內部部署環境中使用代理，則必須設定 `kubelet`，如此才能與您 Amazon EKS 叢集的公有或私有端點通訊。

使用下列內容，在 `/etc/systemd/system/kubelet.service.d/` 目錄中稱為 `http-proxy.conf` 的每個混合節點上，建立檔案。將 `proxy-domain` 和 `port` 取代為您環境的值。

```
[Service]
Environment="HTTP_PROXY=http://proxy-domain:port"
Environment="HTTPS_PROXY=http://proxy-domain:port"
Environment="NO_PROXY=localhost"
```

#### 來自使用者資料的 `kubelet` 組態
<a name="_kubelet_configuration_from_user_data"></a>

必須為此檔案建立 `kubelet.service.d` 目錄。您需要重新載入 systemd，才能在不重新啟動的情況下取得組態檔案。在 AL2023 中，當您的指令碼執行時，服務可能已在執行中，因此您還需要將其重新啟動。

```
mkdir -p /etc/systemd/system/kubelet.service.d
echo '[Service]' > /etc/systemd/system/kubelet.service.d/http-proxy.conf
echo 'Environment="HTTP_PROXY=http://proxy-domain:port"' >> /etc/systemd/system/kubelet.service.d/http-proxy.conf
echo 'Environment="HTTPS_PROXY=http://proxy-domain:port"' >> /etc/systemd/system/kubelet.service.d/http-proxy.conf
echo 'Environment="NO_PROXY=localhost"' >> /etc/systemd/system/kubelet.service.d/http-proxy.conf
systemctl daemon-reload
systemctl restart kubelet
```

### `ssm` 代理組態
<a name="_ssm_proxy_configuration"></a>

 `ssm` 是可用於初始化混合節點的憑證提供者之一。`ssm` 負責使用 AWS 來進行驗證以及產生 `kubelet` 使用的臨時憑證。如果您在內部部署環境中使用代理，並使用 `ssm` 作為節點上的憑證提供者，則必須設定 `ssm`，以便其可以與 Amazon SSM 服務端點通訊。

根據作業系統，在下列路徑中稱為 `http-proxy.conf` 的每個混合節點上，建立檔案
+ Ubuntu - `/etc/systemd/system/snap.amazon-ssm-agent.amazon-ssm-agent.service.d/http-proxy.conf` 
+ Amazon Linux 2023 和 Red Hat Enterprise Linux - `/etc/systemd/system/amazon-ssm-agent.service.d/http-proxy.conf` 

使用下列內容填入檔案。將 `proxy-domain` 和 `port` 取代為您環境的值。

```
[Service]
Environment="HTTP_PROXY=http://proxy-domain:port"
Environment="HTTPS_PROXY=http://proxy-domain:port"
Environment="NO_PROXY=localhost"
```

#### 來自使用者資料的 `ssm` 組態
<a name="_ssm_configuration_from_user_data"></a>

必須為此檔案建立 `ssm` systemd 服務檔案目錄。目錄路徑取決於節點上使用的作業系統。
+ Ubuntu - `/etc/systemd/system/snap.amazon-ssm-agent.amazon-ssm-agent.service.d` 
+ Amazon Linux 2023 和 Red Hat Enterprise Linux - `/etc/systemd/system/amazon-ssm-agent.service.d` 

根據節點上使用的作業系統，取代以下重新啟動命令中的 systemd 服務名稱
+ Ubuntu - `snap.amazon-ssm-agent.amazon-ssm-agent` 
+ Amazon Linux 2023 和 Red Hat Enterprise Linux - `amazon-ssm-agent` 

```
mkdir -p systemd-service-file-directory
echo '[Service]' > [.replaceable]#systemd-service-file-directory/http-proxy.conf
echo 'Environment="HTTP_PROXY=http://[.replaceable]#proxy-domain:port"' >> systemd-service-file-directory/http-proxy.conf
echo 'Environment="HTTPS_PROXY=http://[.replaceable]#proxy-domain:port"' >> [.replaceable]#systemd-service-file-directory/http-proxy.conf
echo 'Environment="NO_PROXY=localhost"' >> [.replaceable]#systemd-service-file-directory/http-proxy.conf
systemctl daemon-reload
systemctl restart [.replaceable]#systemd-service-name
```

### 作業系統代理組態
<a name="_operating_system_proxy_configuration"></a>

如果您使用代理進行網際網路存取，則必須將作業系統設定為能夠從作業系統的套件管理工具提取混合節點相依性。

 **Ubuntu** 

1. 透過以下命令，設定 `snap` 以使用您的代理：

   ```
   sudo snap set system proxy.https=http://proxy-domain:port
   sudo snap set system proxy.http=http://proxy-domain:port
   ```

1. 若要啟用 `apt` 的代理，請在 `/etc/apt/` 目錄中建立稱為 `apt.conf` 的檔案。將代理網域和連接埠取代為您環境的值。

   ```
   Acquire::http::Proxy "http://proxy-domain:port";
   Acquire::https::Proxy "http://proxy-domain:port";
   ```

 **Amazon Linux 2023** 

1. 設定 `dnf` 以使用您的代理。為您的環境建立具有代理網域和連接埠值的檔案 `/etc/dnf/dnf.conf`。

   ```
   proxy=http://proxy-domain:port
   ```

 **Red Hat Enterprise Linux** 

1. 設定 `yum` 以使用您的代理。為您的環境建立具有代理網域和連接埠值的檔案 `/etc/yum.conf`。

   ```
   proxy=http://proxy-domain:port
   ```

### IAM Roles Anywhere 代理組態
<a name="_iam_roles_anywhere_proxy_configuration"></a>

IAM Roles Anywhere 憑證提供者服務負責在搭配 `enableCredentialsFile` 旗標使用 IAM Roles Anywhere 時重新整理憑證 (請參閱 [EKS Pod 身分識別代理程式](hybrid-nodes-add-ons.md#hybrid-nodes-add-ons-pod-id))。如果您在內部部署環境中使用代理，則必須設定服務，以便其可以與 IAM Roles Anywhere 端點通訊。

使用下列內容，在 `/etc/systemd/system/aws_signing_helper_update.service.d/` 目錄中，建立稱為 `http-proxy.conf` 的檔案。將 `proxy-domain` 和 `port` 取代為您環境的值。

```
[Service]
Environment="HTTP_PROXY=http://proxy-domain:port"
Environment="HTTPS_PROXY=http://proxy-domain:port"
Environment="NO_PROXY=localhost"
```

## 整個叢集的組態
<a name="_cluster_wide_configuration"></a>

建立 Amazon EKS 叢集之後以及在每個混合節點上執行 `nodeadm init` 之前，必須套用本節中的組態。

### kube-proxy 代理組態
<a name="_kube_proxy_proxy_configuration"></a>

當您的混合節點加入叢集時，Amazon EKS 會自動在每個混合節點上安裝 `kube-proxy` 作為 DaemonSet。`kube-proxy` 會在由 Amazon EKS 叢集上的 Pod 支援的 服務之間啟用路由。若要設定每個主機，`kube-proxy` 需要對您的 Amazon EKS 叢集端點進行 DNS 解析。

1. 使用下列命令編輯 `kube-proxy` DaemonSet

   ```
   kubectl -n kube-system edit ds kube-proxy
   ```

   這將會在設定的編輯器上開啟 `kube-proxy` DaemonSet 定義。

1. 新增 `HTTP_PROXY` 和 `HTTPS_PROXY` 的環境變數。請注意，`NODE_NAME` 環境變數應該已存在於您的組態中。將 `proxy-domain` 和 `port` 取代為您環境的值。

   ```
   containers:
     - command:
       - kube-proxy
       - --v=2
       - --config=/var/lib/kube-proxy-config/config - --hostname-override=$(NODE_NAME)
       env:
       - name: HTTP_PROXY
         value: http://proxy-domain:port
       - name: HTTPS_PROXY
         value: http://proxy-domain:port
       - name: NODE_NAME
         valueFrom:
           fieldRef:
             apiVersion: v1
             fieldPath: spec.nodeName
   ```

# 設定混合節點的 Cilium BGP
<a name="hybrid-nodes-cilium-bgp"></a>

本主題會說明如何設定 Amazon EKS 混合節點的 Cilium 邊界閘道協定 (BGP)。Cilium 的 BGP 功能稱為 [Cilium BGP 控制平面](https://docs.cilium.io/en/stable/network/bgp-control-plane/bgp-control-plane/)，且可用於向內部部署網路公告 Pod 和服務地址。如需讓 Pod CIDR 在內部部署網路上可路由的替代方法，請參閱 [可路由的遠端 Pod CIDR](hybrid-nodes-concepts-kubernetes.md#hybrid-nodes-concepts-k8s-pod-cidrs)。

## 設定 Cilium BGP
<a name="hybrid-nodes-cilium-bgp-configure"></a>

### 先決條件
<a name="_prerequisites"></a>
+ 遵循 [設定混合節點的 CNI](hybrid-nodes-cni.md) 中的指示安裝 Cilium。

### 程序
<a name="_procedure"></a>

1. 若要搭配 Cilium 使用 BGP 向內部部署網路公告 Pod 或服務地址，Cilium 必須與 `bgpControlPlane.enabled: true` 一起安裝。如果您要為現有的 Cilium 部署啟用 BGP，則必須重新啟動 Cilium 運算子才能套用 BGP 組態 (如果先前尚未啟用 BGP)。您可以在 Helm 值中將 `operator.rollOutPods` 設定為 `true`，以在 Helm 安裝/升級程序中重新啟動 Cilium 運算子。

   ```
   helm upgrade cilium oci://public.ecr.aws/eks/cilium/cilium \
     --namespace kube-system \
     --reuse-values \
     --set operator.rollOutPods=true \
     --set bgpControlPlane.enabled=true
   ```

1. 確認 Cilium 運算子和代理程式已重新啟動並正在執行。

   ```
   kubectl -n kube-system get pods --selector=app.kubernetes.io/part-of=cilium
   ```

   ```
   NAME                               READY   STATUS    RESTARTS   AGE
   cilium-grwlc                       1/1     Running   0          4m12s
   cilium-operator-68f7766967-5nnbl   1/1     Running   0          4m20s
   cilium-operator-68f7766967-7spfz   1/1     Running   0          4m20s
   cilium-pnxcv                       1/1     Running   0          6m29s
   cilium-r7qkj                       1/1     Running   0          4m12s
   cilium-wxhfn                       1/1     Running   0          4m1s
   cilium-z7hlb                       1/1     Running   0          6m30s
   ```

1. 建立稱為 `cilium-bgp-cluster.yaml` 的檔案，其中具有 `CiliumBGPClusterConfig` 定義。您可能需要向您的網路管理員取得下列資訊。
   + 針對執行 Cilium 的節點，使用 ASN 設定 `localASN`。
   + 針對內部部署路由器，使用 ASN 設定 `peerASN`。
   + 使用執行 Cilium 的每個節點將與之對等的內部部署路由器 IP，設定 `peerAddress`。

     ```
     apiVersion: cilium.io/v2alpha1
     kind: CiliumBGPClusterConfig
     metadata:
       name: cilium-bgp
     spec:
       nodeSelector:
         matchExpressions:
         - key: eks.amazonaws.com/compute-type
           operator: In
           values:
           - hybrid
       bgpInstances:
       - name: "rack0"
         localASN: NODES_ASN
         peers:
         - name: "onprem-router"
           peerASN: ONPREM_ROUTER_ASN
           peerAddress: ONPREM_ROUTER_IP
           peerConfigRef:
             name: "cilium-peer"
     ```

1. 將 Cilium BGP 叢集組態套用至您的叢集。

   ```
   kubectl apply -f cilium-bgp-cluster.yaml
   ```

1. 使用定義 BGP 對等組態的 `CiliumBGPPeerConfig` 資源建立名為 `cilium-bgp-peer.yaml` 的檔案。多個對等可以共用相同的組態，並提供常見 `CiliumBGPPeerConfig` 資源的參考。如需組態選項的完整清單，請參閱 Cilium 文件中的 [BGP 對等組態](https://docs.cilium.io/en/latest/network/bgp-control-plane/bgp-control-plane-v2/#bgp-peer-configuration)。

   下列 Cilium 對等設定的值必須符合您要對等互連的內部部署路由器的值。
   + 設定 `holdTimeSeconds`，其可決定在宣告工作階段關閉之前 BGP 對等等待保持連線或更新訊息的時長。預設為 90 秒。
   + 設定 `keepAliveTimeSeconds`，其可決定 BGP 對等是否仍可連線，以及 BGP 工作階段是否在作用中。預設為 30 秒。
   + 設定 `restartTimeSeconds`，其可決定 Cilium 的 BGP 控制平面在重新啟動後預期重新建立 BGP 工作階段的時間。預設值為 120 秒。

     ```
     apiVersion: cilium.io/v2alpha1
     kind: CiliumBGPPeerConfig
     metadata:
       name: cilium-peer
     spec:
       timers:
         holdTimeSeconds: 90
         keepAliveTimeSeconds: 30
       gracefulRestart:
         enabled: true
         restartTimeSeconds: 120
       families:
         - afi: ipv4
           safi: unicast
           advertisements:
             matchLabels:
               advertise: "bgp"
     ```

1. 將 Cilium BGP 對等組態套用至您的叢集。

   ```
   kubectl apply -f cilium-bgp-peer.yaml
   ```

1. 使用 `CiliumBGPAdvertisement` 資源建立名為 `cilium-bgp-advertisement-pods.yaml` 的檔案，以向內部部署網路公告 Pod CIDR。
   + `CiliumBGPAdvertisement` 資源可用於定義與其相關聯的廣告類型和屬性。以下範例會將 Cilium 設定為僅公告 Pod CIDR。如需設定 Cilium 以公告服務地址的詳細資訊，請參閱 [服務類型 LoadBalancer](hybrid-nodes-ingress.md#hybrid-nodes-ingress-cilium-loadbalancer) 和 [Cilium 叢集內負載平衡](hybrid-nodes-load-balancing.md#hybrid-nodes-service-lb-cilium) 中的範例。
   + 執行 Cilium 代理程式的每個混合節點皆與上游已啟用 BGP 的路由器對等。當 Cilium 的 `advertisementType` 設定為 `PodCIDR` (如以下範例所示) 時，每個節點都會公告其擁有的 Pod CIDR 範圍。如需詳細資訊，請參閱 Cilium 文件中的 [BGP 公告組態](https://docs.cilium.io/en/stable/network/bgp-control-plane/bgp-control-plane-v2/#bgp-advertisements)。

     ```
     apiVersion: cilium.io/v2alpha1
     kind: CiliumBGPAdvertisement
     metadata:
       name: bgp-advertisement-pods
       labels:
         advertise: bgp
     spec:
       advertisements:
         - advertisementType: "PodCIDR"
     ```

1. 將 Cilium BGP 公告組態套用至您的叢集。

   ```
   kubectl apply -f cilium-bgp-advertisement-pods.yaml
   ```

1. 您可以使用 `cilium bgp peers` 命令，確認 BGP 對等互連與 [Cilium CLI](https://docs.cilium.io/en/stable/gettingstarted/k8s-install-default/#install-the-cilium-cli) 搭配運作。您應該會在環境的輸出中看到正確的值，且工作階段狀態為 `established`。如需有關故障診斷的詳細資訊，請參閱 Cilium 文件中的[故障診斷和操作指南](https://docs.cilium.io/en/latest/network/bgp-control-plane/bgp-control-plane/#troubleshooting-and-operation-guide)。

   在以下範例中，有五個執行 Cilium 代理程式的混合節點，且每個節點將會公告其擁有的 Pod CIDR 範圍。

   ```
   cilium bgp peers
   ```

   ```
   Node                   Local AS    Peer AS               Peer Address        Session State   Uptime     Family         Received   Advertised
   mi-026d6a261e355fba7   NODES_ASN
                     ONPREM_ROUTER_ASN
                     ONPREM_ROUTER_IP    established     1h18m58s   ipv4/unicast   1          2
   mi-082f73826a163626e   NODES_ASN
                     ONPREM_ROUTER_ASN
                     ONPREM_ROUTER_IP    established     1h19m12s   ipv4/unicast   1          2
   mi-09183e8a3d755abf6   NODES_ASN
                     ONPREM_ROUTER_ASN
                     ONPREM_ROUTER_IP    established     1h18m47s   ipv4/unicast   1          2
   mi-0d78d815980ed202d   NODES_ASN
                     ONPREM_ROUTER_ASN
                     ONPREM_ROUTER_IP    established     1h19m12s   ipv4/unicast   1          2
   mi-0daa253999fe92daa   NODES_ASN
                     ONPREM_ROUTER_ASN
                     ONPREM_ROUTER_IP    established     1h18m58s   ipv4/unicast   1          2
   ```

   ```
   cilium bgp routes
   ```

   ```
   Node                   VRouter       Prefix           NextHop   Age         Attrs
   mi-026d6a261e355fba7   NODES_ASN     10.86.2.0/26     0.0.0.0   1h16m46s   [{Origin: i} {Nexthop: 0.0.0.0}]
   mi-082f73826a163626e   NODES_ASN     10.86.2.192/26   0.0.0.0   1h16m46s   [{Origin: i} {Nexthop: 0.0.0.0}]
   mi-09183e8a3d755abf6   NODES_ASN     10.86.2.64/26    0.0.0.0   1h16m46s   [{Origin: i} {Nexthop: 0.0.0.0}]
   mi-0d78d815980ed202d   NODES_ASN     10.86.2.128/26   0.0.0.0   1h16m46s   [{Origin: i} {Nexthop: 0.0.0.0}]
   mi-0daa253999fe92daa   NODES_ASN     10.86.3.0/26     0.0.0.0   1h16m46s   [{Origin: i} {Nexthop: 0.0.0.0}]
   ```

# 設定混合節點的 Kubernetes Ingress
<a name="hybrid-nodes-ingress"></a>

本主題會說明如何為在 Amazon EKS 混合節點上執行的工作負載設定 Kubernetes Ingress。[Kubernetes Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) 會將叢集外部的 HTTP 和 HTTPS 路由公開至叢集內的服務。若要利用傳入資源，需要 Kubernetes Ingress 控制器來設定可提供網路流量的聯網基礎結構和元件。

 針對 EKS 混合節點上執行的工作負載，AWS 支援 AWS Application Load Balancer (ALB) 和適用於 Kubernetes Ingress 的 Cilium。使用 ALB 還是 Cilium for Ingress 的決定取決於應用程式流量的來源。如果應用程式流量來自 AWS 區域，則 AWS 會建議使用 AWS ALB 和 AWS Load Balancer 控制器。如果應用程式流量來自本機內部部署或邊緣環境，則 AWS 會建議使用 Cilium 的內建傳入功能，而該功能可在您的環境中搭配或不搭配負載平衡器基礎結構使用。

![\[EKS 混合節點傳入\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-ingress.png)


## AWS Application Load Balancer
<a name="hybrid-nodes-ingress-alb"></a>

對於在混合節點上執行的工作負載，您可以搭配目標類型 `ip` 使用 [AWS Load Balancer 控制器](aws-load-balancer-controller.md)和 Application Load Balancer (ALB)。使用目標類型 `ip` 時，ALB 可繞過服務層網路路徑，將流量直接轉送至 Pod。若要讓 ALB 達到混合節點上的 Pod IP 目標，您的內部部署 Pod CIDR 必須在內部部署網路上可路由。此外，AWS Load Balancer 控制器使用 Webhook 並且需要從 EKS 控制平面直接通訊。如需詳細資訊，請參閱 [設定混合節點的 Webhook](hybrid-nodes-webhooks.md)。

### 考量事項
<a name="_considerations"></a>
+ 如需有關 AWS Application Load Balancer 和 AWS Load Balancer 控制器的詳細資訊，請參閱 [透過 Application Load Balancer 路由應用程式與 HTTP 流量](alb-ingress.md) 和 [搭配 Helm 的 Install AWS Load Balancer 控制器](lbc-helm.md)。
+ 如需如何在 AWS Application Load Balancer 和 AWS Network Load Balancer 之間選擇的資訊，請參閱[負載平衡的最佳實務](https://docs.aws.amazon.com/eks/latest/best-practices/load-balacing.html)。
+ 如需可以使用 AWS Application [AWS Load Balancer 為傳入資源設定的註釋清單，請參閱 Load Balancer 控制器傳入注釋](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/ingress/annotations/)。

### 先決條件
<a name="_prerequisites"></a>
+ 遵循 [設定混合節點的 CNI](hybrid-nodes-cni.md) 中的指示安裝 Cilium。
+ 遵循 [設定混合節點的 Cilium BGP](hybrid-nodes-cilium-bgp.md) 中的指示啟用 Cilium BGP 控制平面。如果您不想使用 BGP，則必須使用替代方法，以讓內部部署 Pod CIDR 在內部部署網路上可路由。如果您未讓內部部署 Pod CIDR 可路由，則 ALB 將無法註冊或聯絡您的 Pod IP 目標。
+ 已在命令列環境中安裝 Helm，如需詳細資訊，請參閱[安裝 Helm 說明](helm.md)。
+ 已在命令列環境中安裝 eksctl，如需詳細資訊，請參閱[安裝 eksctl 說明](install-kubectl.md#eksctl-install-update)。

### 程序
<a name="_procedure"></a>

1. 下載適用於 AWS Load Balancer 控制器的 IAM 政策，允許它代表您呼叫 AWS API。

   ```
   curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/refs/heads/main/docs/install/iam_policy.json
   ```

1. 使用上一個步驟中下載的政策，建立 IAM 政策。

   ```
   aws iam create-policy \
       --policy-name AWSLoadBalancerControllerIAMPolicy \
       --policy-document file://iam_policy.json
   ```

1. 使用您的設定取代下列值：叢集名稱 (`CLUSTER_NAME`)、AWS 區域 (`AWS_REGION`) 和 AWS 帳戶 ID (`AWS_ACCOUNT_ID`)，然後執行下列命令。

   ```
   eksctl create iamserviceaccount \
       --cluster=CLUSTER_NAME \
       --namespace=kube-system \
       --name=aws-load-balancer-controller \
       --attach-policy-arn=arn:aws:iam::AWS_ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy \
       --override-existing-serviceaccounts \
       --region AWS_REGION \
       --approve
   ```

1. 新增 eks-charts Helm Chart 儲存庫並更新您的本機 Helm 儲存庫，以確保您擁有最近的圖表。

   ```
   helm repo add eks https://aws.github.io/eks-charts
   ```

   ```
   helm repo update eks
   ```

1. 安裝 AWS Load Balancer 控制器。使用您的設定取代下列值：叢集名稱 (`CLUSTER_NAME`)、AWS 區域 (`AWS_REGION`)、VPC ID (`VPC_ID`) 和 AWS Load Balancer 控制器 Helm Chart 版本 (`AWS_LBC_HELM_VERSION`)，然後執行下列命令。如果您執行具有混合節點和 AWS 雲端中的節點的混合模式叢集，則您可以遵循 [AWS Load Balancer 控制器](hybrid-nodes-webhooks.md#hybrid-nodes-mixed-lbc) 中的指示，在雲端節點上執行 AWS Load Balancer 控制器。
   + 您可以透過執行 `helm search repo eks/aws-load-balancer-controller --versions` 來尋找最新版本的 Helm Chart。

     ```
     helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
       -n kube-system \
       --version AWS_LBC_HELM_VERSION \
       --set clusterName=CLUSTER_NAME \
       --set region=AWS_REGION \
       --set vpcId=VPC_ID \
       --set serviceAccount.create=false \
       --set serviceAccount.name=aws-load-balancer-controller
     ```

1. 驗證 AWS Load Balancer 控制器是否已成功安裝。

   ```
   kubectl get -n kube-system deployment aws-load-balancer-controller
   ```

   ```
   NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
   aws-load-balancer-controller   2/2     2            2           84s
   ```

1. 建立範例應用程式。以下範例會使用 [Istio Bookinfo](https://istio.io/latest/docs/examples/bookinfo/) 範例微服務應用程式。

   ```
   kubectl apply -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/bookinfo/platform/kube/bookinfo.yaml
   ```

1. 使用下列內容建立名為 `my-ingress-alb.yaml` 的檔案。

   ```
   apiVersion: networking.k8s.io/v1
   kind: Ingress
   metadata:
     name: my-ingress
     namespace: default
     annotations:
       alb.ingress.kubernetes.io/load-balancer-name: "my-ingress-alb"
       alb.ingress.kubernetes.io/target-type: "ip"
       alb.ingress.kubernetes.io/scheme: "internet-facing"
       alb.ingress.kubernetes.io/healthcheck-path: "/details/1"
   spec:
     ingressClassName: alb
     rules:
     - http:
         paths:
         - backend:
             service:
               name: details
               port:
                 number: 9080
           path: /details
           pathType: Prefix
   ```

1. 將傳入組態套用至叢集。

   ```
   kubectl apply -f my-ingress-alb.yaml
   ```

1. 為您的傳入資源佈建 ALB 可能需要幾分鐘的時間。佈建 ALB 後，您的傳入資源將會為其指派一個與 ALB 部署的 DNS 名稱對應的地址。地址的格式為 `<alb-name>-<random-string>.<region>.elb.amazonaws.com`。

   ```
   kubectl get ingress my-ingress
   ```

   ```
   NAME         CLASS   HOSTS   ADDRESS                                                     PORTS   AGE
   my-ingress   alb     *       my-ingress-alb-<random-string>.<region>.elb.amazonaws.com   80      23m
   ```

1. 使用 ALB 的地址存取服務。

   ```
   curl -s http//my-ingress-alb-<random-string>.<region>.elb.amazonaws.com:80/details/1 | jq
   ```

   ```
   {
     "id": 1,
     "author": "William Shakespeare",
     "year": 1595,
     "type": "paperback",
     "pages": 200,
     "publisher": "PublisherA",
     "language": "English",
     "ISBN-10": "1234567890",
     "ISBN-13": "123-1234567890"
     "details": "This is the details page"
   }
   ```

## Cilium Ingress 和 Cilium Gateway 概觀
<a name="hybrid-nodes-ingress-cilium"></a>

Cilium 的傳入功能內建於 Cilium 的架構中，並且可以使用 Kubernetes 傳入 API 或閘道 API 進行管理。如果您沒有現有的傳入資源，AWS 會建議您從閘道 API 開始，因為這種方法更豐富生動，可更靈活地是定義和管理 Kubernetes 聯網資源。[Kubernetes 閘道 API](https://gateway-api.sigs.k8s.io/) 旨在標準化 Kubernetes 叢集中傳入、負載平衡和服務網格的網路資源的定義和管理方式。

當您啟用 Cilium 的傳入或閘道功能時，Cilium 運算子會協調叢集中的傳入/閘道物件，而每個節點上的 Envoy 代理會處理第 7 層 (L7) 網路流量。Cilium 不會直接佈建傳入/閘道基礎結構，例如負載平衡器。如果您計劃搭配負載平衡器使用 Cilium Ingress/Gateway，則必須使用負載平衡器的工具，通常是傳入或閘道控制器，來部署和管理負載平衡器的基礎結構。

對於傳入/閘道流量，Cilium 會處理核心網路流量和 L3/L4 政策強制執行，而整合式 Envoy 代理則負責處理 L7 網路流量。藉助 Cilium Ingress/Gateway，Envoy 負責套用 L7 路由規則、政策和請求操作、進階流量管理 (例如流量分割和鏡像) 以及 TLS 終止和起始。根據預設，Cilium 的 Envoy 代理會部署為單獨的 DaemonSet (`cilium-envoy`)，這樣一來，Envoy 和 Cilium 代理程式可分別進行更新、擴展和管理。

如需 Cilium Ingress 和 Cilium Gateway 運作方式的詳細資訊，請參閱 Cilium 文件中的 [Cilium Ingress](https://docs.cilium.io/en/stable/network/servicemesh/ingress/) 和 [Cilium Gateway](https://docs.cilium.io/en/stable/network/servicemesh/gateway-api/gateway-api/) 頁面。

## Cilium Ingress 和 Gateway 比較
<a name="hybrid-nodes-ingress-cilium-comparison"></a>

下表總結了截至 **Cilium 版本 1.17.x** 的 Cilium Ingress 和 Cilium Gateway 功能。


| 功能 | Ingress | 閘道 | 
| --- | --- | --- | 
|  服務類型 LoadBalancer  |  是  |  是  | 
|  服務類型 NodePort  |  是  |  否1   | 
|  主機網路  |  是  |  是  | 
|  共用的負載平衡器  |  是  |  是  | 
|  專用負載平衡器  |  是  |  否2   | 
|  網路政策  |  是  |  是  | 
|  通訊協定  |  第 7 層 (HTTP(S)、gRPC)  |  第 7 層 (HTTP(S)、gRPC)3   | 
|  TLS 傳遞  |  是  |  是  | 
|  流量管理  |  路徑和主機路由  |  路徑和主機路由、URL 重新導向和重寫、流量分割、標頭修改  | 

 1 Cilium Gateway 計劃在 Cilium 版本 1.18.x 中對 NodePort 服務提供支援 ([\$127273](https://github.com/cilium/cilium/pull/27273))

 2 Cilium Gateway 支援專用負載平衡器 ([\$125567](https://github.com/cilium/cilium/issues/25567))

 3 Cilium Gateway 支援 TCP/UDP ([\$121929](https://github.com/cilium/cilium/issues/21929))

## 安裝 Cilium Gateway
<a name="hybrid-nodes-ingress-cilium-gateway-install"></a>

### 考量事項
<a name="_considerations_2"></a>
+ 必須設定 Cilium，即將 `nodePort.enabled` 設定為 `true`，如以下範例所示。如果您使用的是 Cilium 的 kube-proxy 取代功能，則不需要將 `nodePort.enabled` 設定為 `true`。
+ 必須設定 Cilium，即將 `envoy.enabled` 設定為 `true`，如以下範例所示。
+ Cilium Gateway 可以部署在負載平衡器 (預設) 或主機網路模式中。
+ 以負載平衡器模式使用 Cilium Gateway 時，必須在閘道資源上設定 `service.beta.kubernetes.io/aws-load-balancer-type: "external"` 註釋，以防止舊版 AWS 雲端提供者為 LoadBalancer 類型的服務建立 Classic Load Balancer，而該服務是 Cilium 為閘道資源所建立的。
+ 在主機網路模式中使用 Cilium Gateway 時，即會停用 LoadBalancer 類型的服務模式。對於沒有負載平衡器基礎結構的環境，主機網路模式非常有用，如需詳細資訊，請參閱 [主機網路](#hybrid-nodes-ingress-cilium-host-network)。

### 先決條件
<a name="_prerequisites_2"></a>

1. 已在命令列環境中安裝 Helm，請參閱[安裝 Helm 說明](helm.md)。

1. 遵循 [設定混合節點的 CNI](hybrid-nodes-cni.md) 中的指示安裝 Cilium。

### 程序
<a name="_procedure_2"></a>

1. 安裝 Kubernetes 閘道 API 自訂資源定義 (CRD)。

   ```
   kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.2.1/config/crd/standard/gateway.networking.k8s.io_gatewayclasses.yaml
   kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.2.1/config/crd/standard/gateway.networking.k8s.io_gateways.yaml
   kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.2.1/config/crd/standard/gateway.networking.k8s.io_httproutes.yaml
   kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.2.1/config/crd/standard/gateway.networking.k8s.io_referencegrants.yaml
   kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.2.1/config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml
   ```

1. 建立稱為 `cilium-gateway-values.yaml` 的檔案，其中具有以下內容。以下範例會將 Cilium Gateway 設定為使用預設負載平衡器模式，以及為僅在混合節點上執行的 Envoy 代理使用單獨 `cilium-envoy` DaemonSet。

   ```
   gatewayAPI:
     enabled: true
     # uncomment to use host network mode
     # hostNetwork:
     #   enabled: true
   nodePort:
     enabled: true
   envoy:
     enabled: true
     affinity:
       nodeAffinity:
         requiredDuringSchedulingIgnoredDuringExecution:
           nodeSelectorTerms:
           - matchExpressions:
             - key: eks.amazonaws.com/compute-type
               operator: In
               values:
               - hybrid
   ```

1. 將 Helm 值套用至叢集。

   ```
   helm upgrade cilium oci://public.ecr.aws/eks/cilium/cilium \
     --namespace kube-system \
     --reuse-values \
     --set operator.rollOutPods=true \
     --values cilium-gateway-values.yaml
   ```

1. 確認 Cilium 運算子、代理程式和 Envoy Pod 正在執行。

   ```
   kubectl -n kube-system get pods --selector=app.kubernetes.io/part-of=cilium
   ```

   ```
   NAME                               READY   STATUS    RESTARTS   AGE
   cilium-envoy-5pgnd                 1/1     Running   0          6m31s
   cilium-envoy-6fhg4                 1/1     Running   0          6m30s
   cilium-envoy-jskrk                 1/1     Running   0          6m30s
   cilium-envoy-k2xtb                 1/1     Running   0          6m31s
   cilium-envoy-w5s9j                 1/1     Running   0          6m31s
   cilium-grwlc                       1/1     Running   0          4m12s
   cilium-operator-68f7766967-5nnbl   1/1     Running   0          4m20s
   cilium-operator-68f7766967-7spfz   1/1     Running   0          4m20s
   cilium-pnxcv                       1/1     Running   0          6m29s
   cilium-r7qkj                       1/1     Running   0          4m12s
   cilium-wxhfn                       1/1     Running   0          4m1s
   cilium-z7hlb                       1/1     Running   0          6m30s
   ```

## 設定 Cilium Gateway
<a name="hybrid-nodes-ingress-cilium-gateway-configure"></a>

將 `gatewayClassName` 設定為 `cilium`，即可在閘道物件上啟用 Cilium Ingress。Cilium 為閘道資源建立的服務可以使用閘道物件上的欄位進行設定。閘道控制器用來設定負載平衡器基礎結構的常見註釋可以透過閘道物件的 `infrastructure` 欄位進行設定。使用 Cilium 的 LoadBalancer IPAM 時 (請參閱 [服務類型 LoadBalancer](#hybrid-nodes-ingress-cilium-loadbalancer) 中的範例)，可在閘道物件的 `addresses` 欄位中設定用於 LoadBalancer 類型的服務的 IP 位址。如需閘道組態的詳細資訊，請參閱 [Kubernetes 閘道 API 規格](https://gateway-api.sigs.k8s.io/reference/spec/#gateway)。

```
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: my-gateway
spec:
  gatewayClassName: cilium
  infrastructure:
    annotations:
      service.beta.kubernetes.io/...
      service.kuberentes.io/...
  addresses:
  - type: IPAddress
    value: <LoadBalancer IP address>
  listeners:
  ...
```

Cilium 和 Kubernetes Gateway 規格支援 GatewayClass、閘道、HTTPRoute、GRPCRoute 和 ReferenceGrant 資源。
+ 如需可用欄位的清單，請參閱 [HTTPRoute](https://gateway-api.sigs.k8s.io/api-types/httproute/HTTPRoute) 和 [GRPCRoute](https://gateway-api.sigs.k8s.io/api-types/grpcroute/GRPCRoute) 規格。
+ 請參閱以下 [部署 Cilium Gateway](#hybrid-nodes-ingress-cilium-gateway-deploy) 章節中的範例及 [Cilium 文件](https://docs.cilium.io/en/stable/network/servicemesh/gateway-api/gateway-api/#examples)中的範例，以了解如何使用和設定這些資源。

## 部署 Cilium Gateway
<a name="hybrid-nodes-ingress-cilium-gateway-deploy"></a>

1. 建立範例應用程式。以下範例會使用 [Istio Bookinfo](https://istio.io/latest/docs/examples/bookinfo/) 範例微服務應用程式。

   ```
   kubectl apply -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/bookinfo/platform/kube/bookinfo.yaml
   ```

1. 確認應用程式已成功執行。

   ```
   kubectl get pods
   ```

   ```
   NAME                              READY   STATUS    RESTARTS   AGE
   details-v1-766844796b-9965p       1/1     Running   0          81s
   productpage-v1-54bb874995-jmc8j   1/1     Running   0          80s
   ratings-v1-5dc79b6bcd-smzxz       1/1     Running   0          80s
   reviews-v1-598b896c9d-vj7gb       1/1     Running   0          80s
   reviews-v2-556d6457d-xbt8v        1/1     Running   0          80s
   reviews-v3-564544b4d6-cpmvq       1/1     Running   0          80s
   ```

1. 使用下列內容建立名為 `my-gateway.yaml` 的檔案。以下範例使用 `service.beta.kubernetes.io/aws-load-balancer-type: "external"` 註釋，以防止舊版 AWS 雲端提供者為 LoadBalancer 類型的服務建立 Classic Load Balancer，而該服務是 Cilium 為閘道資源所建立的。

   ```
   ---
   apiVersion: gateway.networking.k8s.io/v1
   kind: Gateway
   metadata:
     name: my-gateway
   spec:
     gatewayClassName: cilium
     infrastructure:
       annotations:
         service.beta.kubernetes.io/aws-load-balancer-type: "external"
     listeners:
     - protocol: HTTP
       port: 80
       name: web-gw
       allowedRoutes:
         namespaces:
           from: Same
   ---
   apiVersion: gateway.networking.k8s.io/v1
   kind: HTTPRoute
   metadata:
     name: http-app-1
   spec:
     parentRefs:
     - name: my-gateway
       namespace: default
     rules:
     - matches:
       - path:
           type: PathPrefix
           value: /details
       backendRefs:
       - name: details
         port: 9080
   ```

1. 將閘道資源套用至您的叢集。

   ```
   kubectl apply -f my-gateway.yaml
   ```

1. 確認閘道資源和對應的服務已建立。在此階段，閘道資源的 `ADDRESS` 欄位預期不會填入 IP 位址或主機名稱，而且閘道資源的 LoadBalancer 類型的服務同樣不會指派 IP 位址或主機名稱。

   ```
   kubectl get gateway my-gateway
   ```

   ```
   NAME         CLASS    ADDRESS   PROGRAMMED   AGE
   my-gateway   cilium             True         10s
   ```

   ```
   kubectl get svc cilium-gateway-my-gateway
   ```

   ```
   NAME                        TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
   cilium-gateway-my-gateway   LoadBalancer   172.16.227.247   <pending>     80:30912/TCP   24s
   ```

1. 繼續 [服務類型 LoadBalancer](#hybrid-nodes-ingress-cilium-loadbalancer) 以設定閘道資源，進而使用 Cilium Load Balancer IPAM 配置的 IP 位址；以及使用 [服務類型 NodePort](#hybrid-nodes-ingress-cilium-nodeport) 或 [主機網路](#hybrid-nodes-ingress-cilium-host-network) 以設定閘道資源，進而使用 NodePort 或主機網路位址。

## 安裝 Cilium Ingress
<a name="hybrid-nodes-ingress-cilium-ingress-install"></a>

### 考量事項
<a name="_considerations_3"></a>
+ 必須設定 Cilium，即將 `nodePort.enabled` 設定為 `true`，如以下範例所示。如果您使用的是 Cilium 的 kube-proxy 取代功能，則不需要將 `nodePort.enabled` 設定為 `true`。
+ 必須設定 Cilium，即將 `envoy.enabled` 設定為 `true`，如以下範例所示。
+ 將 `ingressController.loadbalancerMode` 設定為 `dedicated` 時，Cilium 會為每個傳入資源建立專用服務。將 `ingressController.loadbalancerMode` 設定為 `shared` 時，Cilium 會為叢集中的所有傳入資源建立 LoadBalancer 類型的共用服務。使用 `shared` 負載平衡器模式時，共用服務的設定 (例如 `labels`、`annotations`、`type` 和 `loadBalancerIP`) 可在 Helm 值的 `ingressController.service` 區段中進行設定。如需詳細資訊，請參閱 [Cilium Helm 值參考](https://github.com/cilium/cilium/blob/v1.17.6/install/kubernetes/cilium/values.yaml#L887)。
+ 將 `ingressController.default` 設定 `true` 時，Cilium 會設定為叢集的預設傳入控制器，即使未在傳入資源上指定 `ingressClassName`，也會建立傳入項目。
+ Cilium Ingress 可以部署在負載平衡器 (預設)、節點連接埠或主機網路模式中。在主機網路模式下安裝 Cilium 時，會停用 LoadBalancer 類型的服務和 NodePort 類型的服務模式。如需詳細資訊，請參閱「[主機網路](#hybrid-nodes-ingress-cilium-host-network)」。
+ 一律將 Helm 值中的 `ingressController.service.annotations` 設定為 `service.beta.kubernetes.io/aws-load-balancer-type: "external"`，以防止舊版 AWS 雲端提供者為預設的 `cilium-ingress` 服務建立 Classic Load Balancer，而該服務是由 [Cilium Helm chart](https://github.com/cilium/cilium/blob/main/install/kubernetes/cilium/templates/cilium-ingress-service.yaml) 所建立的。

### 先決條件
<a name="_prerequisites_3"></a>

1. 已在命令列環境中安裝 Helm，請參閱[安裝 Helm 說明](helm.md)。

1. 遵循 [設定混合節點的 CNI](hybrid-nodes-cni.md) 中的指示安裝 Cilium。

### 程序
<a name="_procedure_3"></a>

1. 建立稱為 `cilium-ingress-values.yaml` 的檔案，其中具有以下內容。以下範例會將 Cilium Ingress 設定為使用預設負載平衡器 `dedicated` 模式，以及為僅在混合節點上執行的 Envoy 代理使用單獨 `cilium-envoy` DaemonSet。

   ```
   ingressController:
     enabled: true
     loadbalancerMode: dedicated
     service:
       annotations:
         service.beta.kubernetes.io/aws-load-balancer-type: "external"
   nodePort:
     enabled: true
   envoy:
     enabled: true
     affinity:
       nodeAffinity:
         requiredDuringSchedulingIgnoredDuringExecution:
           nodeSelectorTerms:
           - matchExpressions:
             - key: eks.amazonaws.com/compute-type
               operator: In
               values:
               - hybrid
   ```

1. 將 Helm 值套用至叢集。

   ```
   helm upgrade cilium oci://public.ecr.aws/eks/cilium/cilium \
     --namespace kube-system \
     --reuse-values \
     --set operator.rollOutPods=true \
     --values cilium-ingress-values.yaml
   ```

1. 確認 Cilium 運算子、代理程式和 Envoy Pod 正在執行。

   ```
   kubectl -n kube-system get pods --selector=app.kubernetes.io/part-of=cilium
   ```

   ```
   NAME                               READY   STATUS    RESTARTS   AGE
   cilium-envoy-5pgnd                 1/1     Running   0          6m31s
   cilium-envoy-6fhg4                 1/1     Running   0          6m30s
   cilium-envoy-jskrk                 1/1     Running   0          6m30s
   cilium-envoy-k2xtb                 1/1     Running   0          6m31s
   cilium-envoy-w5s9j                 1/1     Running   0          6m31s
   cilium-grwlc                       1/1     Running   0          4m12s
   cilium-operator-68f7766967-5nnbl   1/1     Running   0          4m20s
   cilium-operator-68f7766967-7spfz   1/1     Running   0          4m20s
   cilium-pnxcv                       1/1     Running   0          6m29s
   cilium-r7qkj                       1/1     Running   0          4m12s
   cilium-wxhfn                       1/1     Running   0          4m1s
   cilium-z7hlb                       1/1     Running   0          6m30s
   ```

## 設定 Cilium Ingress
<a name="hybrid-nodes-ingress-cilium-ingress-configure"></a>

將 `ingressClassName` 設定為 `cilium`，即可在 Ingress 物件上啟用 Cilium Ingress。當使用 `dedicated` 負載平衡器模式時，Cilium 為傳入資源建立的服務可藉助傳入物件上的注釋進行設定，而當使用 `shared` 負載平衡器模式時，則可在 Cilium/Helm 組態中進行設定。傳入控制器通常會使用這些註釋來設定負載平衡器基礎結構或服務的其他屬性，例如服務類型、負載平衡器模式、連接埠和 TLS 傳遞。重要註釋如下所述。如需支援的註釋的完整清單，請參閱 Cilium 文件中的 [Cilium Ingress 註釋](https://docs.cilium.io/en/stable/network/servicemesh/ingress/#supported-ingress-annotations)。


| 註釋 | 描述 | 
| --- | --- | 
|   `ingress.cilium.io/loadbalancer-mode`   |   `dedicated`：每個傳入資源的 LoadBalancer 類型的專用服務 (預設)。  `shared`：所有傳入資源的 LoadBalancer 類型的單一服務。  | 
|   `ingress.cilium.io/service-type`   |   `LoadBalancer`：服務屬於 LoadBalancer 類型 (預設)  `NodePort`：服務屬於 NodePort。  | 
|   `service.beta.kubernetes.io/aws-load-balancer-type`   |   `"external"`：防止舊版 AWS 雲端提供者為 LoadBalancer 類型的服務佈建 Classic Load Balancer。  | 
|   `lbipam.cilium.io/ips`   |  要從 Cilium LoadBalancer IPAM 配置的 IP 位址的清單  | 

Cilium 和 Kubernetes Ingress 規格可支援傳入路徑的精確、字首和實作特定相符規則。Cilium 支援 regex 作為其實作專屬相符規則。如需詳細資訊，請參閱 Cilium 文件中的[傳入路徑類型和優先順序](https://docs.cilium.io/en/stable/network/servicemesh/ingress/#ingress-path-types-and-precedence)和[路徑類型範例](https://docs.cilium.io/en/stable/network/servicemesh/path-types/)，以及此頁面 [部署 Cilium Ingress](#hybrid-nodes-ingress-cilium-ingress-deploy) 不分中的範例。

範例 Cilium Ingress 物件如下所示。

```
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    service.beta.kuberentes.io/...
    service.kuberentes.io/...
spec:
  ingressClassName: cilium
  rules:
  ...
```

## 部署 Cilium Ingress
<a name="hybrid-nodes-ingress-cilium-ingress-deploy"></a>

1. 建立範例應用程式。以下範例會使用 [Istio Bookinfo](https://istio.io/latest/docs/examples/bookinfo/) 範例微服務應用程式。

   ```
   kubectl apply -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/bookinfo/platform/kube/bookinfo.yaml
   ```

1. 確認應用程式已成功執行。

   ```
   kubectl get pods
   ```

   ```
   NAME                              READY   STATUS    RESTARTS   AGE
   details-v1-766844796b-9965p       1/1     Running   0          81s
   productpage-v1-54bb874995-jmc8j   1/1     Running   0          80s
   ratings-v1-5dc79b6bcd-smzxz       1/1     Running   0          80s
   reviews-v1-598b896c9d-vj7gb       1/1     Running   0          80s
   reviews-v2-556d6457d-xbt8v        1/1     Running   0          80s
   reviews-v3-564544b4d6-cpmvq       1/1     Running   0          80s
   ```

1. 使用下列內容建立名為 `my-ingress.yaml` 的檔案。以下範例使用 `service.beta.kubernetes.io/aws-load-balancer-type: "external"` 註釋，以防止舊版 AWS 雲端提供者為 LoadBalancer 類型的服務建立 Classic Load Balancer，而該服務是 Cilium 為傳入資源所建立的。

   ```
   apiVersion: networking.k8s.io/v1
   kind: Ingress
   metadata:
     name: my-ingress
     namespace: default
     annotations:
       service.beta.kubernetes.io/aws-load-balancer-type: "external"
   spec:
     ingressClassName: cilium
     rules:
     - http:
         paths:
         - backend:
             service:
               name: details
               port:
                 number: 9080
           path: /details
           pathType: Prefix
   ```

1. 將傳入資源套用至您的叢集。

   ```
   kubectl apply -f my-ingress.yaml
   ```

1. 確認傳入資源和對應的服務已建立。在此階段，傳入資源的 `ADDRESS` 欄位預期不會填入 IP 位址或主機名稱，而且傳入資源的 LoadBalancer 類型的共用或專用服務同樣不會指派 IP 位址或主機名稱。

   ```
   kubectl get ingress my-ingress
   ```

   ```
   NAME         CLASS    HOSTS   ADDRESS   PORTS   AGE
   my-ingress   cilium   *                 80      8s
   ```

   對於負載平衡器模式 `shared` 

   ```
   kubectl -n kube-system get svc cilium-ingress
   ```

   ```
   NAME             TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
   cilium-ingress   LoadBalancer   172.16.217.48   <pending>     80:32359/TCP,443:31090/TCP   10m
   ```

   對於負載平衡器模式 `dedicated` 

   ```
   kubectl -n default get svc cilium-ingress-my-ingress
   ```

   ```
   NAME                        TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
   cilium-ingress-my-ingress   LoadBalancer   172.16.193.15   <pending>     80:32088/TCP,443:30332/TCP   25s
   ```

1. 繼續 [服務類型 LoadBalancer](#hybrid-nodes-ingress-cilium-loadbalancer) 以設定傳入資源，進而使用 Cilium Load Balancer IPAM 配置的 IP 位址；以及使用 [服務類型 NodePort](#hybrid-nodes-ingress-cilium-nodeport) 或 [主機網路](#hybrid-nodes-ingress-cilium-host-network) 以設定傳入資源，進而使用 NodePort 或主機網路位址。

## 服務類型 LoadBalancer
<a name="hybrid-nodes-ingress-cilium-loadbalancer"></a>

### 現有的負載平衡器基礎結構
<a name="_existing_load_balancer_infrastructure"></a>

根據預設，對於 Cilium Ingress 和 Cilium Gateway，Cilium 會為傳入/閘道資源建立 LoadBalancer 類型的 Kubernetes Service。Cilium 建立的服務屬性可以透過傳入和閘道資源進行設定。當您建立傳入或閘道資源時，傳入或閘道的外部公開 IP 位址或主機名稱會從負載平衡器基礎結構進行配置，並且通常由傳入或閘道控制器進行佈建。

許多傳入和閘道控制器會使用註釋來偵測和設定負載平衡器基礎結構。如上述範例所示，這些傳入和閘道控制器的註釋會在傳入或閘道資源上設定。如需其支援的註釋，請參閱傳入或閘道控制器的文件，而如需熱門控制器的清單，則請參閱 [Kubernetes Ingress 文件](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/)和 [Kubernetes Gateway 文件](https://gateway-api.sigs.k8s.io/implementations/)。

**重要**  
Cilium Ingress 和 Gateway 不能搭配具有 EKS 混合節點的 AWS Load Balancer 控制器及 AWS Network Load Balancer (NLB) 使用。嘗試將其一起使用會導致未註冊的目標，因為當 NLB 的 `target-type` 設定為 `ip` 時，NLB 會嘗試直接連接至支援 LoadBalancer 類型的服務的 Pod IP (要求搭配使用 NLB 與在 EKS 混合節點上執行的工作負載)。

### 沒有負載平衡器基礎結構
<a name="_no_load_balancer_infrastructure"></a>

如果您的環境中沒有負載平衡器基礎結構和對應的傳入/閘道控制器，則可以將傳入/閘道資源和對應的 LoadBalancer 類型的服務設定為使用 Cilium [Load Balancer IP 位址管理](https://docs.cilium.io/en/stable/network/lb-ipam/) (LB IPAM) 配置的 IP 位址。Cilium LB IPAM 可以使用來自您內部部署環境的已知 IP 位址範圍進行設定，並且可以使用 Cilium 的內建邊界閘道協定 (BGP) 支援或 L2 公告，從而向內部部署網路公告 LoadBalancer IP 位址。

以下範例說明如何使用 IP 位址設定 Cilium 的 LB IPAM 以用於您的傳入/閘道資源，以及如何設定 Cilium BGP 控制平面以向內部部署網路公告 LoadBalancer IP 位址。根據預設，Cilium 的 LB IPAM 功能已啟用，但在建立 `CiliumLoadBalancerIPPool` 資源之前不會啟動。

#### 先決條件
<a name="_prerequisites_4"></a>
+ 遵循 [安裝 Cilium Ingress](#hybrid-nodes-ingress-cilium-ingress-install) 或 [安裝 Cilium Gateway](#hybrid-nodes-ingress-cilium-gateway-install) 中的指示安裝 Cilium Ingress 或 Gateway。
+ 遵循 [部署 Cilium Ingress](#hybrid-nodes-ingress-cilium-ingress-deploy) 或 [部署 Cilium Gateway](#hybrid-nodes-ingress-cilium-gateway-deploy) 中的指示，部署範例應用程式的 Cilium Ingress 或 Gateway 資源。
+ 遵循 [設定混合節點的 Cilium BGP](hybrid-nodes-cilium-bgp.md) 中的指示啟用 Cilium BGP 控制平面。如果您不想使用 BGP，則可以略過此先決條件，但在 Cilium LB IPAM 配置的 LoadBalancer IP 位址在內部部署網路上可路由之前，您將無法存取您的傳入或閘道資源。

#### 程序
<a name="_procedure_4"></a>

1. 選擇性地修補傳入或閘道資源，以請求用於 LoadBalancer 類型的服務的特定 IP 位址。如果您未請求特定 IP 位址，Cilium 將從後續步驟中的 `CiliumLoadBalancerIPPool` 資源中設定的 IP 位址範圍配置 IP 位址。在下列命令中，使用 IP 位址取代 `LB_IP_ADDRESS`，以請求 LoadBalancer 類型的服務。

    **閘道** 

   ```
   kubectl patch gateway -n default my-gateway --type=merge -p '{
     "spec": {
       "addresses": [{"type": "IPAddress", "value": "LB_IP_ADDRESS"}]
     }
   }'
   ```

    **Ingress** 

   ```
   kubectl patch ingress my-ingress --type=merge -p '{
     "metadata": {"annotations": {"lbipam.cilium.io/ips": "LB_IP_ADDRESS"}}
   }'
   ```

1. 使用 `CiliumLoadBalancerIPPool` 資源建立名為 `cilium-lbip-pool-ingress.yaml` 的檔案，以為您的傳入/閘道資源設定 Load Balancer IP 位址範圍。
   + 如果您使用的是 Cilium Ingress，Cilium 會自動將 `cilium.io/ingress: "true"` 標籤套用至其為傳入資源建立的服務。您可以在 `CiliumLoadBalancerIPPool` 資源定義的 `serviceSelector` 欄位中使用此標籤，以選取符合 LB IPAM 資格的服務。
   + 如果您使用的是 Cilium Gateway，則可以使用 `CiliumLoadBalancerIPPool` 資源定義的 `serviceSelector` 欄位中的 `gateway.networking.k8s.io/gateway-name` 標籤來選取符合 LB IPAM 資格的閘道資源。
   + 使用用於 Load Balancer IP 位址的 IP 位址範圍取代 `LB_IP_CIDR`。若要選取單一 IP 位址，請使用 `/32` CIDR。如需詳細資訊，請參閱 Cilium 文件中的 [LoadBalancer IP 位址管理](https://docs.cilium.io/en/stable/network/lb-ipam/)。

     ```
     apiVersion: cilium.io/v2alpha1
     kind: CiliumLoadBalancerIPPool
     metadata:
       name: bookinfo-pool
     spec:
       blocks:
       - cidr: "LB_IP_CIDR"
       serviceSelector:
         # if using Cilium Gateway
         matchExpressions:
           - { key: gateway.networking.k8s.io/gateway-name, operator: In, values: [ my-gateway ] }
         # if using Cilium Ingress
         matchLabels:
           cilium.io/ingress: "true"
     ```

1. 將 `CiliumLoadBalancerIPPool` 資源套用至您的叢集。

   ```
   kubectl apply -f cilium-lbip-pool-ingress.yaml
   ```

1. 確認已從 Cilium LB IPAM 為傳入/閘道資源配置 IP 位址。

    **閘道** 

   ```
   kubectl get gateway my-gateway
   ```

   ```
   NAME         CLASS    ADDRESS        PROGRAMMED   AGE
   my-gateway   cilium   LB_IP_ADDRESS    True         6m41s
   ```

    **Ingress** 

   ```
   kubectl get ingress my-ingress
   ```

   ```
   NAME         CLASS    HOSTS   ADDRESS        PORTS   AGE
   my-ingress   cilium   *       LB_IP_ADDRESS   80      10m
   ```

1. 使用 `CiliumBGPAdvertisement` 資源建立名為 `cilium-bgp-advertisement-ingress.yaml` 的檔案，以為您的傳入/閘道資源公告 LoadBalancer IP 位址。如果您不使用 Cilium BGP，則可以略過此步驟。用於傳入/閘道的 LoadBalancer IP 位址必須在內部部署網路上可路由，這樣您才能在下一個步驟中查詢服務。

   ```
   apiVersion: cilium.io/v2alpha1
   kind: CiliumBGPAdvertisement
   metadata:
     name: bgp-advertisement-lb-ip
     labels:
       advertise: bgp
   spec:
     advertisements:
       - advertisementType: "Service"
         service:
           addresses:
             - LoadBalancerIP
         selector:
           # if using Cilium Gateway
           matchExpressions:
             - { key: gateway.networking.k8s.io/gateway-name, operator: In, values: [ my-gateway ] }
           # if using Cilium Ingress
           matchLabels:
             cilium.io/ingress: "true"
   ```

1. 將 `CiliumBGPAdvertisement` 資源套用至您的叢集。

   ```
   kubectl apply -f cilium-bgp-advertisement-ingress.yaml
   ```

1. 使用從 Cilium LB IPAM 配置的 IP 位址存取服務。

   ```
   curl -s http://LB_IP_ADDRESS:80/details/1 | jq
   ```

   ```
   {
     "id": 1,
     "author": "William Shakespeare",
     "year": 1595,
     "type": "paperback",
     "pages": 200,
     "publisher": "PublisherA",
     "language": "English",
     "ISBN-10": "1234567890",
     "ISBN-13": "123-1234567890"
   }
   ```

## 服務類型 NodePort
<a name="hybrid-nodes-ingress-cilium-nodeport"></a>

如果您在環境中沒有負載平衡器基礎結構和對應的傳入控制器，或者您是自我管理負載平衡器基礎結構或使用 DNS 型負載平衡，則可以將 Cilium Ingress 設定為為傳入資源建立 NodePort 類型的服務。搭配 Cilium Ingress 使用 NodePort 時，NodePort 類型的服務會在連接埠範圍 30000-32767 內每個節點的連接埠上公開。在此模式中，當流量到達 NodePort 上叢集中的任何節點時，即會轉送到可傳回服務的 Pod，而這些 Pod 可能位於相同的節點，也可能位於不同的節點。

**注意**  
Cilium Gateway 計劃在 Cilium 版本 1.18.x 中對 NodePort 服務提供支援 ([\$127273](https://github.com/cilium/cilium/pull/27273))

### 先決條件
<a name="_prerequisites_5"></a>
+ 遵循 [安裝 Cilium Ingress](#hybrid-nodes-ingress-cilium-ingress-install) 中的指示安裝 Cilium Ingress。
+ 遵循 [部署 Cilium Ingress](#hybrid-nodes-ingress-cilium-ingress-deploy) 中的指示，部署範例應用程式的 Cilium Ingress 資源。

### 程序
<a name="_procedure_5"></a>

1. 修補現有的傳入資源 `my-ingress`，以將其從 LoadBalancer 類型的服務變更為 NodePort。

   ```
   kubectl patch ingress my-ingress --type=merge -p '{
       "metadata": {"annotations": {"ingress.cilium.io/service-type": "NodePort"}}
   }'
   ```

   如果您尚未建立傳入資源，則可以將下列傳入定義套用至叢集，進而建立傳入資源。請注意，以下傳入定義會使用 [部署 Cilium Ingress](#hybrid-nodes-ingress-cilium-ingress-deploy) 中所述的 Istio Bookinfo 範例應用程式。

   ```
   apiVersion: networking.k8s.io/v1
   kind: Ingress
   metadata:
     name: my-ingress
     namespace: default
     annotations:
       service.beta.kubernetes.io/aws-load-balancer-type: "external"
       "ingress.cilium.io/service-type": "NodePort"
   spec:
     ingressClassName: cilium
     rules:
     - http:
         paths:
         - backend:
             service:
               name: details
               port:
                 number: 9080
           path: /details
           pathType: Prefix
   ```

1. 確認傳入資源的服務已更新為使用服務類型 NodePort。請注意輸出中的 HTTP 通訊協定的連接埠。在以下範例中，此 HTTP 連接埠是 `32353`，且在後續步驟中，將用其來查詢服務。搭配 NodePort 類型的服務使用 Cilium Ingress 的優點是，對於 Ingress 流量，您可以套用路徑和以主機為基礎的路由以及相關網路政策，而對於沒有 Ingress 的標準 NodePort 類型的服務，您則無法如此操作。

   ```
   kubectl -n default get svc cilium-ingress-my-ingress
   ```

   ```
   NAME                        TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
   cilium-ingress-my-ingress   NodePort   172.16.47.153   <none>        80:32353/TCP,443:30253/TCP   27m
   ```

1. 獲取您叢集節點的 IP 位址。

   ```
   kubectl get nodes -o wide
   ```

   ```
   NAME                   STATUS   ROLES    AGE   VERSION               INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME
   mi-026d6a261e355fba7   Ready    <none>   23h   v1.32.3-eks-473151a   10.80.146.150   <none>        Ubuntu 22.04.5 LTS   5.15.0-142-generic   containerd://1.7.27
   mi-082f73826a163626e   Ready    <none>   23h   v1.32.3-eks-473151a   10.80.146.32    <none>        Ubuntu 22.04.4 LTS   5.15.0-142-generic   containerd://1.7.27
   mi-09183e8a3d755abf6   Ready    <none>   23h   v1.32.3-eks-473151a   10.80.146.33    <none>        Ubuntu 22.04.4 LTS   5.15.0-142-generic   containerd://1.7.27
   mi-0d78d815980ed202d   Ready    <none>   23h   v1.32.3-eks-473151a   10.80.146.97    <none>        Ubuntu 22.04.4 LTS   5.15.0-142-generic   containerd://1.7.27
   mi-0daa253999fe92daa   Ready    <none>   23h   v1.32.3-eks-473151a   10.80.146.100   <none>        Ubuntu 22.04.4 LTS   5.15.0-142-generic   containerd://1.7.27
   ```

1. 使用節點的 IP 位址和上文擷取的 NodePort 存取 NodePort 類型的服務。在以下範例中，使用的節點 IP 位址是 `10.80.146.32`，而 NodePort 是 `32353`。使用您環境的值取代這些值。

   ```
   curl -s http://10.80.146.32:32353/details/1 | jq
   ```

   ```
   {
     "id": 1,
     "author": "William Shakespeare",
     "year": 1595,
     "type": "paperback",
     "pages": 200,
     "publisher": "PublisherA",
     "language": "English",
     "ISBN-10": "1234567890",
     "ISBN-13": "123-1234567890"
   }
   ```

## 主機網路
<a name="hybrid-nodes-ingress-cilium-host-network"></a>

類似於 NodePort 類型的服務，如果您沒有負載平衡器基礎結構和傳入或閘道控制器，或者如果您使用外部負載平衡器自我管理負載平衡，則可以將 Cilium Ingress 和 Cilium Gateway 設定為可直接在主機網路上公開傳入和閘道資源。為傳入或閘道資源啟用主機網路模式時，會自動停用 LoadBalancer 類型和 NodePort 類型的服務模式，而主機網路模式會與每個傳入或閘道資源的這些替代模式互斥。相較於 NodePort 類型的服務模式，主機網路模式能擴增可使用的連接埠範圍 (不限於 30000-32767 NodePort 範圍)，並且您可以設定 Envoy 代理在主機網路上執行的節點子集。

### 先決條件
<a name="_prerequisites_6"></a>
+ 遵循 [安裝 Cilium Ingress](#hybrid-nodes-ingress-cilium-ingress-install) 或 [安裝 Cilium Gateway](#hybrid-nodes-ingress-cilium-gateway-install) 中的指示安裝 Cilium Ingress 或 Gateway。

### 程序
<a name="_procedure_6"></a>

#### 閘道
<a name="_gateway"></a>

1. 建立名為 `cilium-gateway-host-network.yaml` 且具有下列內容的檔案。

   ```
   gatewayAPI:
     enabled: true
     hostNetwork:
       enabled: true
       # uncomment to restrict nodes where Envoy proxies run on the host network
       # nodes:
       #   matchLabels:
       #     role: gateway
   ```

1. 將主機網路 Cilium Gateway 組態套用至您的叢集。

   ```
   helm upgrade cilium oci://public.ecr.aws/eks/cilium/cilium \
     --namespace kube-system \
     --reuse-values \
     --set operator.rollOutPods=true \
     -f cilium-gateway-host-network.yaml
   ```

   如果您尚未建立閘道資源，則可以將下列閘道定義套用至叢集，進而建立閘道資源。以下閘道定義會使用 [部署 Cilium Gateway](#hybrid-nodes-ingress-cilium-gateway-deploy) 中所述的 Istio Bookinfo 範例應用程式。在以下範例中，閘道資源會設定為使用 HTTP 接聽程式的 `8111` 連接埠，而這是主機網路上執行的 Envoy 代理程式的共用接聽程式連接埠。如果您為閘道資源使用了具有特殊權限的連接埠 (低於 1023)，請參閱 [Cilium 文件](https://docs.cilium.io/en/stable/network/servicemesh/gateway-api/gateway-api/#bind-to-privileged-port)以取得說明。

   ```
   ---
   apiVersion: gateway.networking.k8s.io/v1
   kind: Gateway
   metadata:
     name: my-gateway
   spec:
     gatewayClassName: cilium
     listeners:
     - protocol: HTTP
       port: 8111
       name: web-gw
       allowedRoutes:
         namespaces:
           from: Same
   ---
   apiVersion: gateway.networking.k8s.io/v1
   kind: HTTPRoute
   metadata:
     name: http-app-1
   spec:
     parentRefs:
     - name: my-gateway
       namespace: default
     rules:
     - matches:
       - path:
           type: PathPrefix
           value: /details
       backendRefs:
       - name: details
         port: 9080
   ```

   您可以使用下列命令來觀測套用的 Cilium Envoy 組態。

   ```
   kubectl get cec cilium-gateway-my-gateway -o yaml
   ```

   您可以使用下列命令來取得 `cilium-gateway-my-gateway` 服務的 Envoy 接聽程式連接埠。在此範例中，共用接聽程式連接埠為 `8111`。

   ```
   kubectl get cec cilium-gateway-my-gateway -o jsonpath={.spec.services[0].ports[0]}
   ```

1. 獲取您叢集節點的 IP 位址。

   ```
   kubectl get nodes -o wide
   ```

   ```
   NAME                   STATUS   ROLES    AGE   VERSION               INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME
   mi-026d6a261e355fba7   Ready    <none>   23h   v1.32.3-eks-473151a   10.80.146.150   <none>        Ubuntu 22.04.5 LTS   5.15.0-142-generic   containerd://1.7.27
   mi-082f73826a163626e   Ready    <none>   23h   v1.32.3-eks-473151a   10.80.146.32    <none>        Ubuntu 22.04.4 LTS   5.15.0-142-generic   containerd://1.7.27
   mi-09183e8a3d755abf6   Ready    <none>   23h   v1.32.3-eks-473151a   10.80.146.33    <none>        Ubuntu 22.04.4 LTS   5.15.0-142-generic   containerd://1.7.27
   mi-0d78d815980ed202d   Ready    <none>   23h   v1.32.3-eks-473151a   10.80.146.97    <none>        Ubuntu 22.04.4 LTS   5.15.0-142-generic   containerd://1.7.27
   mi-0daa253999fe92daa   Ready    <none>   23h   v1.32.3-eks-473151a   10.80.146.100   <none>        Ubuntu 22.04.4 LTS   5.15.0-142-generic   containerd://1.7.27
   ```

1. 使用節點的 IP 位址和 `cilium-gateway-my-gateway` 資源的接聽程式連接埠存取服務。在以下範例中，使用的節點 IP 位址是 `10.80.146.32`，而接聽程式連接埠是 `8111`。使用您環境的值取代這些值。

   ```
   curl -s http://10.80.146.32:8111/details/1 | jq
   ```

   ```
   {
     "id": 1,
     "author": "William Shakespeare",
     "year": 1595,
     "type": "paperback",
     "pages": 200,
     "publisher": "PublisherA",
     "language": "English",
     "ISBN-10": "1234567890",
     "ISBN-13": "123-1234567890"
   }
   ```

#### Ingress
<a name="_ingress"></a>

由於上游 Cilium 問題 ([\$134028](https://github.com/cilium/cilium/issues/34028))，主機網路模式中的 Cilium Ingress 需要使用 `loadbalancerMode: shared`，而這會為叢集中的所有傳入資源建立 ClusterIP 類型的單一服務。如果您為傳入資源使用了具有特殊權限的連接埠 (低於 1023)，請參閱 [Cilium 文件](https://docs.cilium.io/en/stable/network/servicemesh/ingress/#bind-to-privileged-port)以取得說明。

1. 建立名為 `cilium-ingress-host-network.yaml` 且具有下列內容的檔案。

   ```
   ingressController:
     enabled: true
     loadbalancerMode: shared
     # This is a workaround for the upstream Cilium issue
     service:
       externalTrafficPolicy: null
       type: ClusterIP
     hostNetwork:
       enabled: true
       # ensure the port does not conflict with other services on the node
       sharedListenerPort: 8111
       # uncomment to restrict nodes where Envoy proxies run on the host network
       # nodes:
       #   matchLabels:
       #     role: ingress
   ```

1. 將主機網路 Cilium Ingress 組態套用至您的叢集。

   ```
   helm upgrade cilium oci://public.ecr.aws/eks/cilium/cilium \
     --namespace kube-system \
     --reuse-values \
     --set operator.rollOutPods=true \
     -f cilium-ingress-host-network.yaml
   ```

   如果您尚未建立傳入資源，則可以將下列傳入定義套用至叢集，進而建立傳入資源。以下傳入定義會使用 [部署 Cilium Ingress](#hybrid-nodes-ingress-cilium-ingress-deploy) 中所述的 Istio Bookinfo 範例應用程式。

   ```
   apiVersion: networking.k8s.io/v1
   kind: Ingress
   metadata:
     name: my-ingress
     namespace: default
   spec:
     ingressClassName: cilium
     rules:
     - http:
         paths:
         - backend:
             service:
               name: details
               port:
                 number: 9080
           path: /details
           pathType: Prefix
   ```

   您可以使用下列命令來觀測套用的 Cilium Envoy 組態。

   ```
   kubectl get cec -n kube-system cilium-ingress -o yaml
   ```

   您可以使用下列命令來取得 `cilium-ingress` 服務的 Envoy 接聽程式連接埠。在此範例中，共用接聽程式連接埠為 `8111`。

   ```
   kubectl get cec -n kube-system cilium-ingress -o jsonpath={.spec.services[0].ports[0]}
   ```

1. 獲取您叢集節點的 IP 位址。

   ```
   kubectl get nodes -o wide
   ```

   ```
   NAME                   STATUS   ROLES    AGE   VERSION               INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME
   mi-026d6a261e355fba7   Ready    <none>   23h   v1.32.3-eks-473151a   10.80.146.150   <none>        Ubuntu 22.04.5 LTS   5.15.0-142-generic   containerd://1.7.27
   mi-082f73826a163626e   Ready    <none>   23h   v1.32.3-eks-473151a   10.80.146.32    <none>        Ubuntu 22.04.4 LTS   5.15.0-142-generic   containerd://1.7.27
   mi-09183e8a3d755abf6   Ready    <none>   23h   v1.32.3-eks-473151a   10.80.146.33    <none>        Ubuntu 22.04.4 LTS   5.15.0-142-generic   containerd://1.7.27
   mi-0d78d815980ed202d   Ready    <none>   23h   v1.32.3-eks-473151a   10.80.146.97    <none>        Ubuntu 22.04.4 LTS   5.15.0-142-generic   containerd://1.7.27
   mi-0daa253999fe92daa   Ready    <none>   23h   v1.32.3-eks-473151a   10.80.146.100   <none>        Ubuntu 22.04.4 LTS   5.15.0-142-generic   containerd://1.7.27
   ```

1. 使用節點的 IP 位址和 `cilium-ingress` 資源的 `sharedListenerPort` 存取服務。在以下範例中，使用的節點 IP 位址是 `10.80.146.32`，而接聽程式連接埠是 `8111`。使用您環境的值取代這些值。

   ```
   curl -s http://10.80.146.32:8111/details/1 | jq
   ```

   ```
   {
     "id": 1,
     "author": "William Shakespeare",
     "year": 1595,
     "type": "paperback",
     "pages": 200,
     "publisher": "PublisherA",
     "language": "English",
     "ISBN-10": "1234567890",
     "ISBN-13": "123-1234567890"
   }
   ```

# 為混合節點設定 LoadBalancer 類型的服務
<a name="hybrid-nodes-load-balancing"></a>

本主題會說明如何為在 Amazon EKS 混合節點上執行的應用程式設定第 4 層 (L4) 負載平衡。LoadBalancer 類型的 Kubernetes Service 可用於向叢集外部公開 Kubernetes 應用程式。LoadBalancer 類型的服務通常可與雲端或內部部署環境中的實體負載平衡器基礎結構搭配使用，進而提供工作負載的流量。此負載平衡器基礎結構通常使用環境特定的控制器進行佈建。

 AWS 支援針對 EKS 混合節點上執行的 LoadBalancer 類型的服務使用 AWS Network Load Balancer (NLB) 和 Cilium。使用 NLB 還是 Cilium 的決定取決於應用程式流量的來源。如果應用程式流量來自 AWS 區域，則 AWS 會建議使用 AWS NLB 和 AWS Load Balancer 控制器。如果應用程式流量來自本機內部部署或邊緣環境，則 AWS 會建議使用 Cilium 的內建負載平衡功能，而該功能可在您的環境中搭配或不搭配負載平衡器基礎結構使用。

如需第 7 層 (L7) 應用程式流量負載平衡，請參閱 [設定混合節點的 Kubernetes Ingress](hybrid-nodes-ingress.md)。如需使用 EKS 進行負載平衡的一般資訊，請參閱[負載平衡的最佳實務](https://docs.aws.amazon.com/eks/latest/best-practices/load-balancing.html)。

## AWS Network Load Balancer
<a name="hybrid-nodes-service-lb-nlb"></a>

對於在混合節點上執行的工作負載，您可以搭配目標類型 `ip` 使用 [AWS Load Balancer 控制器](aws-load-balancer-controller.md)和 NLB。使用目標類型 `ip` 時，NLB 可繞過服務層網路路徑，將流量直接轉送至 Pod。若要讓 NLB 達到混合節點上的 Pod IP 目標，您的內部部署 Pod CIDR 必須在內部部署網路上可路由。此外，AWS Load Balancer 控制器使用 Webhook 並且需要從 EKS 控制平面直接通訊。如需詳細資訊，請參閱 [設定混合節點的 Webhook](hybrid-nodes-webhooks.md)。
+ 如需有關 AWS Network Load Balancer 和 AWS Load Balancer 控制器的其他資訊，請參閱 [透過 Network Load Balancer 路由 TCP 與 UDP 流量](network-load-balancing.md) 以取得子網路組態需求，並參閱 [搭配 Helm 的 Install AWS Load Balancer 控制器](lbc-helm.md) 和[負載平衡的最佳實務](https://docs.aws.amazon.com/eks/latest/best-practices/load-balancing.html)。
+ 請參閱 [AWS Load Balancer 控制器 NLB 組態](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/service/nlb/)，了解可套用至具有 AWS Network Load Balancer 的 `LoadBalancer` 類型的服務的組態。

### 先決條件
<a name="_prerequisites"></a>
+ 遵循 [設定混合節點的 CNI](hybrid-nodes-cni.md) 中的指示安裝 Cilium。
+ 遵循 [設定混合節點的 Cilium BGP](hybrid-nodes-cilium-bgp.md) 中的指示啟用 Cilium BGP 控制平面。如果您不想使用 BGP，則必須使用替代方法，以讓內部部署 Pod CIDR 在內部部署網路上可路由，如需詳細資訊，請參閱 [可路由的遠端 Pod CIDR](hybrid-nodes-concepts-kubernetes.md#hybrid-nodes-concepts-k8s-pod-cidrs)。
+ 已在命令列環境中安裝 Helm，請參閱[安裝 Helm 說明](helm.md)。
+ 已在命令列環境中安裝 eksctl，請參閱[安裝 eksctl 說明](install-kubectl.md#eksctl-install-update)。

### 程序
<a name="_procedure"></a>

1. 下載適用於 AWS Load Balancer 控制器的 IAM 政策，允許它代表您呼叫 AWS API。

   ```
   curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/refs/heads/main/docs/install/iam_policy.json
   ```

1. 使用上一個步驟中下載的政策，建立 IAM 政策。

   ```
   aws iam create-policy \
       --policy-name AWSLoadBalancerControllerIAMPolicy \
       --policy-document file://iam_policy.json
   ```

1. 使用您的設定取代下列值：叢集名稱 (`CLUSTER_NAME`)、AWS 區域 (`AWS_REGION`) 和 AWS 帳戶 ID (`AWS_ACCOUNT_ID`)，然後執行下列命令。

   ```
   eksctl create iamserviceaccount \
       --cluster=CLUSTER_NAME \
       --namespace=kube-system \
       --name=aws-load-balancer-controller \
       --attach-policy-arn=arn:aws:iam::AWS_ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy \
       --override-existing-serviceaccounts \
       --region AWS_REGION \
       --approve
   ```

1. 新增 eks-charts Helm Chart 儲存庫。AWS 會在 GitHub 上維護此儲存庫。

   ```
   helm repo add eks https://aws.github.io/eks-charts
   ```

1. 更新您的本機 Helm 儲存庫，以確保您擁有最近的圖表。

   ```
   helm repo update eks
   ```

1. 安裝 AWS Load Balancer 控制器。使用您的設定取代下列值：叢集名稱 (`CLUSTER_NAME`)、AWS 區域 (`AWS_REGION`)、VPC ID (`VPC_ID`) 和 AWS Load Balancer 控制器 Helm Chart 版本 (`AWS_LBC_HELM_VERSION`)。您可以透過執行 `helm search repo eks/aws-load-balancer-controller --versions` 來尋找最新版本的 Helm Chart。如果您執行具有混合節點和 AWS 雲端中的節點的混合模式叢集，則您可以遵循 [AWS Load Balancer 控制器](hybrid-nodes-webhooks.md#hybrid-nodes-mixed-lbc) 中的指示，在雲端節點上執行 AWS Load Balancer 控制器。

   ```
   helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
     -n kube-system \
     --version AWS_LBC_HELM_VERSION \
     --set clusterName=CLUSTER_NAME \
     --set region=AWS_REGION \
     --set vpcId=VPC_ID \
     --set serviceAccount.create=false \
     --set serviceAccount.name=aws-load-balancer-controller
   ```

1. 驗證 AWS Load Balancer 控制器是否已成功安裝。

   ```
   kubectl get -n kube-system deployment aws-load-balancer-controller
   ```

   ```
   NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
   aws-load-balancer-controller   2/2     2            2           84s
   ```

1. 在名為 `tcp-sample-app.yaml` 的檔案中定義範例應用程式。以下範例使用具有 TCP 連接埠的簡單的 NGINX 部署。

   ```
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: tcp-sample-app
     namespace: default
   spec:
     replicas: 3
     selector:
       matchLabels:
         app: nginx
     template:
       metadata:
         labels:
           app: nginx
       spec:
         containers:
           - name: nginx
             image: public.ecr.aws/nginx/nginx:1.23
             ports:
               - name: tcp
                 containerPort: 80
   ```

1. 將部署套用至叢集。

   ```
   kubectl apply -f tcp-sample-app.yaml
   ```

1. 在名為 `tcp-sample-service.yaml` 的檔案中定義部署的 LoadBalancer 類型服務。

   ```
   apiVersion: v1
   kind: Service
   metadata:
     name: tcp-sample-service
     namespace: default
     annotations:
       service.beta.kubernetes.io/aws-load-balancer-type: external
       service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
       service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
   spec:
     ports:
       - port: 80
         targetPort: 80
         protocol: TCP
     type: LoadBalancer
     selector:
       app: nginx
   ```

1. 將服務組態套用至叢集。

   ```
   kubectl apply -f tcp-sample-service.yaml
   ```

1. 為服務佈建 NLB 可能需要幾分鐘的時間。佈建 NLB 後，服務將會為其指派一個與 NLB 部署的 DNS 名稱對應的地址。

   ```
   kubectl get svc tcp-sample-service
   ```

   ```
   NAME                 TYPE           CLUSTER-IP       EXTERNAL-IP                                                                    PORT(S)        AGE
   tcp-sample-service   LoadBalancer   172.16.115.212   k8s-default-tcpsampl-xxxxxxxxxx-xxxxxxxxxxxxxxxx.elb.<region>.amazonaws.com   80:30396/TCP   8s
   ```

1. 使用 NLB 的地址存取服務。

   ```
   curl k8s-default-tcpsampl-xxxxxxxxxx-xxxxxxxxxxxxxxxx.elb.<region>.amazonaws.com
   ```

   範例輸出如下。

   ```
   <!DOCTYPE html>
   <html>
   <head>
   <title>Welcome to nginx!</title>
   [...]
   ```

1. 清除您建立的 資源。

   ```
   kubectl delete -f tcp-sample-service.yaml
   kubectl delete -f tcp-sample-app.yaml
   ```

## Cilium 叢集內負載平衡
<a name="hybrid-nodes-service-lb-cilium"></a>

Cilium 可用作在 EKS 混合節點上執行的工作負載的叢集內負載平衡器，而這對於沒有負載平衡器基礎結構的環境非常有用。Cilium 的負載平衡功能以 Cilium 功能的組合為建置基礎，包括 kube-proxy 取代、Load Balancer IP 位址管理 (IPAM) 和 BGP 控制平面。這些功能的責任詳述如下：
+  **Cilium kube-proxy 取代**：處理將服務流量路由到後端 Pod。
+  **Cilium Load Balancer IPAM**：管理可指派給 `LoadBalancer` 類型的服務的 IP 位址。
+  **Cilium BGP 控制平面**：將 Load Balancer IPAM 配置的 IP 位址公告至內部部署網路。

如果您沒有使用 Cilium 的 kube-proxy 取代，您仍然可以使用 Cilium Load Balancer IPAM 和 BGP 控制平面，以為 LoadBalancer 類型的服務配置和指派 IP 位址。如果您沒有使用 Cilium 的 kube-proxy 取代，則根據預設，EKS 中服務至後端 Pod 的負載平衡將由 kube-proxy 和 iptables 處理。

### 先決條件
<a name="_prerequisites_2"></a>
+ 在啟用或未啟用 kube-proxy 取代的情況下，遵循 [設定混合節點的 CNI](hybrid-nodes-cni.md) 中的指示安裝 Cilium。Cilium 的 kube-proxy 取代需要執行至少與 v4.19.57、v5.1.16 或 v5.2.0 相近的 Linux 核心作業系統。除了 Red Hat Enterprise Linux (RHEL) 8.x 外，所有支援與混合節點搭配使用的最新版作業系統皆符合此條件。
+ 遵循 [設定混合節點的 Cilium BGP](hybrid-nodes-cilium-bgp.md) 中的指示啟用 Cilium BGP 控制平面。如果您不想使用 BGP，則必須使用替代方法，以讓內部部署 Pod CIDR 在內部部署網路上可路由，如需詳細資訊，請參閱 [可路由的遠端 Pod CIDR](hybrid-nodes-concepts-kubernetes.md#hybrid-nodes-concepts-k8s-pod-cidrs)。
+ 已在命令列環境中安裝 Helm，請參閱[安裝 Helm 說明](helm.md)。

### 程序
<a name="_procedure_2"></a>

1. 使用 `CiliumLoadBalancerIPPool` 資源建立名為 `cilium-lbip-pool-loadbalancer.yaml` 的檔案，以為 Load Balancer 類型的服務設定 Load Balancer IP 位址範圍。
   + 使用用於 Load Balancer IP 位址的 IP 位址範圍取代 `LB_IP_CIDR`。若要選取單一 IP 位址，請使用 `/32` CIDR。如需詳細資訊，請參閱 Cilium 文件中的 [LoadBalancer IP 位址管理](https://docs.cilium.io/en/stable/network/lb-ipam/)。
   + `serviceSelector` 欄位設定為與您將在後續步驟中建立的服務名稱相符。使用此組態，此集區的 IP 將僅會配置給名稱為 `tcp-sample-service` 的服務。

     ```
     apiVersion: cilium.io/v2alpha1
     kind: CiliumLoadBalancerIPPool
     metadata:
       name: tcp-service-pool
     spec:
       blocks:
       - cidr: "LB_IP_CIDR"
       serviceSelector:
         matchLabels:
           io.kubernetes.service.name: tcp-sample-service
     ```

1. 將 `CiliumLoadBalancerIPPool` 資源套用至您的叢集。

   ```
   kubectl apply -f cilium-lbip-pool-loadbalancer.yaml
   ```

1. 確認集區中至少有一個 IP 位址可用。

   ```
   kubectl get ciliumloadbalancerippools.cilium.io
   ```

   ```
   NAME               DISABLED   CONFLICTING   IPS AVAILABLE   AGE
   tcp-service-pool   false      False         1               24m
   ```

1. 使用 `CiliumBGPAdvertisement` 資源建立名為 `cilium-bgp-advertisement-loadbalancer.yaml` 的檔案，以公告您將在下一步驟中建立的服務的負載平衡器 IP 位址。如果您不使用 Cilium BGP，則可以略過此步驟。用於服務的負載平衡器 IP 位址必須在內部部署網路上可路由，這樣您才能在最後一個步驟中查詢服務。
   + `advertisementType` 欄位設定為 `Service`，而 `service.addresses` 則設定為 `LoadBalancerIP`，以便僅為 `LoadBalancer` 類型的服務公告 `LoadBalancerIP`。
   + `selector` 欄位設定為與您將在後續步驟中建立的服務名稱相符。使用此組態時，將僅會公告名稱為 `tcp-sample-service` 的服務的 `LoadBalancerIP`。

     ```
     apiVersion: cilium.io/v2alpha1
     kind: CiliumBGPAdvertisement
     metadata:
       name: bgp-advertisement-tcp-service
       labels:
         advertise: bgp
     spec:
       advertisements:
         - advertisementType: "Service"
           service:
             addresses:
               - LoadBalancerIP
           selector:
             matchLabels:
               io.kubernetes.service.name: tcp-sample-service
     ```

1. 將 `CiliumBGPAdvertisement` 資源套用至您的叢集。如果您不使用 Cilium BGP，則可以略過此步驟。

   ```
   kubectl apply -f cilium-bgp-advertisement-loadbalancer.yaml
   ```

1. 在名為 `tcp-sample-app.yaml` 的檔案中定義範例應用程式。以下範例使用具有 TCP 連接埠的簡單的 NGINX 部署。

   ```
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: tcp-sample-app
     namespace: default
   spec:
     replicas: 3
     selector:
       matchLabels:
         app: nginx
     template:
       metadata:
         labels:
           app: nginx
       spec:
         containers:
           - name: nginx
             image: public.ecr.aws/nginx/nginx:1.23
             ports:
               - name: tcp
                 containerPort: 80
   ```

1. 將部署套用至叢集。

   ```
   kubectl apply -f tcp-sample-app.yaml
   ```

1. 在名為 `tcp-sample-service.yaml` 的檔案中定義部署的 LoadBalancer 類型服務。
   + 您可以從負載平衡器 IP 集區請求特定的 IP 位址，並在服務物件上加上 `lbipam.cilium.io/ips` 註釋。如果您不想為服務請求特定的 IP 位址，則可移除此註釋。
   + 需要 `loadBalancerClass` 規格欄位，才能防止舊版 AWS 雲端提供者為服務建立 Classic Load Balancer。在以下範例中，這會設定為 `io.cilium/bgp-control-plane`，以使用 Cilium 的 BGP 控制平面作為負載平衡器類別。或者，此欄位可設定為 `io.cilium/l2-announcer`，以使用 Cilium 的 [L2 功能公告](https://docs.cilium.io/en/latest/network/l2-announcements/) (目前為 beta 版且未受 AWS 正式支援)。

     ```
     apiVersion: v1
     kind: Service
     metadata:
       name: tcp-sample-service
       namespace: default
       annotations:
         lbipam.cilium.io/ips: "LB_IP_ADDRESS"
     spec:
       loadBalancerClass: io.cilium/bgp-control-plane
       ports:
         - port: 80
           targetPort: 80
           protocol: TCP
       type: LoadBalancer
       selector:
         app: nginx
     ```

1. 將服務套用至叢集。服務將使用外部 IP 位址建立，而您可用其來存取應用程式。

   ```
   kubectl apply -f tcp-sample-service.yaml
   ```

1. 確認服務已成功建立，並從上一個步驟中建立的 `CiliumLoadBalancerIPPool` 為其指派 IP。

   ```
   kubectl get svc tcp-sample-service
   ```

   ```
   NAME                 TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
   tcp-sample-service   LoadBalancer   172.16.117.76   LB_IP_ADDRESS   80:31129/TCP   14m
   ```

1. 如果您以 kube-proxy 取代模式使用 Cilium，您可以執行下列命令，以確認 Cilium 正在處理服務的負載平衡。在以下輸出中，`10.86.2.x` 位址是服務的後端 Pod 的 Pod IP 位址。

   ```
   kubectl -n kube-system exec ds/cilium -- cilium-dbg service list
   ```

   ```
   ID   Frontend               Service Type   Backend
   ...
   41   LB_IP_ADDRESS:80/TCP   LoadBalancer   1 => 10.86.2.76:80/TCP (active)
                                              2 => 10.86.2.130:80/TCP (active)
                                              3 => 10.86.2.141:80/TCP (active)
   ```

1. 確認 Cilium 正透過 BGP 將 IP 位址公告至內部部署網路。在以下範例中，有五個混合節點，並且每個節點都會向內部部署網路公告 `tcp-sample-service` 服務的 `LB_IP_ADDRESS`。

   ```
   Node                   VRouter      Prefix             NextHop   Age     Attrs
   mi-026d6a261e355fba7   NODES_ASN
                     LB_IP_ADDRESS/32   0.0.0.0   12m3s   [{Origin: i} {Nexthop: 0.0.0.0}]
   mi-082f73826a163626e   NODES_ASN
                     LB_IP_ADDRESS/32   0.0.0.0   12m3s   [{Origin: i} {Nexthop: 0.0.0.0}]
   mi-09183e8a3d755abf6   NODES_ASN
                     LB_IP_ADDRESS/32   0.0.0.0   12m3s   [{Origin: i} {Nexthop: 0.0.0.0}]
   mi-0d78d815980ed202d   NODES_ASN
                     LB_IP_ADDRESS/32   0.0.0.0   12m3s   [{Origin: i} {Nexthop: 0.0.0.0}]
   mi-0daa253999fe92daa   NODES_ASN
                     LB_IP_ADDRESS/32   0.0.0.0   12m3s   [{Origin: i} {Nexthop: 0.0.0.0}]
   ```

1. 使用指派的 load balancerIP 位址存取服務。

   ```
   curl LB_IP_ADDRESS
   ```

   範例輸出如下。

   ```
   <!DOCTYPE html>
   <html>
   <head>
   <title>Welcome to nginx!</title>
   [...]
   ```

1. 清除您建立的 資源。

   ```
   kubectl delete -f tcp-sample-service.yaml
   kubectl delete -f tcp-sample-app.yaml
   kubectl delete -f cilium-lb-ip-pool.yaml
   kubectl delete -f cilium-bgp-advertisement.yaml
   ```

# 設定混合節點的 Kubernetes 網路政策
<a name="hybrid-nodes-network-policies"></a>

 當使用 Cilium 作為 CNI 搭配 EKS 混合節點時，AWS 支援適用於 Pod 輸入和輸出流量的 Kubernetes 網路政策 (第 3 層/第 4 層)。如果您使用 AWS 雲端中的節點執行 EKS 叢集，則 AWS 支援 [Kubernetes 專用 Amazon VPC CNI 網路政策](cni-network-policy.md)。

本主題涵蓋如何使用 EKS 混合節點設定 Cilium 和 Kubernetes 網路政策。如需 Kubernetes 網路政策的詳細資訊，請參閱 Kubernetes 文件中的 [Kubernetes 網路政策](https://kubernetes.io/docs/concepts/services-networking/network-policies/)。

## 設定網路政策
<a name="hybrid-nodes-configure-network-policies"></a>

### 考量事項
<a name="_considerations"></a>
+  AWS 支援上游 Kubernetes 網路政策和 Pod 輸入和輸出的規格。AWS 目前不支援 `CiliumNetworkPolicy` 或 `CiliumClusterwideNetworkPolicy`。
+ `policyEnforcementMode` Helm 值可用於控制預設的 Cilium 政策強制執行行為。預設行為允許所有輸出和輸入流量。當網路政策選取端點時，其會轉換為預設拒絕狀態，而該狀態僅允許明確允許的流量。如需[預設政策模式](https://docs.cilium.io/en/stable/security/policy/intro/#policy-mode-default)和[政策強制執行模式](https://docs.cilium.io/en/stable/security/policy/intro/#policy-enforcement-modes)的詳細資訊，請參閱 Cilium 文件。
+ 如果您要變更現有 Cilium 安裝的 `policyEnforcementMode`，則您必須重新啟動 Cilium 代理程式 DaemonSet，以套用新的政策強制執行模式。
+ 使用 `namespaceSelector` 和 `podSelector` 允許或拒絕往返具有相符標籤的命名空間和 Pod 之間的流量。`namespaceSelector` 和 `podSelector` 可與 `matchLabels` 或 `matchExpressions` 搭配使用，以根據其標籤選取命名空間和 Pod。
+ 使用 `ingress.ports` 和 `egress.ports` 允許或拒絕往返連接埠和通訊協定之間的流量。
+ `ipBlock` 欄位無法用於選擇性地允許或拒絕往返 Pod IP 位址 ([\$19209](https://github.com/cilium/cilium/issues/9209)) 的流量。針對節點 IP 使用 `ipBlock` 選取器是 Cilium 中的 Beta 版功能，且不受 AWS 支援。
+ 如需 Kubernetes 網路政策可用欄位的資訊，請參閱 Kubernetes 文件中的 [NetworkPolicy 資源](https://kubernetes.io/docs/concepts/services-networking/network-policies/#networkpolicy-resource)。

### 先決條件
<a name="_prerequisites"></a>
+ 遵循 [設定混合節點的 CNI](hybrid-nodes-cni.md) 中的指示安裝 Cilium。
+ 已在命令列環境中安裝 Helm，請參閱[安裝 Helm 說明](helm.md)。

### 程序
<a name="_procedure"></a>

下列程序會為範例微服務應用程式設定網路政策，以便元件只能與應用程式運作所需的其他元件通訊。程序會使用 [Istio Bookinfo](https://istio.io/latest/docs/examples/bookinfo/) 範例微服務應用程式。

Bookinfo 應用程式由四個單獨的微服務組成，且其關係如下：
+  **productpage**。productpage 微服務會呼叫詳細資訊並檢閱微服務來填入頁面。
+  **詳細資訊** 詳細資訊微服務包含書籍資訊。
+  **檢閱**。檢閱微服務包含書籍檢閱。其還會呼叫評分微服務。
+  **評分**。評分微服務包含隨附書籍檢閱的書籍排名資訊。

  1. 建立範例應用程式。

     ```
     kubectl apply -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/bookinfo/platform/kube/bookinfo.yaml
     ```

  1. 確認應用程式已成功執行，並記下 productpage 微服務的 Pod IP 位址。在後續步驟中，您將使用此 Pod IP 位址來查詢每個微服務。

     ```
     kubectl get pods -o wide
     ```

     ```
     NAME                              READY   STATUS    RESTARTS   AGE   IP            NODE
     details-v1-766844796b-9wff2       1/1     Running   0          7s    10.86.3.7     mi-0daa253999fe92daa
     productpage-v1-54bb874995-lwfgg   1/1     Running   0          7s    10.86.2.193   mi-082f73826a163626e
     ratings-v1-5dc79b6bcd-59njm       1/1     Running   0          7s    10.86.2.232   mi-082f73826a163626e
     reviews-v1-598b896c9d-p2289       1/1     Running   0          7s    10.86.2.47    mi-026d6a261e355fba7
     reviews-v2-556d6457d-djktc        1/1     Running   0          7s    10.86.3.58    mi-0daa253999fe92daa
     reviews-v3-564544b4d6-g8hh4       1/1     Running   0          7s    10.86.2.69    mi-09183e8a3d755abf6
     ```

  1. 建立將用於測試網路政策的 Pod。請注意，Pod 是在具有標籤 `access: true` 的 `default` 命名空間中建立的。

     ```
     kubectl run curl-pod --image=curlimages/curl -i --tty --labels=access=true --namespace=default --overrides='{"spec": { "nodeSelector": {"eks.amazonaws.com/compute-type": "hybrid"}}}' -- /bin/sh
     ```

  1. 測試對 productpage 微服務的存取。在以下範例中，我們使用 productpage Pod (`10.86.2.193`) 的 Pod IP 位址來查詢微服務。將此取代為您環境中 productpage Pod 的 Pod IP 位址。

     ```
     curl -s http://10.86.2.193:9080/productpage | grep -o "<title>.*</title>"
     ```

     ```
     <title>Simple Bookstore App</title>
     ```

  1. 您可以輸入 `exit` 來結束測試 curl Pod，並執行下列命令來重新連接至 Pod。

     ```
     kubectl attach curl-pod -c curl-pod -i -t
     ```

  1. 為了在下列步驟中示範網路政策的效果，我們會先建立一個網路政策，其中該政策會拒絕 BookInfo 微服務的所有流量。建立稱為 `network-policy-deny-bookinfo.yaml` 的檔案，其中會定義拒絕網路政策。

     ```
     apiVersion: networking.k8s.io/v1
     kind: NetworkPolicy
     metadata:
       name: deny-bookinfo
       namespace: default
     spec:
       podSelector:
         matchExpressions:
         - key: app
           operator: In
           values: ["productpage", "details", "reviews", "ratings"]
       policyTypes:
       - Ingress
       - Egress
     ```

  1. 將拒絕網路政策套用至您的叢集。

     ```
     kubectl apply -f network-policy-default-deny-bookinfo.yaml
     ```

  1. 測試對 BookInfo 應用程式的存取。在以下範例中，我們使用 productpage Pod (`10.86.2.193`) 的 Pod IP 位址來查詢微服務。將此取代為您環境中 productpage Pod 的 Pod IP 位址。

     ```
     curl http://10.86.2.193:9080/productpage --max-time 10
     ```

     ```
     curl: (28) Connection timed out after 10001 milliseconds
     ```

  1. 建立稱為 `network-policy-productpage.yaml` 的檔案，其中會定義 productpage 網路政策。政策具有下列規則：
     + 允許來自具有標籤 `access: true` 的 Pod 的輸入流量 (在上一個步驟中建立的 curl Pod)
     + 允許連接埠 `9080` 上的輸出 TCP 流量，以取得詳細資訊、檢閱和評分微服務
     + 允許在 `kube-system` 命名空間中執行的 CoreDNS 連接埠 `53` 上的輸出 TCP/UDP 流量

       ```
       apiVersion: networking.k8s.io/v1
       kind: NetworkPolicy
       metadata:
         name: productpage-policy
         namespace: default
       spec:
         podSelector:
           matchLabels:
             app: productpage
         policyTypes:
         - Ingress
         - Egress
         ingress:
         - from:
           - podSelector:
               matchLabels:
                 access: "true"
         egress:
         - to:
           - podSelector:
               matchExpressions:
               - key: app
                 operator: In
                 values: ["details", "reviews", "ratings"]
           ports:
           - port: 9080
             protocol: TCP
         - to:
           - namespaceSelector:
               matchLabels:
                 kubernetes.io/metadata.name: kube-system
             podSelector:
               matchLabels:
                 k8s-app: kube-dns
           ports:
           - port: 53
             protocol: UDP
           - port: 53
             protocol: TCP
       ```

  1. 將 productpage 網路政策套用至您的叢集。

     ```
     kubectl apply -f network-policy-productpage.yaml
     ```

  1. 連線至 curl Pod 並測試對 Bookinfo 應用程式的存取。現在允許存取 productpage 微服務，但其他微服務仍然被拒絕，因為它們仍須遵循拒絕網路政策。在以下範例中，我們使用 productpage Pod (`10.86.2.193`) 的 Pod IP 位址來查詢微服務。將此取代為您環境中 productpage Pod 的 Pod IP 位址。

     ```
     kubectl attach curl-pod -c curl-pod -i -t
     ```

     ```
     curl -s http://10.86.2.193:9080/productpage | grep -o "<title>.*</title>"
     <title>Simple Bookstore App</title>
     ```

     ```
     curl -s http://10.86.2.193:9080/api/v1/products/1
     {"error": "Sorry, product details are currently unavailable for this book."}
     ```

     ```
     curl -s http://10.86.2.193:9080/api/v1/products/1/reviews
     {"error": "Sorry, product reviews are currently unavailable for this book."}
     ```

     ```
     curl -s http://10.86.2.193:9080/api/v1/products/1/ratings
     {"error": "Sorry, product ratings are currently unavailable for this book."}
     ```

  1. 建立稱為 `network-policy-details.yaml` 的檔案，其中會定義詳細資訊網路政策。此政策僅允許來自 productpage 微服務的輸入流量。

     ```
     apiVersion: networking.k8s.io/v1
     kind: NetworkPolicy
     metadata:
       name: details-policy
       namespace: default
     spec:
       podSelector:
         matchLabels:
           app: details
       policyTypes:
       - Ingress
       ingress:
       - from:
         - podSelector:
             matchLabels:
               app: productpage
     ```

  1. 建立稱為 `network-policy-reviews.yaml` 的檔案，其中會定義檢閱網路政策。此政策僅允許來自 productpage 微服務輸入流量，且僅允許至評分微服務和 CoreDNS 的輸出流量。

     ```
     apiVersion: networking.k8s.io/v1
     kind: NetworkPolicy
     metadata:
       name: reviews-policy
       namespace: default
     spec:
       podSelector:
         matchLabels:
           app: reviews
       policyTypes:
       - Ingress
       - Egress
       ingress:
       - from:
         - podSelector:
             matchLabels:
               app: productpage
       egress:
       - to:
         - podSelector:
             matchLabels:
               app: ratings
       - to:
         - namespaceSelector:
             matchLabels:
               kubernetes.io/metadata.name: kube-system
           podSelector:
             matchLabels:
               k8s-app: kube-dns
         ports:
         - port: 53
           protocol: UDP
         - port: 53
           protocol: TCP
     ```

  1. 建立稱為 `network-policy-ratings.yaml` 的檔案，其中會定義評分網路政策。此政策僅允許來自檢閱微服務的輸入流量。

     ```
     apiVersion: networking.k8s.io/v1
     kind: NetworkPolicy
     metadata:
       name: ratings-policy
       namespace: default
     spec:
       podSelector:
         matchLabels:
           app: ratings
       policyTypes:
       - Ingress
       ingress:
       - from:
         - podSelector:
             matchExpressions:
             - key: app
               operator: In
               values: ["productpage", "reviews"]
     ```

  1. 將詳細資訊、檢閱和評分網路政策套用至您的叢集。

     ```
     kubectl apply -f network-policy-details.yaml
     kubectl apply -f network-policy-reviews.yaml
     kubectl apply -f network-policy-ratings.yaml
     ```

  1. 連線至 curl Pod 並測試對 Bookinfo 應用程式的存取。在以下範例中，我們使用 productpage Pod (`10.86.2.193`) 的 Pod IP 位址來查詢微服務。將此取代為您環境中 productpage Pod 的 Pod IP 位址。

     ```
     kubectl attach curl-pod -c curl-pod -i -t
     ```

     測試詳細資訊微服務。

     ```
     curl -s http://10.86.2.193:9080/api/v1/products/1
     ```

     ```
     {"id": 1, "author": "William Shakespeare", "year": 1595, "type": "paperback", "pages": 200, "publisher": "PublisherA", "language": "English", "ISBN-10": "1234567890", "ISBN-13": "123-1234567890"}
     ```

     測試檢閱微服務。

     ```
     curl -s http://10.86.2.193:9080/api/v1/products/1/reviews
     ```

     ```
     {"id": "1", "podname": "reviews-v1-598b896c9d-p2289", "clustername": "null", "reviews": [{"reviewer": "Reviewer1", "text": "An extremely entertaining play by Shakespeare. The slapstick humour is refreshing!"}, {"reviewer": "Reviewer2", "text": "Absolutely fun and entertaining. The play lacks thematic depth when compared to other plays by Shakespeare."}]}
     ```

     測試評分微服務。

     ```
     curl -s http://10.86.2.193:9080/api/v1/products/1/ratings
     ```

     ```
     {"id": 1, "ratings": {"Reviewer1": 5, "Reviewer2": 4}}
     ```

  1. 清除您在本程序中建立的資源。

     ```
     kubectl delete -f network-policy-deny-bookinfo.yaml
     kubectl delete -f network-policy-productpage.yaml
     kubectl delete -f network-policy-details.yaml
     kubectl delete -f network-policy-reviews.yaml
     kubectl delete -f network-policy-ratings.yaml
     kubectl delete -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/bookinfo/platform/kube/bookinfo.yaml
     kubectl delete pod curl-pod
     ```

# 混合節點的概念
<a name="hybrid-nodes-concepts"></a>

使用 *Amazon EKS 混合節點*，您可以將內部部署或邊緣環境中執行的實體或虛擬機器加入 AWS 雲端中執行的 Amazon EKS 叢集。這種方法可帶來許多好處，但同時也會為熟悉在單一網路環境中執行 Kubernetes 叢集的使用者引進新的聯網概念和架構。

以下章節將深入探討 EKS 混合節點的 Kubernetes 和聯網概念，並詳細說明流量如何流經混合式架構。這些章節會要求您熟悉基本的 Kubernetes 網路知識，例如 Pod、節點、服務、Kubernetes 控制平面、kubelet 和 kube-proxy 的概念。

我們建議您按照順序閱讀這些頁面，即從 [混合節點的聯網概念](hybrid-nodes-concepts-networking.md) 開始，接著是 [混合節點的 Kubernetes 概念](hybrid-nodes-concepts-kubernetes.md)，最後是 [混合節點的網路流量流程](hybrid-nodes-concepts-traffic-flows.md)。

**Topics**
+ [混合節點的聯網概念](hybrid-nodes-concepts-networking.md)
+ [混合節點的 Kubernetes 概念](hybrid-nodes-concepts-kubernetes.md)
+ [混合節點的網路流量流程](hybrid-nodes-concepts-traffic-flows.md)

# 混合節點的聯網概念
<a name="hybrid-nodes-concepts-networking"></a>

本節詳細說明設計 EKS 混合節點的網路拓撲時，必須考量的核心聯網概念和限制條件。

## EKS 混合節點的聯網概念
<a name="_networking_concepts_for_eks_hybrid_nodes"></a>

![\[高階混合節點網路圖\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-highlevel-network.png)


 **VPC 作為網路集線器** 

所有跨雲端邊界路由的流量都會通過您的 VPC。這包括在 中執行的 EKS 控制平面或 Pod AWS 與在其上執行的混合節點或 Pod 之間的流量。您可以將叢集的 VPC 視為混合節點與叢集其餘部分之間的網路集線器。此架構可讓您完全控制流量及其路由，但也可要求您須負責正確設定 VPC 的路由、安全群組和防火牆。

 **EKS 控制平面到 VPC** 

EKS 控制平面會將**彈性網路介面 (ENI)** 連接至您的 VPC。這些 ENI 會處理進出 EKS API 伺服器的流量。您可以在設定叢集時控制 EKS 控制平面 ENI 的置放，因為 EKS 會將 ENI 連接到您在叢集建立期間傳遞的子網路。

EKS 會將安全群組與 EKS 連接到子網路的 ENI 建立關聯。這些安全群組允許流量透過 ENI 進出 EKS 控制平面。這對 EKS 混合節點很重要，因為您必須允許流量從混合節點和在其上執行的 Pod 進入 EKS 控制平面 ENI。

 **遠端節點網路** 

遠端節點網路，特別是遠端節點 CIDR，是指派給您用作混合節點的機器的 IP 範圍。當您佈建混合節點時，它們位於您的內部部署資料中心或邊緣節點，這是與 EKS 控制平面和 VPC 不同的網路網域。每個混合節點都有來自遠端節點 CIDR 的 IP 位址或地址，而該 CIDR 與您 VPC 中的子網路不同。

您可以使用這些遠端節點 CIDR 設定 EKS 叢集，以便 EKS 知道透過叢集 VPC 路由所有以混合節點 IP 為目標的流量，例如請求到 kubelet API。API 的連線`kubelet`用於 `kubectl attach`、`kubectl cp`、`kubectl logs`、 `kubectl exec`和 `kubectl port-forward`命令。

 **遠端 Pod 網路** 

遠端 Pod 網路是指派給在混合節點上執行的 Pod 的 IP 範圍。一般而言，您可以使用這些範圍設定 CNI，而 CNI 的 IP 位址管理 (IPAM) 功能會負責將這些範圍的配量指派給每個混合節點。當您建立 Pod 時，CNI 會從配置給已排程 Pod 的節點的配量，將 IP 指派給 Pod。

您可以使用這些遠端 Pod CIDR 設定 EKS 叢集，因此 EKS 控制平面知道透過叢集的 VPC 路由所有以混合節點上執行的 Pod 為目標的流量，例如與 Webhook 的通訊。

![\[遠端 Pod 網路\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-remote-pod-cidrs.png)


 **內部部署到 VPC** 

您用於混合節點的內部部署網路必須路由到您用於 EKS 叢集的 VPC。若要將內部部署網路連接到 VPC，有數個[網路到 Amazon VPC 連線選項](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/network-to-amazon-vpc-connectivity-options.html)可用。您也可以使用自己的 VPN 解決方案。

請務必在 VPC 和內部部署網路的 AWS 雲端端正確設定路由，以便兩個網路透過兩個網路的連線路由正確的流量。

在 VPC 中，所有流向遠端節點和遠端 Pod 網路的流量都必須透過連線路由至內部部署網路 (稱為「閘道」)。如果您的部分子網路具有不同的路由表，則您必須使用混合節點的路由和在其上執行的 Pod 來設定每個路由表。對於連接 EKS 控制平面 ENI 的子網路，以及包含必須與混合節點通訊的 EC2 節點或 Pod 的子網路而言，都是如此。

在內部部署網路中，您必須設定網路，以允許進出 EKS 叢集 VPC 的流量，以及混合節點 AWS 所需的其他服務。EKS 叢集的流量可雙向周遊閘道。

## 聯網限制條件
<a name="_networking_constraints"></a>

 **完全路由的網路** 

主要限制條件是 EKS 控制平面和所有節點 (雲端或混合節點) 需要形成一個**完全路由的**網路。這表示所有節點都必須能夠透過 IP 位址在第三層彼此連接。

由於 EKS 控制平面和雲端節點位於平面網路 (VPC) 中，因此它們可以彼此連接。不過，混合節點會位於不同的網路網域中。因此，您需要在 VPC 和內部部署網路中設定額外的路由，以在混合節點和叢集的其餘部分之間路由流量。如果混合節點可從彼此和 VPC 連接，則您的混合節點可以位於單一平面網路或多個分段網路中。

 **可路由的遠端 Pod CIDR** 

若要讓 EKS 控制平面與在混合節點 (例如 Webhook 或指標伺服器) 上執行的 Pod 通訊，或讓在雲端節點上執行的 Pod 與在混合節點上執行的 Pod 通訊 (工作負載東西通訊)，您的遠端 Pod CIDR 必須可從 VPC 路由。這表示 VPC 必須能夠透過閘道將流量路由至內部部署網路的 Pod CIDR，並且您的內部部署網路必須能夠將 Pod 的流量路由至正確的節點。

請務必注意 VPC 和內部部署中 Pod 路由要求之間的差異。VPC 只需要知道任何流向遠端 Pod 的流量均應通過閘道。如果您只有一個遠端 Pod CIDR，則僅需一個路由。

此要求適用於您內部部署網路中的所有躍點，直到與您的混合節點位於相同子網路的本機路由器為止。這是唯一需要了解指派給每個節點的 Pod CIDR 配量的路由器，從而確保特定 Pod 的流量會交付至已排程 Pod 的節點。

您可以選擇將這些內部部署 Pod CIDR 的路由從本機內部部署路由器傳播到 VPC 路由表，但這並非必要。如果您的內部部署 Pod CIDR 經常變更，且您的 VPC 路由表需要更新以反映不斷變化的 Pod CIDR，我們建議您將內部部署 Pod CIDR 傳播至 VPC 路由表，不過這並不常見。

請注意，將內部部署 Pod CIDR 設為可路由的限制條件為選用項。如果您不需要在混合節點上執行 Webhook，或讓雲端節點上的 Pod 與混合節點上的 Pod 通訊，則您無需為內部部署網路上的 Pod CIDR 設定路由。

 *為什麼內部部署 Pod CIDR 需要使用混合節點進行路由？* 

將 EKS 與雲端節點的 VPC CNI 搭配使用時，VPC CNI 會將 IP 直接從 VPC 指派給 Pod。這表示不需要任何特殊路由，因為雲端 Pod 和 EKS 控制平面都可以直接連接 Pod IP。

當在內部部署執行 (以及與雲端中的其他 CNI 一起執行) 時，Pod 通常會在隔離的覆蓋網路中執行，而 CNI 則負責在 Pod 之間交付流量。這通常透過封裝來完成：CNI 會將 pod 至 pod 流量轉換為節點至節點流量，並負責兩端的封裝和解封裝。如此一來，就節點和路由器上就不需要額外的組態。

與混合節點的聯網是唯一的，因為它會提供兩種拓撲的組合：EKS 控制平面和雲端節點 (使用 VPC CNI) 預期包括節點和 Pod 的平坦網路，而混合節點上執行的 Pod 則位於覆蓋網路 (預設位於 Cilium)中，可透過使用 VXLAN 進行封裝。在混合節點上執行的 Pod 可以連接在雲端節點上執行的 EKS 控制平面和 Pod，前提是內部部署網路可路由到 VPC。不過，如果沒有內部部署網路上的 Pod CIDR 的路由，而且網路不知道如何連接至覆蓋網路以及路由到正確的節點，則最終會捨棄任何返回內部部署 Pod IP 的流量。

# 混合節點的 Kubernetes 概念
<a name="hybrid-nodes-concepts-kubernetes"></a>

此頁面詳細說明支援 EKS 混合節點系統架構的重要 Kubernetes 概念。

## VPC 中的 EKS 控制平面
<a name="hybrid-nodes-concepts-k8s-api"></a>

EKS 控制平面 ENI 的 IP 會存放在 `default` 命名空間的 `kubernetes` `Endpoints` 物件中。當 EKS 建立新的 ENI 或移除較舊的 ENI 時，EKS 會更新此物件，以便 IP 清單永遠是保持最新。

您可以透過 `kubernetes` 服務使用這些端點，也可以在 `default` 命名空間中使用這些端點。此服務為 `ClusterIP` 類型，且一律會獲指派叢集服務 CIDR 的第一個 IP。例如，對於服務 CIDR `172.16.0.0/16`，服務 IP 將為 `172.16.0.1`。

一般而言，這就是 Pod (無論是在雲端還是在混合節點中執行) 存取 EKS Kubernetes API 伺服器的方式。Pod 使用服務 IP 最為目的地 IP，且其會轉譯為其中一個 EKS 控制平面 ENI 的實際 IP。主要例外狀況是 `kube-proxy`，因為它會設定轉譯。

## EKS API 伺服器端點
<a name="hybrid-nodes-concepts-k8s-eks-api"></a>

`kubernetes` 服務 IP 並非存取 EKS API 伺服器的唯一方式。當您建立叢集時，EKS 也會建立一個 Route53 DNS 名稱。這是呼叫 EKS `DescribeCluster` API 動作時 EKS 叢集的 `endpoint` 欄位。

```
{
    "cluster": {
        "endpoint": "https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.gr7.us-west-2.eks.amazonaws.com",
        "name": "my-cluster",
        "status": "ACTIVE"
    }
}
```

在公有端點存取或公有和私有端點存取叢集中，根據預設，您的混合節點會將此 DNS 名稱解析為公有 IP，且可透過網際網路路由。在私有端點存取叢集中，DNS 名稱會解析為 EKS 控制平面 ENI 的私有 IP。

這是 `kubelet` 和 `kube-proxy` 存取 Kubernetes API 伺服器的方式。如果您希望所有 Kubernetes 叢集流量流經 VPC，您需要以私有存取模式設定叢集，或修改內部部署 DNS 伺服器，以將 EKS 叢集端點解析為 EKS 控制平面 ENI 的私有 IP。

## `kubelet` 端點
<a name="hybrid-nodes-concepts-k8s-kubelet-api"></a>

`kubelet` 會公開數個 REST 端點，從而允許系統的其他部分與每個節點互動並收集資訊。在大多數叢集中，前往 `kubelet` 伺服器的大多數流量都來自控制平面，但某些監控代理程式也可能會與其互動。

透過此介面，`kubelet` 會處理各種請求：擷取日誌 (`kubectl logs`)、在容器內執行命令 (`kubectl exec`) 以及連接埠轉送流量 (`kubectl port-forward`)。其中每個請求皆會透過 `kubelet` 與基礎容器執行時期互動，而對叢集管理員和開發人員來說，這似乎是無縫的。

此 API 最常見的取用者是 Kubernetes API 伺服器。當您使用上述任何 `kubectl` 命令時，`kubectl` 會向 API 伺服器發出 API 請求，然後呼叫執行 Pod 的節點的 `kubelet` API。這就是需要從 EKS 控制平面連接至節點 IP，以及即使您的 Pod 正在執行，如果節點路由設定錯誤，您也無法存取其日誌或 `exec` 的主要原因。

 **節點 IP** 

當 EKS 控制平面與節點通訊時，其會使用以 `Node` 物件狀態 (`status.addresses`) 回報的其中一個地址。

使用 EKS 雲端節點時，kubelet 通常會在節點註冊期間將 EC2 執行個體的私有 IP 報告為 `InternalIP`。然後，雲端控制器管理員 (CCM) 會驗證此 IP，進而確保其屬於 EC2 執行個體。此外，CCM 通常會將執行個體的公有 IP (例如 `ExternalIP`) 和 DNS 名稱 (`InternalDNS` 和 `ExternalDNS`) 新增至節點狀態。

不過，混合節點沒有 CCM。當您向 EKS 混合節點 CLI (`nodeadm`) 註冊混合節點時，它會將 kubelet 設定為在節點狀態中直接報告機器的 IP，且不需要 CCM。

```
apiVersion: v1
kind: Node
metadata:
  name: my-node-1
spec:
  providerID: eks-hybrid:///us-west-2/my-cluster/my-node-1
status:
  addresses:
  - address: 10.1.1.236
    type: InternalIP
  - address: my-node-1
    type: Hostname
```

如果您的機器具有多個 IP，則 kubelet 會依照其自己的邏輯選取其中一個 IP。您可以使用 `--node-ip` 旗標來控制選取的 IP，而您可以在 `spec.kubelet.flags` 中的 `nodeadm` 組態內傳遞該旗標。只有 `Node` 物件中報告的 IP 需要來自 VPC 的路由。您的機器可能擁有無法從雲端連線的其他 IP。

## `kube-proxy`
<a name="hybrid-nodes-concepts-k8s-kube-proxy"></a>

 `kube-proxy` 負責在每個節點的網路層實作服務抽象。它可作為通往 Kubernetes Services 的流量的網路代理和負載平衡器。透過持續監看 Kubernetes API 伺服器中是否存在與服務和端點相關的變更，`kube-proxy` 會動態更新基礎主機的聯網規則，進而確保流量導向正確無誤。

在 `iptables` 模式中，`kube-proxy` 會設定數個 `netfilter` 鏈結來處理服務流量。這些規則可組成下列階層：

1.  **KUBE-SERVICES 鏈結**：所有服務流量的進入點。它具有與每個服務的 `ClusterIP` 和連接埠相符的規則。

1.  **KUBE-SVC-XXX 鏈結**：服務特定鏈結針對每個服務都設有負載平衡規則。

1.  **KUBE-SEP-XXX 鏈結**：端點特定鏈結設有實際 `DNAT` 規則。

讓我們檢查 `default` 命名空間中服務 `test-server` 的情況：\$1 服務 ClusterIP：`172.16.31.14` \$1 服務連接埠：`80` \$1 支援 Pod：`10.2.0.110`、`10.2.1.39` 和 `10.2.2.254` 

當我們檢查 `iptables` 規則時 (使用 `iptables-save 0 grep -A10 KUBE-SERVICES`)：

1. 在 **KUBE-SERVICES** 鏈結中，我們可找到與服務相符的規則：

   ```
   -A KUBE-SERVICES -d 172.16.31.14/32 -p tcp -m comment --comment "default/test-server cluster IP" -m tcp --dport 80 -j KUBE-SVC-XYZABC123456
   ```
   + 此規則與目的地為 172.16.31.14:80 的封包相符
   + 該註解指出此規則的用途：`default/test-server cluster IP`
   + 相符的封包會跳至 `KUBE-SVC-XYZABC123456` 鏈結

1. **KUBE-SVC-XYZABC123456** 鏈結設有機率型負載平衡規則：

   ```
   -A KUBE-SVC-XYZABC123456 -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-POD1XYZABC
   -A KUBE-SVC-XYZABC123456 -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-POD2XYZABC
   -A KUBE-SVC-XYZABC123456 -j KUBE-SEP-POD3XYZABC
   ```
   + 第一項規則：33.3% 的機會跳至 `KUBE-SEP-POD1XYZABC` 
   + 第二項規則：50% 的剩餘流量 (總計的 33.3%) 會跳至 `KUBE-SEP-POD2XYZABC` 
   + 最後一項規則：所有剩餘的流量 (總計的 33.3%) 會跳至 `KUBE-SEP-POD3XYZABC` 

1. 個別 **KUBE-SEP-XXX** 鏈結會執行 DNAT (目的地 NAT)：

   ```
   -A KUBE-SEP-POD1XYZABC -p tcp -m tcp -j DNAT --to-destination 10.2.0.110:80
   -A KUBE-SEP-POD2XYZABC -p tcp -m tcp -j DNAT --to-destination 10.2.1.39:80
   -A KUBE-SEP-POD3XYZABC -p tcp -m tcp -j DNAT --to-destination 10.2.2.254:80
   ```
   + 這些 DNAT 規則會重寫目的地 IP 和連接埠，以將流量導向特定的 Pod。
   + 每項規則可處理大約 33.3% 的流量，以便在 `10.2.0.110`、`10.2.1.39` 和 `10.2.2.254` 之間提供均勻的負載平衡。

此多層級鏈結結構讓 `kube-proxy` 能夠透過核心層級封包操作高效實作服務負載平衡和重新導向，而不需要資料路徑中的代理。

### 對 Kubernetes 操作的影響
<a name="hybrid-nodes-concepts-k8s-operations"></a>

節點上中斷的 `kube-proxy` 可防止該節點正常路由服務流量，進而導致依賴叢集服務的 Pod 逾時或連線失敗。首次註冊節點時，這尤其會造成干擾。在設定任何 Pod 聯網之前，CNI 需要與 Kubernetes API 伺服器通訊以取得資訊，例如節點的 Pod CIDR。為此，它會使用 `kubernetes` 服務 IP。不過，如果 `kube-proxy` 無法啟動或無法設定正確的 `iptables` 規則，則傳送至 `kubernetes` 服務 IP 的請求不會轉譯為 EKS 控制平面 ENI 的實際 IP。因此，CNI 將進入損毀循環，而且任何 Pod 都無法正常執行。

我們知道 Pod 會使用 `kubernetes` 服務 IP 與 Kubernetes API 伺服器通訊，但 `kube-proxy` 需要先設定 `iptables` 規則才能讓其運作。

`kube-proxy` 如何與 API 伺服器通訊？

必須將 `kube-proxy` 設定為使用 Kubernetes API 伺服器的實際 IP 或解析為它們的 DNS 名稱。若為 EKS，則 EKS 會將預設的 `kube-proxy` 設定為指向 EKS 在您建立叢集時建立的 Route53 DNS 名稱。您可以在 `kube-system` 命名空間的 `kube-proxy` ConfigMap 中看到此值。此 ConfigMap 的內容是注入 `kube-proxy` Pod 中的 `kubeconfig`，因此請尋找 `clusters0.cluster.server` 欄位。此值將與您 EKS 叢集的 `endpoint` 欄位相符 (呼叫 EKS `DescribeCluster` API 時)。

```
apiVersion: v1
data:
  kubeconfig: |-
    kind: Config
    apiVersion: v1
    clusters:
    - cluster:
        certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        server: https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.gr7.us-west-2.eks.amazonaws.com
      name: default
    contexts:
    - context:
        cluster: default
        namespace: default
        user: default
      name: default
    current-context: default
    users:
    - name: default
      user:
        tokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
kind: ConfigMap
metadata:
  name: kube-proxy
  namespace: kube-system
```

## 可路由的遠端 Pod CIDR
<a name="hybrid-nodes-concepts-k8s-pod-cidrs"></a>

此 [混合節點的聯網概念](hybrid-nodes-concepts-networking.md) 頁面會詳細說明在混合節點上執行 Webhook 或讓在雲端節點上執行的 Pod 與在混合節點上執行的 Pod 進行通訊的需求。關鍵要求是，內部部署路由器需要知道哪個節點負責特定的 Pod IP。有幾種方法可以實現這一點，包括邊界閘道協定 (BGP)、靜態路由和位址解析通訊協定 (ARP) 代理。詳細方法請參閱下列各節。

 **邊界閘道協定 (BGP)** 

如果您的 CNI 對其提供支援 (例如 Cilium 和 Calico)，您可以使用 CNI 的 BGP 模式，以將路由傳播到每個節點的 Pod CIDR (從節點到本機路由器)。使用 CNI 的 BGP 模式時，您的 CNI 可作為虛擬路由器，因此您的本機路由器會認為 Pod CIDR 屬於不同的子網路，而您的節點是該子網路的閘道。

![\[混合節點 BGP 路由\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-bgp.png)


 **靜態路由** 

或者，您可以在本機路由器中設定靜態路由。這是將內部部署 Pod CIDR 路由至 VPC 的最簡單方法，但這也是最容易出錯且難以維護的方法。您需要確保路由始終與現有節點及其指派的 Pod CIDR 保持同步。如果您的節點數量很小且基礎結構為靜態，則此方案可行，並且不需要路由器中的 BGP 支援。如果您選擇此方案，那麼建議您使用要指派給每個節點的 Pod CIDR 配量來設定 CNI，而不是讓其 IPAM 決定。

![\[混合節點靜態路由\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-static-routes.png)


 **位址解析通訊協定 (ARP) 代理** 

ARP 代理是讓內部部署 Pod IP 可路由的另一種方法，並且當您的混合節點與本機路由器位於相同的第 2 層網路上時，特別有用。啟用 ARP 代理後，節點會回應其託管的 Pod IP 的 ARP 請求，即使這些 IP 屬於不同的子網路。

當您本機網路上的裝置嘗試連接 Pod IP 時，會先傳送 ARP 請求，並詢問「誰有此 IP？」。託管該 Pod 的混合節點將以其自己的 MAC 位址回應，表示「我可以處理該 IP 的流量」。這會在本機網路上的裝置與 Pod 之間建立一條直接路徑，而無需路由器組態。

若要使其運作，您的 CNI 必須支援代理 ARP 功能。Cilium 內建對代理 ARP 的支援，並且您可以透過組態將其啟用。關鍵考量是，Pod CIDR 不得與您環境中的任何其他網路重疊，因為這可能會導致路由衝突。

此方法有多個優點：\$1 無需使用 BGP 設定路由器或維護靜態路由 \$1 適用於您無法控制路由器組態的環境

![\[混合節點 ARP 代理\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-arp-proxy.png)


## Pod 至 Pod 封裝
<a name="hybrid-nodes-concepts-k8s-pod-encapsulation"></a>

在內部部署環境中，CNI 通常會使用封裝通訊協定來建立可在實體網路上運行的覆蓋網路，而無需重新設定。本節說明此封裝如何運作。請注意，某些詳細資訊可能會因您使用的 CNI 而有所不同。

封裝會將原始 Pod 網路封包包裝在另一個可透過基礎實體網路路由的網路封包內。這可讓 Pod 跨執行相同 CNI 的節點進行通訊，而不需要實體網路知道如何路由這些 Pod CIDR。

與 Kubernetes 搭配使用的最常見封裝通訊協定是虛擬局域網擴展 (VXLAN)，但視您的 CNI 而定，也可使用其他通訊協定 (例如 `Geneve`)。

### VXLAN 封裝
<a name="_vxlan_encapsulation"></a>

VXLAN 將第 2 層乙太網路訊框封裝在 UDP 封包內。當 Pod 將流量傳送至不同節點上的另一個 Pod 時，CNI 會執行下列動作：

1. CNI 攔截來自 Pod A 的封包

1. CNI 將原始封包包裝在 VXLAN 標頭中

1. 然後，此已包裝的封包會透過節點的一般網路堆疊傳送至目的地節點

1. 目的地節點上的 CNI 會取消包裝封包並將其交付至 Pod B

以下是 VXLAN 封裝期間封包結構的相關情況：

原始 Pod 至 Pod 封包：

```
+-----------------+---------------+-------------+-----------------+
| Ethernet Header | IP Header     | TCP/UDP     | Payload         |
| Src: Pod A MAC  | Src: Pod A IP | Src Port    |                 |
| Dst: Pod B MAC  | Dst: Pod B IP | Dst Port    |                 |
+-----------------+---------------+-------------+-----------------+
```

VXLAN 封裝後：

```
+-----------------+-------------+--------------+------------+---------------------------+
| Outer Ethernet  | Outer IP    | Outer UDP    | VXLAN      | Original Pod-to-Pod       |
| Src: Node A MAC | Src: Node A | Src: Random  | VNI: xx    | Packet (unchanged         |
| Dst: Node B MAC | Dst: Node B | Dst: 4789    |            | from above)               |
+-----------------+-------------+--------------+------------+---------------------------+
```

VXLAN 網路識別符 (VNI) 可區分不同的覆蓋網路。

### Pod 通訊案例
<a name="_pod_communication_scenarios"></a>

 **相同混合節點上的 Pod** 

當相同混合節點上的 Pod 彼此通訊時，通常不需要封裝。CNI 會設定本機路由，而該路由可透過節點的內部虛擬介面來引導 Pod 之間的流量：

```
Pod A -> veth0 -> node's bridge/routing table -> veth1 -> Pod B
```

封包永遠不會離開節點，並且也不需要封裝。

 **不同混合節點上的 Pod** 

不同混合節點上的 Pod 之間的通訊需要封裝：

```
Pod A -> CNI -> [VXLAN encapsulation] -> Node A network -> router or gateway -> Node B network -> [VXLAN decapsulation] -> CNI -> Pod B
```

這可讓 Pod 流量周遊實體網路基礎結構，而無需實體網路來了解 Pod IP 路由。

# 混合節點的網路流量流程
<a name="hybrid-nodes-concepts-traffic-flows"></a>

此頁面詳細說明 EKS 混合節點的網路流量流程，其中各圖表會顯示不同流量類型的端到端網路路徑。

涵蓋下列流量流程：
+  [混合節點 `kubelet` 到 EKS 控制平面](#hybrid-nodes-concepts-traffic-flows-kubelet-to-cp) 
+  [EKS 控制平面到混合節點 (`kubelet` 伺服器)](#hybrid-nodes-concepts-traffic-flows-cp-to-kubelet) 
+  [在混合節點上執行的 Pod 到 EKS 控制平面](#hybrid-nodes-concepts-traffic-flows-pods-to-cp) 
+  [EKS 控制平面到混合節點上執行的 Pod (Webhook)](#hybrid-nodes-concepts-traffic-flows-cp-to-pod) 
+  [在混合節點上執行的 Pod 到 Pod](#hybrid-nodes-concepts-traffic-flows-pod-to-pod) 
+  [雲端節點上的 Pod 到混合節點上的 Pod (東西流量)](#hybrid-nodes-concepts-traffic-flows-east-west) 

## 混合節點 `kubelet` 到 EKS 控制平面
<a name="hybrid-nodes-concepts-traffic-flows-kubelet-to-cp"></a>

![\[混合節點 kubelet 到 EKS 控制平面\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-kubelet-to-cp-public.png)


### 請求
<a name="_request"></a>

 **1`kubelet`. 啟動請求** 

當混合節點上的 `kubelet` 需要與 EKS 控制平面進行通訊時 (例如，報告節點狀態或取得 Pod 規格)，它會使用節點註冊期間提供的 `kubeconfig` 檔案。該 `kubeconfig` 具有 API 伺服器端點 URL (Route53 DNS 名稱)，而不是直接 IP 位址。

`kubelet` 會執行端點的 DNS 查詢 (例如，`https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.gr7.us-west-2.eks.amazonaws.com`)。在公有存取叢集中，這會解析為屬於在 AWS中執行的 EKS 服務的公有 IP 位址 (例如 `54.239.118.52`)。然後，`kubelet` 會為此端點建立安全的 HTTPS 請求。初始封包如下所示：

```
+--------------------+---------------------+-----------------+
| IP Header          | TCP Header          | Payload         |
| Src: 10.80.0.2     | Src: 52390 (random) |                 |
| Dst: 54.239.118.52 | Dst: 443            |                 |
+--------------------+---------------------+-----------------+
```

 **2. 本機路由器路由** 

由於目的地 IP 是公有 IP 位址並且不屬於本機網路，因此 `kubelet` 會將此封包傳送至其預設閘道 (本機內部部署路由器)。路由器會檢查目的地 IP，並判定其是否為公有 IP 位址。

對於公有流量，路由器通常會將封包轉送至網際網路閘道或邊界路由器，而它們可處理向網際網路的傳出流量。此內容未在圖表中顯示，且具體取決於內部部署網路的設定方式。封包會在您的內部部署網路基礎結構上傳輸，最終連接網際網路服務提供商的網路。

 **3. 交付至 EKS 控制平面** 

封包會通過公有網際網路和傳輸網路，直到到達 AWS網路。 AWS的網路會將封包路由到適當區域中的 EKS 服務端點。當該封包連接 EKS 服務時，它會轉送到叢集的實際 EKS 控制平面。

透過公有網際網路的路由不同於我們在其他流量流程中看到的私有 VPC 路由路徑。主要差異在於，使用公有存取模式時，從內部部署 `kubelet` (儘管並非從 Pod) 到 EKS 控制平面的流量不會經過您的 VPC，而是會使用全球網際網路基礎結構。

### 回應
<a name="_response"></a>

在 EKS 控制平面處理 `kubelet` 請求後，它會傳送回應：

 **3. EKS 控制平面傳送回應** 

EKS 控制平面會建立回應封包。此封包將公有 IP 作為來源，並將混合節點的 IP 作為目的地：

```
+--------------------+---------------------+-----------------+
| IP Header          | TCP Header          | Payload         |
| Src: 54.239.118.52 | Src: 443            |                 |
| Dst: 10.80.0.2     | Dst: 52390          |                 |
+--------------------+---------------------+-----------------+
```

 **2. 網際網路路由** 

回應封包會透過網際網路傳回，並遵循網際網路服務提供商確定的路由路徑，直到連接您的內部部署網路邊緣路由器為止。

 **1。本機交付** 

您的內部部署路由器會接收封包，並將目的地 IP (`10.80.0.2`) 識別為屬於您的本機網路。它會透過您的本機網路基礎結構轉送封包，直到它連接目標混合節點為止，其中 `kubelet` 會接收和處理回應。

## 混合節點 `kube-proxy` 到 EKS 控制平面
<a name="_hybrid_node_kube_proxy_to_eks_control_plane"></a>

如果您啟用叢集的公有端點存取，則傳回流量會使用公有網際網路。此流量源自混合節點上的 `kube-proxy` 且通往 EKS 控制平面，因此須遵循與從 `kubelet` 到 EKS 控制平面的流量相同的路徑。

## EKS 控制平面到混合節點 (`kubelet` 伺服器)
<a name="hybrid-nodes-concepts-traffic-flows-cp-to-kubelet"></a>

![\[EKS 控制平面到混合節點\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-cp-to-kubelet.png)


### 請求
<a name="_request_2"></a>

 **1。EKS Kubernetes API 伺服器啟動請求** 

EKS Kubernetes API 伺服器會從節點物件的狀態擷取節點的 IP 位址 (`10.80.0.2`)。然後，它會透過 VPC 中的 ENI 路由此請求，因為目的地 IP 屬於已設定的遠端節點 CIDR (`10.80.0.0/16`)。初始封包如下所示：

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 10.0.0.132 | Src: 67493 (random) |                 |
| Dst: 10.80.0.2  | Dst: 10250          |                 |
+-----------------+---------------------+-----------------+
```

 **2. VPC 網路處理** 

該封包會離開 ENI 並進入 VPC 網路層，而其會導向子網路的閘道，以便進行進一步路由。

 **3. VPC 路由表查詢** 

包含 EKS 控制平面 ENI 的子網路的 VPC 路由表具有適用於遠端節點 CIDR 的特定路由 (圖表中的第二個路由)。根據此路由規則，該封包會導向至 VPC-to-onprem 閘道。

 **4. 跨邊界傳輸** 

閘道會透過您已建立的連線 (例如 Direct Connect 或 VPN)，將封包跨雲端邊界傳輸到您的內部部署網路。

 **5. 內部部署網路接收** 

該封包會抵達本機內部部署路由器，以處理混合節點所在的子網路的流量。

 **6. 最終交付** 

本機路由器會識別目的地 IP (`10.80.0.2`) 位址屬於其直接連接的網路，並將封包直接轉送至目標混合節點，而 `kubelet` 會在其中接收和處理請求。

### 回應
<a name="_response_2"></a>

在混合節點的 `kubelet` 處理請求後，它會遵循相同路徑反向傳回回應：

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 10.80.0.2  | Src: 10250          |                 |
| Dst: 10.0.0.132 | Dst: 67493          |                 |
+-----------------+---------------------+-----------------+
```

 **6. `kubelet` 傳送回應** 

混合節點 (`10.80.0.2`) 上的 `kubelet` 會使用原始來源 IP 作為目的地來建立回應封包。該目的地不屬於本機網路，因此其會傳送到主機的預設閘道，也就是本機路由器。

 **5. 本機路由器路由** 

該路由器會判定目的地 IP (`10.0.0.132`) 屬於 `10.0.0.0/16`，並且其具有會指向連接到 AWS的閘道的路由。

 **4. 跨邊界傳回** 

該封包會傳回相同的內部部署至 VPC 連線 (例如 Direct Connect 或 VPN)，並以相反方向跨越雲端邊界。

 **3. VPC 路由** 

當該封包抵達 VPC 時，路由表會識別目的地 IP 屬於 VPC CIDR。該封包會在 VPC 內路由。

 **2. VPC 網路交付** 

VPC 網路層會使用 EKS 控制平面 ENI (`10.0.0.132`) 將封包轉送至子網路。

 **1。ENI 接收** 

該封包會到達連接到 Kubernetes API 伺服器的 EKS 控制平面 ENI，以便完成往返。

## 在混合節點上執行的 Pod 到 EKS 控制平面
<a name="hybrid-nodes-concepts-traffic-flows-pods-to-cp"></a>

![\[在混合節點上執行的 Pod 到 EKS 控制平面\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-pod-to-cp.png)


### 不使用 CNI NAT
<a name="_without_cni_nat"></a>

### 請求
<a name="_request_3"></a>

Pod 通常會透過 `kubernetes` 服務與 Kubernetes API 伺服器進行通訊。服務 IP 是叢集的服務 CIDR 的第一個 IP。此慣例允許需要在 CoreDNS 可用之前執行的 Pod，以便連接 API 伺服器，例如 CNI。請求以服務 IP 作為目的地離開 Pod。例如，如果服務 CIDR 為 `172.16.0.0/16`，則服務 IP 將為 `172.16.0.1`。

 **1。Pod 啟動請求** 

Pod 會從隨機來源連接埠傳送請求至 API 伺服器連接埠 (443) 上的 `kubernetes` 服務 IP (`172.16.0.1`)。封包如下所示：

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 10.85.1.56 | Src: 67493 (random) |                 |
| Dst: 172.16.0.1 | Dst: 443            |                 |
+-----------------+---------------------+-----------------+
```

 **2. CNI 處理** 

CNI 偵測到目的地 IP 不屬於其管理的任何 Pod CIDR。由於**傳出 NAT 已停用**，CNI 會將該封包傳遞至主機網路堆疊，而且不會進行修改。

 **3. 節點網路處理** 

該封包會進入節點的網路堆疊，其中 `netfilter` 勾點會觸發由 kube-proxy 設定的 `iptables` 規則。按下列順序依次適用數條規則：

1. 該封包會先命中 `KUBE-SERVICES` 鏈結，其中包含與每個服務的 ClusterIP 和連接埠相符的規則。

1. 該相符規則會跳至 `kubernetes` 服務的 `KUBE-SVC-XXX` 鏈結 (以 `172.16.0.1:443` 為目的地的封包)，其中包含負載平衡規則。

1. 該負載平衡規則會隨機選取控制平面 ENI IP (`10.0.0.132` 或 `10.0.1.23`) 的其中一個 `KUBE-SEP-XXX` 鏈結。

1. 選取的 `KUBE-SEP-XXX` 鏈結具有實際規則，可將目的地 IP 從服務 IP 變更為選取的 IP。這就是所謂的目的地網路位址轉譯 (DNAT)。

套用這些規則後，假設選取的 EKS 控制平面 ENI 的 IP 為 `10.0.0.132`，且封包會如下所示：

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 10.85.1.56 | Src: 67493 (random) |                 |
| Dst: 10.0.0.132 | Dst: 443            |                 |
+-----------------+---------------------+-----------------+
```

節點會將封包轉送至其預設閘道，因為目的地 IP 不在本機網路中。

 **4. 本機路由器路由** 

本機路由器會判定目的地 IP (`10.0.0.132`) 屬於 VPC CIDR (`10.0.0.0/16`)，並將其轉送至與 AWS連接的閘道。

 **5. 跨邊界傳輸** 

封包會透過您已建立的連線 (例如 Direct Connect 或 VPN) 跨雲端邊界傳輸到 VPC。

 **6. VPC 網路交付** 

VPC 網路層會將封包路由至 EKS 控制平面 ENI (`10.0.0.132`) 所在的正確子網路。

 **7. ENI 接收** 

該封包會到達連接到 Kubernetes API 伺服器的 EKS 控制平面 ENI。

### 回應
<a name="_response_3"></a>

在 EKS 控制平面處理請求後，它會傳送回應至 Pod：

 **7. API 伺服器傳送回應** 

EKS Kubernetes API 伺服器會使用原始來源 IP 作為目的地，進而建立回應封包。封包如下所示：

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 10.0.0.132 | Src: 443            |                 |
| Dst: 10.85.1.56 | Dst: 67493          |                 |
+-----------------+---------------------+-----------------+
```

由於目的地 IP 屬於已設定的遠端 Pod CIDR (`10.85.0.0/16`)，因此它會透過其在 VPC 中的 ENI 傳送，並將子網路的路由器作為下一個躍點。

 **6. VPC 路由** 

VPC 路由表包含遠端 Pod CIDR (`10.85.0.0/16`) 的項目，並且會將此流量導向 VPC-to-onprem 閘道。

 **5. 跨邊界傳輸** 

閘道會透過您已建立的連線 (例如 Direct Connect 或 VPN)，將封包跨雲端邊界傳輸到您的內部部署網路。

 **4. 內部部署網路接收** 

封包送達本機內部部署路由器。

 **3. 交付至節點** 

路由器的資料表有一個 `10.85.1.0/24` 的項目，其中 `10.80.0.2` 將作為下一個躍點，負責將封包交付至我們的節點。

 **2. 節點網路處理** 

當封包由節點的網路堆疊處理時，`conntrack` (`netfilter` 的一部分) 會將封包與 Pod 最初建立的連線進行比對。由於最初套用了 DNAT，`conntrack` 透過將來源 IP 從 EKS 控制平面 ENI 的 IP 重寫到 `kubernetes` 服務 IP，進而反轉 DNAT：

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 172.16.0.1 | Src: 443            |                 |
| Dst: 10.85.1.56 | Dst: 67493          |                 |
+-----------------+---------------------+-----------------+
```

 **1。CNI 處理** 

CNI 會識別目的地 IP 屬於其網路中的 Pod，並將封包交付至正確的 Pod 網路命名空間。

此流程展示為什麼遠端 Pod CIDR 必須能夠從 VPC 一直正確路由到託管每個 Pod 的特定節點，整個傳回路徑取決於跨雲端和內部部署網路的適當 Pod IP 路由。

### 使用 CNI NAT
<a name="_with_cni_nat"></a>

此流程與*不使用 CNI NAT* 的流程非常相似，但有一個重要差異：CNI 會先將來源 NAT (SNAT) 套用至封包，然後再將其傳送至節點的網路堆疊。這樣一來，即會將封包的來源 IP 變更為節點的 IP，從而允許封包路由回節點，而不需要額外的路由組態。

### 請求
<a name="_request_4"></a>

 **1。Pod 啟動請求** 

Pod 會從隨機來源連接埠傳送請求至 EKS Kubernetes API 伺服器連接埠 (443) 上的 `kubernetes` 服務 IP (`172.16.0.1`)。封包如下所示：

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 10.85.1.56 | Src: 67493 (random) |                 |
| Dst: 172.16.0.1 | Dst: 443            |                 |
+-----------------+---------------------+-----------------+
```

 **2. CNI 處理** 

CNI 偵測到目的地 IP 不屬於其管理的任何 Pod CIDR。由於**傳出 NAT 已啟用**，CNI 會將 SNAT 套用至封包，將來源 IP 變更為節點的 IP，然後再將其傳遞至節點的網路堆疊：

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 10.80.0.2  | Src: 67493 (random) |                 |
| Dst: 172.16.0.1 | Dst: 443            |                 |
+-----------------+---------------------+-----------------+
```

注意：為了清楚起見，在範例中，CNI 和 `iptables` 會顯示為獨立的區塊，但實際上，有些 CNI 可能會使用 `iptables` 來套用 NAT。

 **3. 節點網路處理** 

在這裡，由 `kube-proxy` 設定的 `iptables` 規則的行為與上一個範例中的行為相同，並且會將封包負載平衡到其中一個 EKS 控制平面 ENI。初始封包現如下所示：

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 10.80.0.2  | Src: 67493 (random) |                 |
| Dst: 10.0.0.132 | Dst: 443            |                 |
+-----------------+---------------------+-----------------+
```

節點會將封包轉送至其預設閘道，因為目的地 IP 不在本機網路中。

 **4. 本機路由器路由** 

本機路由器會判定目的地 IP (`10.0.0.132`) 屬於 VPC CIDR (`10.0.0.0/16`)，並將其轉送至與 AWS連接的閘道。

 **5. 跨邊界傳輸** 

封包會透過您已建立的連線 (例如 Direct Connect 或 VPN) 跨雲端邊界傳輸到 VPC。

 **6. VPC 網路交付** 

VPC 網路層會將封包路由至 EKS 控制平面 ENI (`10.0.0.132`) 所在的正確子網路。

 **7. ENI 接收** 

該封包會到達連接到 Kubernetes API 伺服器的 EKS 控制平面 ENI。

### 回應
<a name="_response_4"></a>

在 EKS 控制平面處理請求後，它會傳送回應至 Pod：

 **7. API 伺服器傳送回應** 

EKS Kubernetes API 伺服器會使用原始來源 IP 作為目的地，進而建立回應封包。封包如下所示：

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 10.0.0.132 | Src: 443            |                 |
| Dst: 10.80.0.2  | Dst: 67493          |                 |
+-----------------+---------------------+-----------------+
```

由於目的地 IP 屬於已設定的遠端節點 CIDR (`10.80.0.0/16`)，因此它會透過其在 VPC 中的 ENI 傳送，並將子網路的路由器作為下一個躍點。

 **6. VPC 路由** 

VPC 路由表包含遠端節點 CIDR (`10.80.0.0/16`) 的項目，並且會將此流量導向 VPC-to-onprem 閘道。

 **5. 跨邊界傳輸** 

閘道會透過您已建立的連線 (例如 Direct Connect 或 VPN)，將封包跨雲端邊界傳輸到您的內部部署網路。

 **4. 內部部署網路接收** 

封包送達本機內部部署路由器。

 **3. 交付至節點** 

本機路由器會識別目的地 IP (`10.80.0.2`) 位址屬於其直接連接的網路，並將封包直接轉送至目標混合節點。

 **2. 節點網路處理** 

當封包由節點的網路堆疊處理時，`conntrack` (`netfilter` 的一部分) 會將封包與 Pod 最初建立的連線進行比對，而且由於最初套用了 DNAT，其透過將來源 IP 從 EKS 控制平面 ENI 的 IP 重寫到 `kubernetes` 服務 IP，進而實現反轉：

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 172.16.0.1 | Src: 443            |                 |
| Dst: 10.80.0.2  | Dst: 67493          |                 |
+-----------------+---------------------+-----------------+
```

 **1。CNI 處理** 

CNI 會識別此封包屬於先前已套用 SNAT 的連線。其會反轉 SNAT，並將目的地 IP 變更回 Pod 的 IP：

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 172.16.0.1 | Src: 443            |                 |
| Dst: 10.85.1.56 | Dst: 67493          |                 |
+-----------------+---------------------+-----------------+
```

CNI 偵測到目的地 IP 屬於其網路中的 Pod，並將封包交付至正確的 Pod 網路命名空間。

此流程會示範 CNI NAT-ing 可如何透過允許封包路由回節點來簡化組態，並且無需額外的 Pod CIDR 路由。

## EKS 控制平面到混合節點上執行的 Pod (Webhook)
<a name="hybrid-nodes-concepts-traffic-flows-cp-to-pod"></a>

![\[EKS 控制平面到混合節點上執行的 Pod\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-cp-to-pod.png)


此流量模式最常見於 Webhook 中，而 EKS 控制平面需要直接啟動與混合節點上 Pod 中執行的 Webhook 伺服器的連線。範例包括驗證和變換許可 Webhook，其中這些 Webhook 會在資源驗證或變換程序期間由 API 伺服器呼叫。

### 請求
<a name="_request_5"></a>

 **1。EKS Kubernetes API 伺服器啟動請求** 

在叢集中設定 Webhook 並且相關 API 操作將其觸發後，EKS Kubernetes API 伺服器需要直接連線至 Webhook 伺服器 Pod。API 伺服器會先從與 Webhook 相關聯的服務或端點資源中查詢 Pod 的 IP 位址。

假設 Webhook Pod 在具有 IP `10.85.1.23` 的混合節點上執行，EKS Kubernetes API 伺服器會建立對 Webhook 端點的 HTTPS 請求。初始封包會透過 VPC 中的 EKS 控制平面 ENI 傳送，因為目的地 IP `10.85.1.23` 屬於已設定的遠端 Pod CIDR (`10.85.0.0/16`)。封包如下所示：

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 10.0.0.132 | Src: 41892 (random) |                 |
| Dst: 10.85.1.23 | Dst: 8443           |                 |
+-----------------+---------------------+-----------------+
```

 **2. VPC 網路處理** 

該封包會離開 EKS 控制平面 ENI 並進入 VPC 網路層，同時會將子網路的路由器作為下一個躍點。

 **3. VPC 路由表查詢** 

包含 EKS 控制平面 ENI 的子網路的 VPC 路由表包含適用於遠端 Pod CIDR 的特定路由 (`10.85.0.0/16`)。此路由規則會將封包導向 VPC-to-onprem 閘道 (例如，適用於 Direct Connect 的虛擬私有閘道或 VPN 連線)：

```
Destination     Target
10.0.0.0/16     local
10.85.0.0/16    vgw-id (VPC-to-onprem gateway)
```

 **4. 跨邊界傳輸** 

閘道會透過您已建立的連線 (例如 Direct Connect 或 VPN)，將封包跨雲端邊界傳輸到您的內部部署網路。該封包會在其於連線傳輸時，維護其原始來源和目的地 IP 位址。

 **5. 內部部署網路接收** 

封包送達本機內部部署路由器。路由器會參考其路由表，以判定連接 10.85.1.23 地址的方式。為此，您的內部部署網路必須具有將流量導向適當混合節點的 Pod CIDR 的路由。

在此情況下，路由器的路由表包含一個項目，其中會指出可透過具有 IP `10.80.0.2` 的混合節點來連接 `10.85.1.0/24` 子網路：

```
Destination     Next Hop
10.85.1.0/24    10.80.0.2
```

 **6. 交付至節點** 

根據路由表項目，路由器會將封包轉送到混合節點 (`10.80.0.2`)。當封包抵達節點時，它看起來與 EKS Kubernetes API 伺服器傳送它時相同，而目的地 IP 仍然是 Pod 的 IP。

 **7. CNI 處理** 

節點的網路堆疊會接收封包，並發現目的地 IP 不是節點的自有 IP，然後將其傳遞給 CNI 以進行處理。CNI 會識別目的地 IP 屬於在此節點上以本機執行的 Pod，並透過適當的虛擬介面將封包轉送至正確的 Pod：

```
Original packet -> node routing -> CNI -> Pod's network namespace
```

Pod 中的 Webhook 伺服器會接收請求並進行處理。

### 回應
<a name="_response_5"></a>

在 Webhook Pod 處理請求後，它會遵循相同路徑反向傳回回應：

 **7. Pod 傳送回應** 

Webhook Pod 會使用其自己的 IP 作為來源建立回應封包，並將原始請求者 (EKS 控制平面 ENI) 作為目的地：

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 10.85.1.23 | Src: 8443           |                 |
| Dst: 10.0.0.132 | Dst: 41892          |                 |
+-----------------+---------------------+-----------------+
```

CNI 會識別此封包會移至外部網路 (而非本機 Pod)，並將封包傳遞至保留原始來源 IP 的節點的網路堆疊。

 **6. 節點網路處理** 

節點會判定目的地 IP (`10.0.0.132`) 不在本機網路中，並將封包轉送至其預設閘道 (本機路由器)。

 **5. 本機路由器路由** 

本機路由器會參考其路由表，並判定目的地 IP (`10.0.0.132`) 屬於 VPC CIDR (`10.0.0.0/16`)。它會將封包轉送到連接至 AWS的閘道。

 **4. 跨邊界傳輸** 

該封包會傳回相同的內部部署至 VPC 連線，並以相反方向跨越雲端邊界。

 **3. VPC 路由** 

當該封包抵達 VPC 時，路由表會識別目的地 IP 屬於 VPC 內的子網路。封包會在 VPC 中進行相應路由。

 **2. 和 1. EKS 控制平面 ENI 接收** 

該封包會到達連接到 EKS Kubernetes API 伺服器的 ENI，以便完成往返。API 伺服器會接收 Webhook 回應，並繼續根據此回應處理原始 API 請求。

此流量流程示範為什麼遠端 Pod CIDR 必須正確進行設定和路由：
+ VPC 必須具有指向內部部署閘道的遠端 Pod CIDR 的路由
+ 您的內部部署網路必須具有 Pod CIDR 的路由，並將流量導向託管這些 Pod 的特定節點
+ 如果沒有此路由組態，將無法從 EKS 控制平面連接混合節點上 Pod 中執行的 Webhook 和其他類似服務。

## 在混合節點上執行的 Pod 到 Pod
<a name="hybrid-nodes-concepts-traffic-flows-pod-to-pod"></a>

![\[在混合節點上執行的 Pod 到 Pod\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-pod-to-pod.png)


本節說明在不同混合節點上執行的 Pod 會如何彼此進行通訊。此範例假設您的 CNI 使用 VXLAN 進行封裝，而這在 Cilium 或 Calico 等 CNI 中很常見。整體程序與其他封裝通訊協定，例如 Geneve 或 IP-in-IP。

### 請求
<a name="_request_6"></a>

 **1。Pod A 啟動通訊** 

節點 1 上的 Pod A (`10.85.1.56`) 想要將流量傳送至節點 2 上的 Pod B (`10.85.2.67`)。初始封包如下所示：

```
+------------------+-----------------+-------------+-----------------+
| Ethernet Header  | IP Header       | TCP/UDP     | Payload         |
| Src: Pod A MAC   | Src: 10.85.1.56 | Src: 43721  |                 |
| Dst: Gateway MAC | Dst: 10.85.2.67 | Dst: 8080   |                 |
+------------------+-----------------+-------------+-----------------+
```

 **2. CNI 攔截和處理封包** 

當 Pod A 的封包離開其網路命名空間時，CNI 會將其攔截。CNI 會參考其路由表並判定： - 目的地 IP (`10.85.2.67`) 屬於 Pod CIDR - 此 IP 不在本機節點上，但屬於節點 2 (`10.80.0.3`) - 該封包需要使用 VXLAN 進行封裝。

封裝的決策至關重要，因為底層實體網路不知道如何直接路由 Pod CIDR，它只知道如何在節點 IP 之間路由流量。

CNI 會將整個原始封包封裝在 VXLAN 架構內。這實際上建立了有效地具有新標頭的「封包內封包」：

```
+-----------------+----------------+--------------+------------+---------------------------+
| Outer Ethernet  | Outer IP       | Outer UDP    | VXLAN      | Original Pod-to-Pod       |
| Src: Node1 MAC  | Src: 10.80.0.2 | Src: Random  | VNI: 42    | Packet (unchanged         |
| Dst: Router MAC | Dst: 10.80.0.3 | Dst: 8472    |            | from above)               |
+-----------------+----------------+--------------+------------+---------------------------+
```

此封裝的要點：- 將外部封包從節點 1 (`10.80.0.2`) 傳送至節點 2 (`10.80.0.3`) - 根據預設，UDP 連接埠 `8472` 是 Cilium 使用的 VXLAN 連接埠 - VXLAN 網路識別符 (VNI) 可識別此封包所屬的覆蓋網路 - 整個原始封包 (將 Pod A 的 IP 作為來源，將 Pod B 的 IP 作為目的地) 可在內部完整保留

已封裝的封包現在會進入節點 1 的常規網路堆疊，並以與任何其他封包相同的方式進行處理：

1.  **節點網路處理**：節點 1 的網路堆疊會根據其目的地 (`10.80.0.3`) 路由封包

1.  **本機網路交付**：
   + 如果兩個節點位於相同的第 2 層網路上，則該封包會直接傳送至節點 2
   + 如果封包位於不同的子網路上，則會先將該封包轉送至本機路由器

1.  **路由器處理**：路由器會根據其路由表轉送封包，並將其交付至節點 2

 **3. 接收節點處理** 

當封裝的封包抵達節點 2 (`10.80.0.3`) 時：

1. 節點的網路堆疊會接收此封包並將其識別為 VXLAN 封包 (UDP 連接埠 `4789`)

1. 該封包會傳遞至 CNI 的 VXLAN 介面，以進行處理

 **4. VXLAN 解封裝** 

節點 2 上的 CNI 會處理 VXLAN 封包：

1. 它會移除外部標頭 (乙太網路、IP、UDP 和 VXLAN)

1. 它會擷取原始內部封包

1. 該封包現恢復為其原始格式：

```
+------------------+-----------------+-------------+-----------------+
| Ethernet Header  | IP Header       | TCP/UDP     | Payload         |
| Src: Pod A MAC   | Src: 10.85.1.56 | Src: 43721  |                 |
| Dst: Gateway MAC | Dst: 10.85.2.67 | Dst: 8080   |                 |
+------------------+-----------------+-------------+-----------------+
```

節點 2 上的 CNI 會檢查目的地 IP (`10.85.2.67`) 和：

1. 識別此 IP 屬於本機 Pod

1. 透過適當的虛擬介面路由封包

1. 將封包交付至 Pod B 的網路命名空間

### 回應
<a name="_response_6"></a>

當 Pod B 回應 Pod A 時，整個程序會發生反轉，即以相反順序執行：

1. Pod B 會將封包傳送至 Pod A (`10.85.1.56`)

1. 節點 2 的 CNI 會使用 VXLAN 進行封裝，並將目的地設定為節點 1 (`10.80.0.2`)

1. 封裝的封包會交付至節點 1

1. 節點 1 的 CNI 會將其解封裝，並將原始回應交付給 Pod A

## 雲端節點上的 Pod 到混合節點上的 Pod (東西流量)
<a name="hybrid-nodes-concepts-traffic-flows-east-west"></a>

![\[雲端節點上的 Pod 到混合節點上的 Pod\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-east-west.png)


### 請求
<a name="_request_7"></a>

 **1。Pod A 啟動通訊** 

EC2 節點上的 Pod A (`10.0.0.56`) 想要將流量傳送至混合節點上的 Pod B (`10.85.1.56`)。初始封包如下所示：

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 10.0.0.56  | Src: 52390 (random) |                 |
| Dst: 10.85.1.56 | Dst: 8080           |                 |
+-----------------+---------------------+-----------------+
```

使用 VPC CNI 時，Pod A 具有來自 VPC CIDR 的 IP，並會直接連接到 EC2 執行個體上的 ENI。Pod 的網路命名空間已連接至 VPC 網路，因此該封包會直接進入 VPC 路由基礎結構。

 **2. VPC 路由** 

VPC 路由表包含遠端 Pod CIDR (`10.85.0.0/16`) 的特定路由，並且會將此流量導向 VPC-to-onprem 閘道：

```
Destination     Target
10.0.0.0/16     local
10.85.0.0/16    vgw-id (VPC-to-onprem gateway)
```

根據此路由規則，該封包會導向至連接到內部部署網路的閘道。

 **3. 跨邊界傳輸** 

閘道會透過您已建立的連線 (例如 Direct Connect 或 VPN)，將封包跨雲端邊界傳輸到您的內部部署網路。該封包會在其傳輸過程中，維護其原始來源和目的地 IP 位址。

 **4. 內部部署網路接收** 

封包送達本機內部部署路由器。路由器會參考其路由表，以判定連接 10.85.1.56 地址的下一個躍點。您的內部部署路由器必須具有將流量導向適當混合節點的 Pod CIDR 的路由。

該路由器的資料表包含一個項目，其中會指出可透過具有 IP `10.80.0.2` 的混合節點來連接 `10.85.1.0/24` 子網路：

```
Destination     Next Hop
10.85.1.0/24    10.80.0.2
```

 **5. 節點網路處理** 

路由器會將封包轉送至混合節點 (`10.80.0.2`)。當封包抵達節點時，它仍然將 Pod A 的 IP 作為來源，並將 Pod B 的 IP 作為目的地。

 **6. CNI 處理** 

節點的網路堆疊會接收封包，並發現目的地 IP 不是其自有 IP，然後將其傳遞給 CNI 以進行處理。CNI 會識別目的地 IP 屬於在此節點上以本機執行的 Pod，並透過適當的虛擬介面將封包轉送至正確的 Pod：

```
Original packet -> node routing -> CNI -> Pod B's network namespace
```

Pod B 會接收封包並視需要進行處理。

### 回應
<a name="_response_7"></a>

 **6. Pod B 傳送回應** 

Pod B 會以其自有 IP 作為來源建立回應封包，而會將 Pod A 的 IP 作為目的地：

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 10.85.1.56 | Src: 8080           |                 |
| Dst: 10.0.0.56  | Dst: 52390          |                 |
+-----------------+---------------------+-----------------+
```

CNI 會識別此封包以外部網路為目的地，並將其傳遞至節點的網路堆疊。

 **5. 節點網路處理** 

節點會判定目的地 IP (`10.0.0.56`) 不屬於本機網路，並將封包轉送至其預設閘道 (本機路由器)。

 **4. 本機路由器路由** 

本機路由器會參考其路由表，並判定目的地 IP (`10.0.0.56`) 屬於 VPC CIDR (`10.0.0.0/16`)。它會將封包轉送到連接至 AWS的閘道。

 **3. 跨邊界傳輸** 

該封包會傳回相同的內部部署至 VPC 連線，並以相反方向跨越雲端邊界。

 **2. VPC 路由** 

當該封包抵達 VPC 時，路由系統會識別目的地 IP 屬於 VPC 內的子網路。該封包會透過 VPC 網路路由至託管 Pod A 的 EC2 執行個體。

 **1。Pod A 接收回應** 

該封包抵達 EC2 執行個體，並透過其連接的 ENI 直接交付至 Pod A。由於 VPC CNI 不會為 VPC 中的 Pod 使用覆蓋網路，因此不需要額外的解封裝 - 封包送達時，其原始標題會完整保留。

此東西流量流程示範為什麼遠端 Pod CIDR 必須正確設定並可從雙向路由：
+ VPC 必須具有指向內部部署閘道的遠端 Pod CIDR 的路由
+ 您的內部部署網路必須具有 Pod CIDR 的路由，並將流量導向託管這些 Pod 的特定節點。

# 混合節點 `nodeadm` 參考
<a name="hybrid-nodes-nodeadm"></a>

Amazon EKS 混合節點 CLI (`nodeadm`) 可簡化混合節點元件的安裝、組態、註冊和解除安裝。您可以在作業系統映像中包含 `nodeadm`，以自動化混合節點引導，如需詳細資訊，請參閱 [準備混合節點的作業系統](hybrid-nodes-os.md)。

混合節點的 `nodeadm` 版本與用於將 Amazon EC2 執行個體引導為 Amazon EKS 叢集中節點的 `nodeadm` 版本不同。遵循相應 `nodeadm` 版本的文件和參考。本文件頁面適用於混合節點 `nodeadm` 版本。

混合節點的原始程式碼`nodeadm`會發佈在 https://github.com/aws/eks-hybrid GitHub 儲存庫中。

**重要**  
您必須與擁有 root/sudo 權限的使用者一同執行 `nodeadm`。

## 下載 `nodeadm`
<a name="_download_nodeadm"></a>

`nodeadm` 的混合節點版本託管於前端為 Amazon CloudFront 的 Amazon S3 中。若要在每個內部部署主機上安裝 `nodeadm`，您可以從內部部署主機執行下列命令。

 **對於 x86\$164 主機** 

```
curl -OL 'https://hybrid-assets.eks.amazonaws.com/releases/latest/bin/linux/amd64/nodeadm'
```

 **對於 ARM 主機** 

```
curl -OL 'https://hybrid-assets.eks.amazonaws.com/releases/latest/bin/linux/arm64/nodeadm'
```

在每個主機上，為下載的二進位檔新增可執行檔許可。

```
chmod +x nodeadm
```

## `nodeadm install`
<a name="_nodeadm_install"></a>

`nodeadm install` 命令可用於安裝執行混合節點並將其加入 Amazon EKS 叢集所需的成品和相依性。`nodeadm install` 命令可在每個混合節點上分別執行，也可以在映像建置管道期間執行，進而在作業系統映像中預先安裝混合節點相依性。

 **用途** 

```
nodeadm install [KUBERNETES_VERSION] [flags]
```

 **位置引數** 

(必要) `KUBERNETES_VERSION` 要安裝的 EKS Kubernetes major.minor 版本，例如 `1.32` 

 **Flags** 


| Name | 必要 | Description | 
| --- | --- | --- | 
|   `-p`,  `--credential-provider`   |  TRUE  |  要安裝的憑證提供者。支援的值為 `iam-ra` 和 `ssm`。如需詳細資訊，請參閱[準備混合節點的憑證](hybrid-nodes-creds.md)。  | 
|   `-s`,  `--containerd-source`   |  FALSE  |  `containerd` 的來源。`nodeadm` 支援從 OS distro、Docker 套件安裝 `containerd`，並略過 `containerd` 安裝。  **Values (數值)**   `distro` - 這是預設值。 `nodeadm`將安裝由與 EKS Kubernetes 版本相容的節點作業系統分發的最新`containerd`套件。 `distro` 不是 Red Hat Enterprise Linux (RHEL) 作業系統支援的值。  `docker` - `nodeadm`將安裝由 Docker 建置和分發且與 EKS Kubernetes 版本相容的最新`containerd`套件。 `docker` 不是 Amazon Linux 2023 支援的值。  `none` - `nodeadm` 不會安裝 `containerd` 套件。您必須先手動安裝 `containerd`，然後才能執行 `nodeadm init`。  | 
|   `-r`,  `--region`   |  FALSE  |  指定下載成品 AWS 的區域，例如 SSM Agent。預設為 `us-west-2`。  | 
|   `-t`,  `--timeout`   |  FALSE  |  安裝命令持續時間上限。輸入遵循持續時間格式。例如 `1h23m`。安裝命令的預設下載逾時設定為 20 分鐘。  | 
|   `-h`, `--help`   |  FALSE  |  顯示說明訊息，其中包含可用的旗標、子命令和定位值參數。  | 

 **範例** 

`1.32` 使用 AWS Systems Manager (SSM) 做為登入資料提供者來安裝 Kubernetes 版本

```
nodeadm install 1.32 --credential-provider ssm
```

`1.32` 使用 AWS Systems Manager (SSM) 作為登入資料提供者安裝 Kubernetes 版本，Docker 作為容器化來源，下載逾時為 20 分鐘。

```
nodeadm install 1.32 --credential-provider ssm --containerd-source docker --timeout 20m
```

`1.32` 使用 AWS IAM Roles Anywhere 做為登入資料提供者來安裝 Kubernetes 版本

```
nodeadm install 1.32 --credential-provider iam-ra
```

## `nodeadm config check`
<a name="_nodeadm_config_check"></a>

`nodeadm config check` 命令會檢查提供的節點組態是否存在錯誤。此命令可用於確認和驗證混合節點組態檔案的正確性。

 **用途** 

```
nodeadm config check [flags]
```

 **Flags** 


| Name | 必要 | Description | 
| --- | --- | --- | 
|   `-c`,  `--config-source`   |  TRUE  |  nodeadm 組態的來源。對於混合節點，輸入應該遵循具有檔案結構描述的 URI。  | 
|   `-h`, `--help`   |  FALSE  |  顯示說明訊息，其中包含可用的旗標、子命令和定位值參數。  | 

 **範例** 

```
nodeadm config check -c file://nodeConfig.yaml
```

## `nodeadm init`
<a name="_nodeadm_init"></a>

`nodeadm init` 命令會啟動混合節點並將其與設定的 Amazon EKS 叢集進行連接。如需如何設定 `nodeConfig.yaml` 檔案的詳細資訊，請參閱 [SSM 混合啟用的節點組態](#hybrid-nodes-node-config-ssm) 或 [IAM Roles Anywhere 的節點組態](#hybrid-nodes-node-config-iamra)。

 **用途** 

```
nodeadm init [flags]
```

 **Flags** 


| Name | 必要 | Description | 
| --- | --- | --- | 
|   `-c`,  `--config-source`   |  TRUE  |  `nodeadm` 組態的來源。對於混合節點，輸入應該遵循具有檔案結構描述的 URI。  | 
|   `-s`,  `--skip`   |  FALSE  |  要略過的 `init` 階段。除非有助於修正問題，否則不建議略過任何階段。  **Values (數值)**   `install-validation` 會略過檢查上述安裝命令是否已成功執行。  如果節點上已啟用防火牆，則 `cni-validation` 會略過檢查 Cilium 或 Calico CNI 的 VXLAN 連接埠是否已開啟  `node-ip-validation` 會略過檢查節點 IP 是否落在遠端節點網路中的 CIDR 內  | 
|   `-h`, `--help`   |  FALSE  |  顯示說明訊息，其中包含可用的旗標、子命令和定位值參數。  | 

 **範例** 

```
nodeadm init -c file://nodeConfig.yaml
```

## `nodeadm upgrade`
<a name="_nodeadm_upgrade"></a>

`nodeadm upgrade` 命令會將所有已安裝的成品升級到最新版本，並引導節點來設定升級的成品，並在 AWS上加入 EKS 叢集。升級是對節點上執行的工作負載的干擾命令。請先將工作負載移至另一個節點，然後再執行升級。

 **用途** 

```
nodeadm upgrade [KUBERNETES_VERSION] [flags]
```

 **位置引數** 

(必要) `KUBERNETES_VERSION` 要安裝的 EKS Kubernetes major.minor 版本，例如 `1.32` 

 **Flags** 


| Name | 必要 | Description | 
| --- | --- | --- | 
|   `-c`,  `--config-source`   |  TRUE  |  `nodeadm` 組態的來源。對於混合節點，輸入應該遵循具有檔案結構描述的 URI。  | 
|   `-t`,  `--timeout`   |  FALSE  |  下載成品逾時。輸入遵循持續時間格式。例如 1h23m。升級命令的預設下載逾時設定為 10 分鐘。  | 
|   `-s`,  `--skip`   |  FALSE  |  要略過的升級階段。除非有助於修正問題，否則不建議略過任意階段。  **Values (數值)**   `pod-validation` 會略過檢查節點上是否所有 Pod 都在執行，但常駐程式集和靜態 Pod 除外。  `node-validation` 會略過檢查是否已包圍隔離節點。  `init-validation` 會略過檢查節點是否在執行升級之前已成功初始化。  `containerd-major-version-upgrade` 可防止在節點升級期間進行容器主要版本升級。  | 
|   `-h`, `--help`   |  FALSE  |  顯示說明訊息，其中包含可用的旗標、子命令和定位值參數。  | 

 **範例** 

```
nodeadm upgrade 1.32 -c file://nodeConfig.yaml
```

```
nodeadm upgrade 1.32 -c file://nodeConfig.yaml --timeout 20m
```

## `nodeadm uninstall`
<a name="_nodeadm_uninstall"></a>

`nodeadm uninstall` 命令會停止並移除 `nodeadm` 在 `nodeadm install` 期間安裝的成品，包括 kubelet 和 containerd。請注意，解除安裝命令不會耗盡或刪除叢集中的混合節點。您必須分別執行耗盡和刪除操作，如需詳細資訊，請參閱 [移除混合節點](hybrid-nodes-remove.md)。根據預設，如果節點上還有剩餘的 Pod，則 `nodeadm uninstall` 不會繼續。同樣地，`nodeadm uninstall` 不會移除 CNI 相依性或您在叢集上執行的其他 Kubernetes 附加元件的相依性。若要從主機完全移除 CNI 安裝，請參閱 [設定混合節點的 CNI](hybrid-nodes-cni.md) 中的指示。如果您使用 AWS SSM 混合啟用做為內部部署憑證提供者，`nodeadm uninstall`命令會將您的主機取消註冊為 AWS SSM 受管執行個體。

 **用途** 

```
nodeadm uninstall [flags]
```

 **Flags** 


| Name | 必要 | Description | 
| --- | --- | --- | 
|   `-s`,  `--skip`   |  FALSE  |  要略過的解除安裝階段。除非有助於修正問題，否則不建議略過任何階段。  **Values (數值)**   `pod-validation` 會略過檢查節點上是否所有 Pod 都在執行，但常駐程式集和靜態 Pod 除外。  `node-validation` 會略過檢查是否已包圍隔離節點。  `init-validation` 會略過檢查節點是否在執行解除安裝之前已成功初始化。  | 
|   `-h`,  `--help`   |  FALSE  |  顯示說明訊息，其中包含可用的旗標、子命令和定位值參數。  | 
|   `-f`,  `--force`   |  FALSE  |  強制刪除可能包含 Kubernetes 和 CNI 元件剩餘檔案的其他目錄。  **WARNING**  這將刪除預設 Kubernetes 和 CNI 目錄中的所有內容 (`/var/lib/cni`、`/etc/cni/net.d` 等等)。如果您在這些位置存放您自己的資料，則請勿使用此旗標。 從 nodeadm `v1.0.9` 開始，`./nodeadm uninstall --skip node-validation,pod-validation --force` 命令不會再刪除 `/var/lib/kubelet` 目錄。這是因為它可能包含 Pod 磁碟區和磁碟區子路徑目錄，而這些目錄有時會包含掛載的節點檔案系統。  **安全處理秘訣**  - 刪除掛載的路徑可能會導致意外刪除實際掛載的節點檔案系統。在手動刪除 `/var/lib/kubelet` 目錄之前，請仔細檢查所有作用中的掛載並安全地卸載磁碟區，以避免資料遺失。  | 

 **範例** 

```
nodeadm uninstall
```

```
nodeadm uninstall --skip node-validation,pod-validation
```

## `nodeadm debug`
<a name="_nodeadm_debug"></a>

`nodeadm debug` 命令可用於對運作狀態不佳或設定錯誤的混合節點進行故障診斷。它會驗證下列需求是否已就位。
+ 節點具有必要 AWS APIs的網路存取權，以取得登入資料，
+ 節點可以取得所設定混合節點 IAM 角色的 AWS 登入資料，
+ 節點具有對 EKS Kubernetes API 端點的網路存取權以及 EKS Kubernetes API 端點憑證的有效性，
+ 節點能夠使用 EKS 叢集進行身分驗證，其在叢集中的身分有效，而且該節點可以透過為 EKS 叢集設定的 VPC 存取 EKS 叢集。

如果發現錯誤，命令的輸出會建議故障診斷步驟。某些驗證步驟會顯示子程序。如果失敗，輸出會顯示在驗證錯誤下的 stderr 區段中。

 **用途** 

```
nodeadm debug [flags]
```

 **Flags** 


| Name | 必要 | Description | 
| --- | --- | --- | 
|   `-c`, `--config-source`   |  TRUE  |  `nodeadm` 組態的來源。對於混合節點，輸入應該遵循具有檔案結構描述的 URI。  | 
|   `--no-color`   |  FALSE  |  停用顏色輸出。適用於自動化。  | 
|   `-h`, `--help`   |  FALSE  |  顯示說明訊息，其中包含可用的旗標、子命令和定位值參數。  | 

 **範例** 

```
nodeadm debug -c file://nodeConfig.yaml
```

## Nodeadm 檔案位置
<a name="_nodeadm_file_locations"></a>

### nodeadm 安裝
<a name="_nodeadm_install_2"></a>

執行 `nodeadm install` 時，會設定下列檔案和檔案位置。


| Artifact | 路徑 | 
| --- | --- | 
|  IAM Roles Anywhere CLI  |  /usr/local/bin/aws\$1signing\$1helper  | 
|  Kubelet 二進位檔  |  /usr/bin/kubelet  | 
|  Kubectl 二進位檔  |  usr/local/bin/kubectl  | 
|  ECR 憑證提供者  |  /etc/eks/image-credential-provider/ecr-credential-provider  | 
|   AWS IAM 驗證器  |  /usr/local/bin/aws-iam-authenticator  | 
|  SSM Setup CLI  |  /opt/ssm/ssm-setup-cli  | 
|  SSM Agent  |  在 Ubuntu 上 - /snap/amazon-ssm-agent/current/amazon-ssm-agent 在 RHEL 和 AL2023 上 - /usr/bin/amazon-ssm-agent  | 
|  containerd  |  在 Ubuntu 和 AL2023 上 - /usr/bin/containerd 在 RHEL 上 - /bin/containerd  | 
|  Iptables  |  在 Ubuntu 和 AL2023 上 - /usr/sbin/iptables 在 RHEL 上 - /sbin/iptables  | 
|  CNI 外掛程式  |  /opt/cni/bin  | 
|  已安裝的成品追蹤器  |  /opt/nodeadm/tracker  | 

### nodeadm init
<a name="_nodeadm_init_2"></a>

執行 `nodeadm init` 時，會設定下列檔案和檔案位置。


| Name | 路徑 | 
| --- | --- | 
|  Kubelet kubeconfig  |  /var/lib/kubelet/kubeconfig  | 
|  Kubelet 組態  |  /etc/kubernetes/kubelet/config.json  | 
|  Kubelet systemd 單位  |  /etc/systemd/system/kubelet.service  | 
|  映像憑證提供者組態  |  /etc/eks/image-credential-provider/config.json  | 
|  Kubelet env 檔案  |  /etc/eks/kubelet/environment  | 
|  Kubelet 憑證  |  /etc/kubernetes/pki/ca.crt  | 
|  Containerd 組態  |  /etc/containerd/config.toml  | 
|  Containerd 核心模組組態  |  /etc/modules-load.d/contianerd.conf  | 
|   AWS 組態檔案  |  /etc/aws/hybrid/config  | 
|   AWS 登入資料檔案 （如果啟用登入資料檔案）  |  /eks-hybrid/.aws/credentials  | 
|   AWS 簽署協助程式系統單位  |  /etc/systemd/system/aws\$1signing\$1helper\$1update.service  | 
|  Sysctl conf 檔案  |  /etc/sysctl.d/99-nodeadm.conf  | 
|  Ca-certificates  |  /etc/ssl/certs/ca-certificates.crt  | 
|  Gpg 金鑰檔案  |  /etc/apt/keyrings/docker.asc  | 
|  Docker 儲存庫來源檔案  |  /etc/apt/sources.list.d/docker.list  | 

## SSM 混合啟用的節點組態
<a name="hybrid-nodes-node-config-ssm"></a>

以下是針對混合節點登入資料使用 AWS SSM 混合啟用`nodeConfig.yaml`的範例。

```
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
  cluster:
    name:             # Name of the EKS cluster
    region:           # AWS Region where the EKS cluster resides
  hybrid:
    ssm:
      activationCode: # SSM hybrid activation code
      activationId:   # SSM hybrid activation id
```

## IAM Roles Anywhere 的節點組態
<a name="hybrid-nodes-node-config-iamra"></a>

以下是混合節點登入`nodeConfig.yaml`資料 AWS IAM Roles Anywhere 的範例。

使用 AWS IAM Roles Anywhere 做為內部部署憑證提供者時，`nodeName`您在`nodeadm`組態中使用的 必須符合您為混合節點 IAM 角色設定範圍的許可。例如，如果您的混合節點 IAM 角色許可僅允許 AWS IAM Roles Anywhere 在角色工作階段名稱等於主機憑證的 CN 時擔任角色，則`nodeadm`組態`nodeName`中的 必須與您憑證的 CN 相同。您使用的 `nodeName` 不可超過 64 個字元。如需詳細資訊，請參閱[準備混合節點的憑證](hybrid-nodes-creds.md)。

```
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
  cluster:
    name:              # Name of the EKS cluster
    region:            # AWS Region where the EKS cluster resides
  hybrid:
    iamRolesAnywhere:
      nodeName:        # Name of the node
      trustAnchorArn:  # ARN of the IAM Roles Anywhere trust anchor
      profileArn:      # ARN of the IAM Roles Anywhere profile
      roleArn:         # ARN of the Hybrid Nodes IAM role
      certificatePath: # Path to the certificate file to authenticate with the IAM Roles Anywhere trust anchor
      privateKeyPath:  # Path to the private key file for the certificate
```

## 用於自訂 kubelet 的節點組態 (選用)
<a name="hybrid-nodes-nodeadm-kubelet"></a>

您可以在 `nodeadm` 組態中傳遞 kubelet 組態和旗標。請參閱以下範例，了解如何新增額外的節點標籤 `abc.amazonaws.com/test-label` 以及將 `shutdownGracePeriod` 設定為 30 秒的組態。

```
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
  cluster:
    name:             # Name of the EKS cluster
    region:           # AWS Region where the EKS cluster resides
  kubelet:
    config:           # Map of kubelet config and values
       shutdownGracePeriod: 30s
    flags:            # List of kubelet flags
       - --node-labels=abc.company.com/test-label=true
  hybrid:
    ssm:
      activationCode: # SSM hybrid activation code
      activationId:   # SSM hybrid activation id
```

## 用於自訂 containerd 的節點組態 (選用)
<a name="_node_config_for_customizing_containerd_optional"></a>

您可以在 `nodeadm` 組態中傳遞自訂 containerd 組態。`nodeadm` 的 containerd 組態接受內嵌 TOML。請參閱以下範例，了解如何設定 containerd 以停用刪除 containerd 內容存放區中已解壓縮的映像層。

```
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
  cluster:
    name:             # Name of the EKS cluster
    region:           # AWS Region where the EKS cluster resides
  containerd:
    config: |         # Inline TOML containerd additional configuration
       [plugins."io.containerd.grpc.v1.cri".containerd]
       discard_unpacked_layers = false
  hybrid:
    ssm:
      activationCode: # SSM hybrid activation code
      activationId:   # SSM hybrid activation id
```

**注意**  
容器版本 1.x 和 2.x 使用不同的組態格式。Containerd 1.x 使用組態版本 2，而 Containerd 2.x 使用組態版本 3。雖然 containerd 2.x 仍與組態第 2 版回溯相容，但建議使用組態第 3 版，以獲得最佳效能。使用 檢查您的容器版本`containerd --version`或檢閱`nodeadm`安裝日誌。如需組態版本控制的詳細資訊，請參閱 https：//https://containerd.io/releases/

您也可以使用 containerd 組態來啟用 SELinux 支援。在 containerd 上啟用 SELinux 後，請確保在節點上排程的 Pod 已啟用適當的 securityContext 和 seLinuxOptions。如需設定安全性內容的詳細資訊，請參閱 [Kubernetes 文件](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)。

**注意**  
根據預設，Red Hat Enterprise Linux (RHEL) 8 和 RHEL 9 已啟用 SELinux，並在主機上設定為嚴格。根據預設，Amazon Linux 2023 已啟用 SELinux，並設定為寬容模式。在主機上將 SELinux 設定為寬容模式時，在 containerd 上啟用它不會封鎖請求，但會根據主機上的 SELinux 組態進行記錄。

```
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
  cluster:
    name:             # Name of the EKS cluster
    region:           # AWS Region where the EKS cluster resides
  containerd:
    config: |         # Inline TOML containerd additional configuration
       [plugins."io.containerd.grpc.v1.cri"]
       enable_selinux = true
  hybrid:
    ssm:
      activationCode: # SSM hybrid activation code
      activationId:   # SSM hybrid activation id
```

# 故障診斷混合節點
<a name="hybrid-nodes-troubleshooting"></a>

本主題涵蓋一些使用 Amazon EKS 混合節點時可能遇到的常見錯誤與修正這些錯誤的方法。如需其他疑難排解資訊，請參閱 * AWS re：Post* 上的 [排解 Amazon EKS 叢集和節點問題](troubleshooting.md)和 [Amazon EKS 知識中心標籤](https://repost.aws/tags/knowledge-center/TA4IvCeWI1TE66q4jEj4Z9zg/amazon-elastic-kubernetes-service)。如果您無法解決問題，請聯絡 AWS Support。

 **使用 `nodeadm debug` 進行節點故障診斷** 您可以從混合節點執行 `nodeadm debug` 命令，以驗證是否符合聯網和憑證要求。如需有關 `nodeadm debug` 命令的詳細資訊，請參閱 [混合節點 `nodeadm` 參考](hybrid-nodes-nodeadm.md)。

 **使用叢集洞察偵測混合節點的問題** Amazon EKS 叢集洞察包括*洞察檢查*，可偵測叢集中 EKS 混合節點組態的常見問題。您可以從 AWS 管理主控台、 AWS CLI 和 AWS SDKs 檢視所有洞見檢查的結果。如需有關叢集洞察的詳細資訊，請參閱 [利用叢集洞見為 Kubernetes 版本升級做好準備，並為錯誤組態進行故障診斷](cluster-insights.md)。

## 安裝混合節點故障診斷
<a name="hybrid-nodes-troubleshooting-install"></a>

下列故障診斷主題與使用 `nodeadm install` 命令在主機上安裝混合節點相依性相關。

 ** `nodeadm` 命令失敗 `must run as root` ** 

`nodeadm install` 命令必須由主機上具有 root 或 `sudo` 權限的使用者執行。如果您利用沒有 root 或 `sudo` 權限的使用者執行 `nodeadm install`，則會在 `nodeadm` 輸出中看到下列錯誤。

```
"msg":"Command failed","error":"must run as root"
```

 **無法連接至相依性** 

`nodeadm install` 命令可安裝混合節點所需的相依性。混合節點相依性包括 `containerd`、`kubectl`、 `kubelet`和 AWS SSM 或 AWS IAM Roles Anywhere 元件。您必須擁有從執行 `nodeadm install` 的位置的存取權，才能下載這些相依性。如需您必須能夠存取的位置清單的詳細資訊，請參閱 [準備混合節點的聯網](hybrid-nodes-networking.md)。如果您沒有存取權，則會在 `nodeadm install` 輸出中看到類似以下錯誤。

```
"msg":"Command failed","error":"failed reading file from url: ...: max retries achieved for http request"
```

 **無法更新套件管理工具** 

在安裝混合節點相依性之前，`nodeadm install` 命令會執行 `apt update` 或 `yum update` 或 `dnf update`。如果此步驟不成功，您可能會看到類似以下錯誤。若要修復，您可以在執行 `nodeadm install` 之前執行 `apt update`、`yum update` 或 `dnf update`，也可以嘗試重新執行 `nodeadm install`。

```
failed to run update using package manager
```

 **逾時或超過內容截止日期** 

執行 `nodeadm install` 時，如果您在安裝程序的各個階段看到錯誤，其中指出逾時或超過內容截止日期，則可能是連接速度緩慢，進而導致在逾時之前無法安裝混合節點相依性。若要解決這些問題，您可以嘗試使用 `nodeadm` 中的 `--timeout` 旗標來延長下載相依性的逾時持續時間。

```
nodeadm install K8S_VERSION --credential-provider CREDS_PROVIDER --timeout 20m0s
```

## 連接混合節點故障診斷
<a name="hybrid-nodes-troubleshooting-connect"></a>

本節中的故障診斷主題與使用 `nodeadm init` 命令將混合節點連接至 EKS 叢集的程序有關。

 **操作錯誤或不支援的結構描述** 

執行 `nodeadm init` 時，如果您看到與 `operation error` 或 `unsupported scheme` 相關的錯誤，請檢查您的 `nodeConfig.yaml`，以確保其格式正確並傳遞給 `nodeadm`。如需有關 `nodeConfig.yaml` 的格式和選項的詳細資訊，請參閱 [混合節點 `nodeadm` 參考](hybrid-nodes-nodeadm.md)。

```
"msg":"Command failed","error":"operation error ec2imds: GetRegion, request canceled, context deadline exceeded"
```

 **混合節點 IAM 角色缺少對 `eks:DescribeCluster` 動作的許可** 

執行 時`nodeadm init`， 會呼叫 EKS `DescribeCluster`動作，`nodeadm`嘗試收集 EKS 叢集的相關資訊。如果您的混合節點 IAM 角色沒有 `eks:DescribeCluster`動作的許可，則您必須在執行 `nodeadm`時傳遞節點組態中的 Kubernetes API 端點、叢集 CA 套件和服務 IPv4 CIDR`nodeadm init`。如需有關混合節點 IAM 角色所需許可的詳細資訊，請參閱 [準備混合節點的憑證](hybrid-nodes-creds.md)。

```
"msg":"Command failed","error":"operation error EKS: DescribeCluster, https response error StatusCode: 403 ... AccessDeniedException"
```

 **混合節點 IAM 角色缺少對 `eks:ListAccessEntries` 動作的許可** 

執行 時`nodeadm init`， 會呼叫 EKS `ListAccessEntries`動作，`nodeadm`嘗試驗證 EKS 叢集是否具有與混合節點 IAM 角色`HYBRID_LINUX`相關聯的 類型存取項目。如果您的混合節點 IAM 角色沒有 `eks:ListAccessEntries`動作的許可，則您必須在執行 `nodeadm init`命令時傳遞 `--skip cluster-access-validation`旗標。如需有關混合節點 IAM 角色所需許可的詳細資訊，請參閱 [準備混合節點的憑證](hybrid-nodes-creds.md)。

```
"msg":"Command failed","error":"operation error EKS: ListAccessEntries, https response error StatusCode: 403 ... AccessDeniedException"
```

 **節點 IP 不在遠端節點網路 CIDR 中** 

執行 `nodeadm init` 時，如果節點的 IP 位址不在指定的遠端節點網路 CIDR 內，則您可能會遇到錯誤。錯誤看起來與下列範例類似：

```
node IP 10.18.0.1 is not in any of the remote network CIDR blocks [10.0.0.0/16 192.168.0.0/16]
```

此範例顯示 IP 10.18.0.1 的節點嘗試加入具有遠端網路 CIDR 10.0.0.0/16 和 192.168.0.0/16 的叢集。發生錯誤，因為 10.18.0.1 不在任一範圍內。

確認您已正確設定 `RemoteNodeNetworks` 以包含所有節點 IP 位址。如需有關聯網組態的詳細資訊，請參閱 [準備混合節點的聯網](hybrid-nodes-networking.md)。
+ 在叢集所在的區域中執行下列命令，以檢查您的 `RemoteNodeNetwork` 組態。確認輸出中列出的 CIDR 區塊包含節點的 IP 範圍，並且與錯誤訊息中列出的 CIDR 區塊相同。如果它們不相符，請確認您 `nodeConfig.yaml` 中的叢集名稱和區域與您預期的叢集相符。

```
aws eks describe-cluster --name CLUSTER_NAME --region REGION_NAME --query cluster.remoteNetworkConfig.remoteNodeNetworks
```
+ 驗證您正在處理的是預期節點：
  + 檢查其主機名稱和 IP 位址是否與您要向叢集註冊的 IP 位址相符，以確認您使用正確的節點。
  + 確認此節點位於正確的內部部署網路中 (在叢集設定期間，其 CIDR 範圍已註冊為 `RemoteNodeNetwork` 的網路)。

如果您的節點 IP 仍然不符合預期，請檢查下列項目：
+ 如果您使用的是 IAM Roles Anywhere，`kubelet` 會在 IAM Roles Anywhere `nodeName` 上執行 DNS 查詢，並在可用時使用與節點名稱相關聯的 IP。如果您維護節點的 DNS 項目，請確認這些項目會指向遠端節點網路 CIDR 內的 IP。
+ 如果您的節點有多個網路介面，`kubelet` 可能會預設選取遠端節點網路 CIDR 外部的 IP 位址的介面。若要使用不同的介面，請使用 `nodeConfig.yaml` 中的 `--node-ip` `kubelet` 旗標指定其 IP 位址。如需詳細資訊，請參閱[混合節點 `nodeadm` 參考](hybrid-nodes-nodeadm.md)。您可以透過在節點上執行下列命令，來檢視節點的網路介面及其 IP 位址：

```
ip addr show
```

 **混合節點未出現在 EKS 叢集中** 

如果您執行 `nodeadm init` 且已完成，但您的混合節點未出現在叢集中，混合節點與 EKS 控制平面之間的網路連線可能會發生問題，您可能並未設定必要的安全群組許可，或者您可能沒有混合節點 IAM 角色與 Kubernetes 角色型存取控制 (RBAC) 的必要映射。您可以使用下列命令檢查 `kubelet` 和 `kubelet` 日誌的狀態，進而開始偵錯程序。從無法加入叢集的混合節點執行下列命令。

```
systemctl status kubelet
```

```
journalctl -u kubelet -f
```

 **無法與叢集通訊** 

如果您的混合節點無法與叢集控制平面通訊，您可能會看到類似如下的日誌。

```
"Failed to ensure lease exists, will retry" err="Get ..."
```

```
"Unable to register node with API server" err="Post ..."
```

```
Failed to contact API server when waiting for CSINode publishing ... dial tcp <ip address>: i/o timeout
```

如果您看到這些訊息，請檢查下列項目，以確保其符合 [準備混合節點的聯網](hybrid-nodes-networking.md) 中詳述的混合節點要求。
+ 確認傳遞給 EKS 叢集的 VPC 已設定為可路由到適用於內部部署節點或選用的 Pod CIDR 的傳輸閘道 (TGW) 或虛擬私有閘道 (VGW)。
+ 確認您的 EKS 叢集具有其他安全群組，且該安全群組包含適用於內部部署節點 CIDR 的傳入規則，也選擇性地包含適用於 Pod CIDR 的傳入規則。
+ 確認您的內部部署路由器已設定為允許流量往返 EKS 控制平面。

 **未授權** 

如果您的混合節點能夠與 EKS 控制平面通訊但無法註冊，您可能會看到類似如下的日誌。請注意，以下日誌訊息中的主要差異是 `Unauthorized` 錯誤。這表明該節點無法執行其任務，因為它沒有必要許可。

```
"Failed to ensure lease exists, will retry" err="Unauthorized"
```

```
"Unable to register node with API server" err="Unauthorized"
```

```
Failed to contact API server when waiting for CSINode publishing: Unauthorized
```

如果您看到這些訊息，請檢查下列項目，以確保其符合 [準備混合節點的憑證](hybrid-nodes-creds.md) 和 [準備混合節點的叢集存取](hybrid-nodes-cluster-prep.md) 中詳述的混合節點要求。
+ 確認混合節點的身分與您預期的混合節點 IAM 角色相符。為此，可以從混合節點執行 `sudo aws sts get-caller-identity`。
+ 確認您的混合節點 IAM 角色具有必要許可。
+ 確認您的叢集中具有適用於混合節點 IAM 角色的 EKS 存取項目，或確認您的 `aws-auth` ConfigMap 具有適用於混合節點 IAM 角色的項目。如果您使用的是 EKS 存取項目，則請確認適用於混合節點 IAM 角色的存取項目具有 `HYBRID_LINUX` 存取類型。如果您使用的是 `aws-auth` ConfigMap，則請確認適用於混合節點 IAM 角色的項目符合 [準備混合節點的叢集存取](hybrid-nodes-cluster-prep.md) 中詳述的要求和格式。

### 向 EKS 叢集註冊但顯示狀態為 `Not Ready` 的混合節點
<a name="hybrid-nodes-troubleshooting-not-ready"></a>

如果您的混合節點已成功向 EKS 叢集註冊，但混合節點顯示狀態為 `Not Ready`，則首先要檢查的是容器聯網介面 (CNI) 狀態。如果您尚未安裝 CNI，則預期您的混合節點的狀態為 `Not Ready`。成功安裝並執行 CNI 後，節點狀態會更新為 `Ready`。如果您嘗試安裝 CNI，但未成功執行，請參閱此頁面上的 [混合節點 CNI 故障診斷](#hybrid-nodes-troubleshooting-cni)。

 **憑證簽署請求 (CSR) 卡在待定狀態** 

將混合節點連接到 EKS 叢集後，如果您看到混合節點有待定的 CSR，則您的混合節點不符合自動核准的要求。如果混合節點的 CSR 是由具有 `eks.amazonaws.com/compute-type: hybrid` 標籤的節點建立，且 CSR 具有下列主體替代名稱 (SAN)，則會自動核准及核發混合節點的 CSR：至少一個 DNS SAN 等於節點名稱且 IP SAN 屬於遠端節點網路 CIDR。

 **混合設定檔已存在** 

如果您變更 `nodeadm` 組態並嘗試使用新組態重新註冊節點，您可能會發現錯誤，其中會指出混合設定檔已存在，但其內容已變更。不要在組態變更之間執行 `nodeadm init`，而是要先執行 `nodeadm uninstall`，然後再執行 `nodeadm install` 和 `nodeadm init`。如此可確保正確清除組態中的變更。

```
"msg":"Command failed","error":"hybrid profile already exists at /etc/aws/hybrid/config but its contents do not align with the expected configuration"
```

 **混合節點無法解析私有 API** 

執行 `nodeadm init` 後，如果您在 `kubelet` 日誌中發現錯誤，其中顯示由於存在 `no such host` 的情況而無法聯絡 EKS Kubernetes API 伺服器，您可能需要變更內部部署網路或主機層級的 EKS Kubernetes API 端點的 DNS 項目。請參閱 * AWS Route53 文件*中的[轉送傳入 DNS 查詢到您的 VPC](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver-forwarding-inbound-queries.html)。

```
Failed to contact API server when waiting for CSINode publishing: Get ... no such host
```

 **無法在 EKS 主控台中檢視混合節點** 

如果您已註冊混合節點，但無法在 EKS 主控台中進行檢視，請檢查您用來檢視主控台的 IAM 主體的許可。您使用的 IAM 主體必須具有特定的最低 IAM 和 Kubernetes 許可，才能在主控台中檢視資源。如需詳細資訊，請參閱[在 中檢視 Kubernetes 資源 AWS 管理主控台](view-kubernetes-resources.md)。

## 執行混合節點故障診斷
<a name="_running_hybrid_nodes_troubleshooting"></a>

如果您的混合節點已向 EKS 叢集註冊，狀態為 `Ready`，然後轉換為狀態 `Not Ready`，則可能存在各種問題會導致運作狀態不佳，例如節點缺少充足的 CPU、記憶體或可用磁碟空間資源，或節點與 EKS 控制平面中斷連線。您可以使用下列步驟對節點進行故障診斷，如果無法解決問題，請聯絡 AWS Support。

從混合節點執行 `nodeadm debug`，以驗證是否符合聯網和憑證要求。如需有關 `nodeadm debug` 命令的詳細資訊，請參閱 [混合節點 `nodeadm` 參考](hybrid-nodes-nodeadm.md)。

 **取得節點狀態** 

```
kubectl get nodes -o wide
```

 **檢查節點條件和事件** 

```
kubectl describe node NODE_NAME
```

 **取得 Pod 狀態** 

```
kubectl get pods -A -o wide
```

 **檢查 Pod 條件和事件** 

```
kubectl describe pod POD_NAME
```

 **檢查 Pod 日誌** 

```
kubectl logs POD_NAME
```

 **檢查 `kubectl` 日誌** 

```
systemctl status kubelet
```

```
journalctl -u kubelet -f
```

 **Pod 即時性探查失敗或 Webhook 無法運作** 

如果混合節點上執行的應用程式、附加元件或 Webhook 未正確啟動，您可能會遇到封鎖與 Pod 的通訊的聯網問題。若要讓 EKS 控制平面聯絡在混合節點上執行的 Webhook，您必須使用遠端 Pod 網路設定 EKS 叢集，並在 VPC 路由表中為內部部署 Pod CIDR 設定路由，且以傳輸閘道 (TGW)、虛擬私有閘道 (VPW) 或您用來連接 VPC 與內部部署網路的其他閘道為目標。如需有關混合節點的聯網需求的詳細資訊，請參閱 [準備混合節點的聯網](hybrid-nodes-networking.md)。此外，您還必須在內部部署防火牆中允許此流量，並確保您的路由器可正確路由到您的 Pod。如需有關在混合節點上執行 Webhook 的需求的詳細資訊，請參閱 [設定混合節點的 Webhook](hybrid-nodes-webhooks.md)。

此案例的常見 Pod 日誌訊息如下所示，其中 ip-address 是 Kubernetes Service 的叢集 IP。

```
dial tcp <ip-address>:443: connect: no route to host
```

 ** `kubectl logs` 或 `kubectl exec` 命令無法運作 (`kubelet` API 命令）** 

如果 `kubectl attach`、`kubectl cp`、`kubectl logs`、 和 `kubectl exec``kubectl port-forward`命令在其他`kubectl`命令成功時逾時，問題可能與遠端網路組態有關。這些命令會透過叢集連接至節點上的 `kubelet` 端點。如需更多資訊，請參閱[`kubelet` 端點](hybrid-nodes-concepts-kubernetes.md#hybrid-nodes-concepts-k8s-kubelet-api)。

確認您的節點 IP 和 Pod IP 位於為叢集設定的遠端節點網路和遠端 Pod 網路 CIDR 內。使用以下命令來檢查 IP 指派。

```
kubectl get nodes -o wide
```

```
kubectl get pods -A -o wide
```

將這些 IP 與您設定的遠端網路 CIDR 進行比較，以確保正確路由。有關網路組態需求，請參閱 [準備混合節點的聯網](hybrid-nodes-networking.md)。

## 混合節點 CNI 故障診斷
<a name="hybrid-nodes-troubleshooting-cni"></a>

如果您一開始使用混合節點啟動 Cilium 或 Calico 時就遇到問題，最常見的原因是混合節點或混合節點上執行的 CNI Pod 與 EKS 控制平面之間存在聯網問題。請確保您的環境符合準備混合節點的聯網要求。將問題分成幾個部分非常實用。

EKS 叢集組態  
RemoteNodeNetwork 和 RemotePodNetwork 組態是否正確無誤？

VPC 組態  
VPC 路由表中是否有以傳輸閘道或虛擬私有閘道為目標的 RemoteNodeNetwork and RemotePodNetwork 的路由？

安全群組組態  
RemoteNodeNetwork 和 RemotePodNetwork 是否設有傳入和傳出規則？

現場部署網路  
是否有往返 EKS 控制平面以及往返混合節點和混合節點上執行的 Pod 的路由和存取權？

CNI 組態  
如果使用覆蓋網路，CNI 的 IP 集區組態是否會與使用 Webhook 時為 EKS 叢集設定的 RemotePodNetwork 相符？

 **混合節點的狀態為 `Ready` 且 CNI 未安裝** 

如果您的混合節點顯示狀態為 `Ready`，但您尚未在叢集上安裝 CNI，則混合節點上可能存在舊的 CNI 成品。根據預設，當您使用 Helm 等工具解除安裝 Cilium 和 Calico 時，不會從實體或虛擬機器中移除磁碟上的資源。此外，這些 CNI 的自訂資源定義 (CRD) 仍可能存在於舊安裝的叢集上。如需詳細資訊，請參閱 [設定混合節點的 CNI](hybrid-nodes-cni.md) 的「刪除 Cilium」和「刪除 Calico」章節。

 **Cilium 故障診斷** 

如果您在混合節點上執行 Cilium 時遇到問題，請參閱 Cilium 文件中的[故障診斷步驟](https://docs.cilium.io/en/stable/operations/troubleshooting/)。以下各節涵蓋在混合節點上部署 Cilium 時可能特有的問題。

 **Cilium 未啟動** 

如果每個混合節點上執行的 Cilium 代理程式未啟動，請檢查 Cilium 代理程式 Pod 的日誌是否存在錯誤。Cilium 代理程式需要連線到 EKS Kubernetes API 端點才能啟動。如果未正確設定此連線，則 Cilium 代理程式啟動會失敗。在此情況下，您會在 Cilium 代理程式 Pod 日誌中看到類似如下的日誌訊息。

```
msg="Unable to contact k8s api-server"
level=fatal msg="failed to start: Get \"https://<k8s-cluster-ip>:443/api/v1/namespaces/kube-system\": dial tcp <k8s-cluster-ip>:443: i/o timeout"
```

Cilium 代理程式會在主機網路上執行。您的 EKS 叢集必須使用 `RemoteNodeNetwork` 進行設定，如此才能實現 Cilium 連線。確認您的 EKS 叢集具有其他安全群組，且該安全群組包含適用於 `RemoteNodeNetwork` 的傳入規則，您的 VPC 中為您的 `RemoteNodeNetwork` 設定了路由，並且您的內部部署網路已正確設定為允許連線至 EKS 控制平面。

如果 Cilium 運算子正在執行，且部分 Cilium 代理程式也正在執行 (並非全部)，則請確認您有可用的 Pod IP 可配置給叢集中的所有節點。您可以在 Cilium 組態中搭配使用叢集集區 IPAM 和 `clusterPoolIPv4PodCIDRList` 時，設定可配置的 Pod CIDR 大小。每個節點 CIDR 大小是使用 Cilium 組態中的 `clusterPoolIPv4MaskSize` 設定進行設定的。如需詳細資訊，請參閱 Cilium 文件中的[展開叢集集區](https://docs.cilium.io/en/stable/network/concepts/ipam/cluster-pool/#expanding-the-cluster-pool)。

 **Cilium BGP 無法運作** 

如果您使用 Cilium BGP 控制平面向內部部署網路公告您的 Pod 或服務地址，則您可以使用下列 Cilium CLI 命令來檢查 BGP 是否會向資源公告路由。有關安裝 Cilium CLI 的步驟，請參閱 Cilium 文件中的[安裝 Cilium CLI](https://docs.cilium.io/en/stable/gettingstarted/k8s-install-default/#install-the-cilium-cli)。

如果 BGP 正常運作，您應該在輸出中看到工作階段狀態為 `established` 的混合節點。您可能需要與聯網團隊合作，以便為環境的本機 AS、對等 AS 和對等地址確定正確的值。

```
cilium bgp peers
```

```
cilium bgp routes
```

如果您使用 Cilium BGP 來公告類型為 `LoadBalancer` 的 服務 IP，則您的 `CiliumLoadBalancerIPPool` 和 服務必須具有相同的標籤，而該標籤應該在您的 `CiliumBGPAdvertisement` 選取器中使用。以下所示為範例。請注意，如果您使用 Cilium BGP 來公告 LoadBalancer 類型的服務 IP，則 BGP 路由可能會在 Cilium 代理程式重新啟動期間中斷。如需詳細資訊，請參閱 Cilium 文件中的[失敗案例](https://docs.cilium.io/en/latest/network/bgp-control-plane/bgp-control-plane-operation/#failure-scenarios)。

 **服務** 

```
kind: Service
apiVersion: v1
metadata:
  name: guestbook
  labels:
    app: guestbook
spec:
  ports:
  - port: 3000
    targetPort: http-server
  selector:
    app: guestbook
  type: LoadBalancer
```

 **CiliumLoadBalancerIPPool** 

```
apiVersion: cilium.io/v2alpha1
kind: CiliumLoadBalancerIPPool
metadata:
  name: guestbook-pool
  labels:
    app: guestbook
spec:
  blocks:
  - cidr: <CIDR to advertise>
  serviceSelector:
    matchExpressions:
      - { key: app, operator: In, values: [ guestbook ] }
```

 **CiliumBGPAdvertisement** 

```
apiVersion: cilium.io/v2alpha1
kind: CiliumBGPAdvertisement
metadata:
  name: bgp-advertisements-guestbook
  labels:
    advertise: bgp
spec:
  advertisements:
    - advertisementType: "Service"
      service:
        addresses:
          - ExternalIP
          - LoadBalancerIP
      selector:
        matchExpressions:
          - { key: app, operator: In, values: [ guestbook ] }
```

 **Calico 故障診斷** 

如果您在混合節點上執行 Calico 時遇到問題，請參閱 Calico 文件中的[故障診斷步驟](https://docs.tigera.io/calico/latest/operations/troubleshoot/)。以下各節涵蓋在混合節點上部署 Calico 時可能特有的問題。

下表摘要說明了 Calico 元件以及它們是否會依預設在節點或 Pod 網路上執行。如果您將 Calico 設定為使用 NAT 傳出 Pod 流量，則必須將內部部署網路設定為將流量路由到內部部署節點 CIDR，而您的 VPC 路由表必須設定有為內部部署節點 CIDR 的路由，且這些路由會以傳輸閘道 (TGW) 或虛擬私有閘道 (VGW) 為目標。如果您未將 Calico 設定為使用 NAT 傳出 Pod 流量，則必須將內部部署網路設定為將流量路由到內部部署 Pod CIDR，而您的 VPC 路由表必須設定有為內部部署 Pod CIDR 的路由，且這些路由會以傳輸閘道 (TGW) 或虛擬私有閘道 (VGW) 為目標。


| 元件 | 網路 | 
| --- | --- | 
|  Calico API 伺服器  |  節點  | 
|  Kubernetes 專用 Calico 控制器  |  Pod  | 
|  Calico 節點代理程式  |  節點  | 
|  Calico `typha`   |  節點  | 
|  Calico CSI 節點驅動程式  |  Pod  | 
|  Calico 運算子  |  節點  | 

 **Calico 資源已在封鎖節點上排程或執行** 

根據預設，Calico 資源未以 DaemonSet 執行並且具有靈活的容錯能力，可在尚未準備好排程或執行 Pod 的封鎖節點上排程這些資源。您可以變更您的運算子安裝以包含下列內容，進而限制非 DaemonSet Calico 資源的容錯。

```
installation:
  ...
  controlPlaneTolerations:
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  calicoKubeControllersDeployment:
    spec:
      template:
        spec:
          tolerations:
          - effect: NoExecute
            key: node.kubernetes.io/unreachable
            operator: Exists
            tolerationSeconds: 300
          - effect: NoExecute
            key: node.kubernetes.io/not-ready
            operator: Exists
            tolerationSeconds: 300
  typhaDeployment:
    spec:
      template:
        spec:
          tolerations:
          - effect: NoExecute
            key: node.kubernetes.io/unreachable
            operator: Exists
            tolerationSeconds: 300
          - effect: NoExecute
            key: node.kubernetes.io/not-ready
            operator: Exists
            tolerationSeconds: 300
```

## 憑證故障診斷
<a name="hybrid-nodes-troubleshooting-creds"></a>

對於 AWS SSM 混合啟用和 AWS IAM Roles Anywhere，您可以從混合節點執行下列命令，驗證混合節點 IAM 角色的登入資料是否已在您的混合節點上正確設定。確認節點名稱和混合節點 IAM 角色名稱與您的預期相符。

```
sudo aws sts get-caller-identity
```

```
{
    "UserId": "ABCDEFGHIJKLM12345678910:<node-name>",
    "Account": "<aws-account-id>",
    "Arn": "arn:aws: sts::<aws-account-id>:assumed-role/<hybrid-nodes-iam-role/<node-name>"
}
```

 ** AWS Systems Manager (SSM) 故障診斷** 

如果您針對混合節點登入資料使用 AWS SSM 混合啟用，請注意 安裝在混合節點上的下列 SSM 目錄和成品`nodeadm`。如需 SSM 代理程式的詳細資訊，請參閱 * AWS Systems Manager 使用者指南*中的[使用 SSM 代理程式](https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-agent.html)。


| Description | Location | 
| --- | --- | 
|  SSM 代理程式  |  Ubuntu - `/snap/amazon-ssm-agent/current/amazon-ssm-agent` RHEL 和 AL2023 - `/usr/bin/amazon-ssm-agent`   | 
|  SSM 代理程式日誌  |   `/var/log/amazon/ssm`   | 
|   AWS 登入資料  |   `/root/.aws/credentials`   | 
|  SSM Setup CLI  |   `/opt/ssm/ssm-setup-cli`   | 

 **重新啟動 SSM 代理程式** 

重新啟動 SSM 代理程式即可解決某些問題。您可以使用以下命令來重新啟動。

 **AL2023 和其他作業系統** 

```
systemctl restart amazon-ssm-agent
```

 **Ubuntu** 

```
systemctl restart snap.amazon-ssm-agent.amazon-ssm-agent
```

 **檢查 SSM 端點的連線** 

確認您可以從混合節點連接至 SSM 端點。如需 SSM 端點的清單，請參閱 [AWS Systems Manager 端點和配額](https://docs.aws.amazon.com/general/latest/gr/ssm.html)。將以下命令`us-west-2`中的 取代為 AWS SSM 混合啟用 AWS 的區域。

```
ping ssm.us-west-2.amazonaws.com
```

 **檢視已註冊的 SSM 執行個體的連線狀態** 

您可以使用下列 CLI 命令，檢查已向 SSM AWS 混合啟用註冊之執行個體的連線狀態。使用您執行個體的機器 ID 取代機器 ID。

```
aws ssm get-connection-status --target mi-012345678abcdefgh
```

 **SSM Setup CLI 檢查總和不相符** 

執行 `nodeadm install` 時，如果您看到 `ssm-setup-cli` 檢查總和不相符的問題，則您應該確認主機上的現有 SSM 安裝並非較舊版本。如果您的主機上有較舊的 SSM 安裝，則請將其移除並重新執行 `nodeadm install`，以解決問題。

```
Failed to perform agent-installation/on-prem registration: error while verifying installed ssm-setup-cli checksum: checksum mismatch with latest ssm-setup-cli.
```

 **SSM `InvalidActivation` ** 

如果您看到向 AWS SSM 註冊執行個體時發生錯誤，請確認 `activationId`中的 `activationCode`、 `region`和 `nodeConfig.yaml` 正確無誤。EKS 叢集 AWS 的區域必須符合 SSM 混合啟用的區域。如果這些值設定錯誤，您可能會看到類似如下的錯誤。

```
ERROR Registration failed due to error registering the instance with AWS SSM. InvalidActivation
```

 **SSM `ExpiredTokenException`：包含在​請求中的安全性權杖已過期** 

如果 SSM 代理程式無法重新整理憑證，您可能會看到 `ExpiredTokenException`。在這種情況下，如果您能夠從混合節點連接至 SSM 端點，您可能需要重新啟動 SSM 代理程式，以強制執行憑證重新整理。

```
"msg":"Command failed","error":"operation error SSM: DescribeInstanceInformation, https response error StatusCode: 400, RequestID: eee03a9e-f7cc-470a-9647-73d47e4cf0be, api error ExpiredTokenException: The security token included in the request is expired"
```

 **執行 register machine 命令時發生 SSM 錯誤** 

如果您發現向 SSM 註冊機器時出現錯誤，您可能需要重新執行 `nodeadm install`，以確保已正確安裝所有 SSM 相依性。

```
"error":"running register machine command: , error: fork/exec /opt/aws/ssm-setup-cli: no such file or directory"
```

 **SSM `ActivationExpired` ** 

執行 `nodeadm init` 時，如果您發現因為過期的啟用而向 SSM 註冊執行個體發生錯誤，您需要建立新的 SSM 混合啟用、使用新的 SSM 混合啟用的 `activationCode` 和 `activationId` 更新 `nodeConfig.yaml`，並重新執行 `nodeadm init`。

```
"msg":"Command failed","error":"SSM activation expired. Please use a valid activation"
```

```
ERROR Registration failed due to error registering the instance with AWS SSM. ActivationExpired
```

 **SSM 無法重新整理快取的憑證** 

如果您發現重新整理快取的憑證失敗，`/root/.aws/credentials` 檔案可能已從您的主機上刪除。首先檢查您的 SSM 混合啟用，並確保其處於作用中狀態，且您的混合節點已正確設定為使用啟用。檢查位於 `/var/log/amazon/ssm` 的 SSM 代理程式日誌，並在 SSM 端解決問題後重新執行 `nodeadm init` 命令。

```
"Command failed","error":"operation error SSM: DescribeInstanceInformation, get identity: get credentials: failed to refresh cached credentials"
```

 **清除 SSM** 

若要從主機移除 SSM 代理程式，您可以執行下列命令。

```
dnf remove -y amazon-ssm-agent
sudo apt remove --purge amazon-ssm-agent
snap remove amazon-ssm-agent
rm -rf /var/lib/amazon/ssm/Vault/Store/RegistrationKey
```

 ** AWS IAM Roles Anywhere 故障診斷** 

如果您將 AWS IAM Roles Anywhere 用於混合節點憑證，請注意 安裝在混合節點上的下列目錄和成品`nodeadm`。如需故障診斷 IAM Roles Anywhere 的詳細資訊，請參閱《[IAM Roles Anywhere AWS 使用者指南》中的故障診斷 IAM Roles Anywhere 身分和存取權](https://docs.aws.amazon.com/rolesanywhere/latest/userguide/security_iam_troubleshoot.html)。 * AWS *


| Description | Location | 
| --- | --- | 
|  IAM Roles Anywhere CLI  |   `/usr/local/bin/aws_signing_helper`   | 
|  預設憑證位置和名稱  |   `/etc/iam/pki/server.pem`   | 
|  預設金鑰位置和名稱  |   `/etc/iam/pki/server.key`   | 

 **IAM Roles Anywhere 無法重新整理快取的憑證** 

如果您發現重新整理快取的憑證失敗，請檢閱 `/etc/aws/hybrid/config` 的內容，並確認已正確設定 `nodeadm` 組態中的 IAM Roles Anywhere。確認存在 `/etc/iam/pki`。每個節點都必須有唯一的憑證和金鑰。根據預設，使用 IAM Roles Anywhere 作為憑證提供者時，`nodeadm` 會將 `/etc/iam/pki/server.pem` 用於憑證位置和名稱，以及將 `/etc/iam/pki/server.key` 用於私有金鑰。您可能需要先建立目錄，然後再將憑證和金鑰放入具有 `sudo mkdir -p /etc/iam/pki` 的目錄中。您可以使用以下命令來驗證憑證的內容。

```
openssl x509 -text -noout -in server.pem
```

```
open /etc/iam/pki/server.pem: no such file or directory
could not parse PEM data
Command failed {"error": "... get identity: get credentials: failed to refresh cached credentials, process provider error: error in credential_process: exit status 1"}
```

 **IAM Roles Anywhere 未獲授權執行 `sts:AssumeRole` ** 

在 `kubelet` 日誌中，如果您在使用 IAM Roles Anywhere 時發現 `sts:AssumeRole` 操作的存取遭拒問題，請檢查混合節點 IAM 角色的信任政策，以確認允許 IAM Roles Anywhere 服務主體擔任混合節點 IAM 角色。此外，請確認您的混合節點 IAM 角色信任政策中已正確設定信任錨 ARN，並且您的混合節點 IAM 角色已新增至您的 IAM Roles Anywhere 設定檔。

```
could not get token: AccessDenied: User: ... is not authorized to perform: sts:AssumeRole on resource: ...
```

 **IAM Roles Anywhere 未獲授權設定 `roleSessionName` ** 

在 `kubelet` 日誌中，如果您發現設定 `roleSessionName` 時出現存取遭拒問題，請確認您已為 IAM Roles Anywhere 設定檔將 `acceptRoleSessionName` 設為 true。

```
AccessDeniedException: Not authorized to set roleSessionName
```

## 作業系統故障診斷
<a name="hybrid-nodes-troubleshooting-os"></a>

### RHEL
<a name="_rhel"></a>

 **權利或訂閱管理員註冊失敗** 

如果您正在執行 `nodeadm install`，且由於權利註冊問題而無法安裝混合節點相依性，則請確保您已在主機上正確設定您的 Red Hat 使用者名稱和密碼。

```
This system is not registered with an entitlement server
```

### Ubuntu
<a name="_ubuntu"></a>

 **找不到 GLIBC** 

如果您將 Ubuntu 用於作業系統，並將 IAM Roles Anywhere 用作具有混合節點的憑證提供者，同時還發現找不到 GLIBC 的問題，則您可以手動安裝該相依性，進而解決問題。

```
GLIBC_2.32 not found (required by /usr/local/bin/aws_signing_helper)
```

執行下列命令以安裝相依性：

```
ldd --version
sudo apt update && apt install libc6
sudo apt install glibc-source
```

### Bottlerocket
<a name="_bottlerocket"></a>

如果您已啟用 Bottlerocket 管理員容器，則可使用 SSH 來進行存取，以利用更高的權限進行進階偵錯和故障診斷。下列各節包含需要在 Bottlerocket 主機環境中執行的命令。進入管理員容器後，您可以執行 `sheltie`，以取得 Bottlerocket 主機中的完整根 shell。

```
sheltie
```

您也可以在每個命令前加上字首 `sudo chroot /.bottlerocket/rootfs`，進而從管理員容器 Shell 的下列區段中執行命令。

```
sudo chroot /.bottlerocket/rootfs <command>
```

 **使用 logdog 進行日誌收集** 

Bottlerocket 提供 `logdog` 公用程式來高效收集日誌和系統資訊，進而供故障診斷之用。

```
logdog
```

`logdog` 公用程式會從 Bottlerocket 主機上的不同位置收集日誌，並將其合併為 tarball。根據預設，tarball 會在 `/var/log/support/bottlerocket-logs.tar.gz` 中建立，並且可從 `/.bottlerocket/support/bottlerocket-logs.tar.gz` 的託管容器存取。

 **使用 journalctl 存取系統日誌** 

您可以使用下列命令檢查各種系統服務的狀態 (例如 `kubelet`、`containerd` 等等)，並檢視其日誌。`-f` 旗標會即時追蹤日誌。

若要檢查 `kubelet` 服務狀態並擷取 `kubelet` 日誌，您可以執行：

```
systemctl status kubelet
journalctl -u kubelet -f
```

若要檢查 `containerd` 服務狀態並擷取協調的 `containerd` 執行個體的日誌，您可以執行：

```
systemctl status containerd
journalctl -u containerd -f
```

若要檢查 `host-containerd` 服務狀態並擷取主體 `containerd` 執行個體的日誌，您可以執行：

```
systemctl status host-containerd
journalctl -u host-containerd -f
```

如需擷取引導容器和託管容器的日誌，您可以執行：

```
journalctl _COMM=host-ctr -f
```