

 **이 페이지 개선에 도움 주기** 

이 사용자 가이드에 기여하려면 모든 페이지의 오른쪽 창에 있는 **GitHub에서 이 페이지 편집** 링크를 선택합니다.

# Amazon EKS Hybrid Nodes 개요
<a name="hybrid-nodes-overview"></a>

*Amazon EKS Hybrid Nodes*를 사용하면 온프레미스 및 엣지 인프라를 Amazon EKS 클러스터의 노드로 사용할 수 있습니다. AWS는 Amazon EKS 클러스터의 AWS 호스팅 Kubernetes 컨트롤 플레인을 관리하고 온프레미스 또는 엣지 환경에서 실행되는 하이브리드 노드를 관리합니다. 이를 통해 환경 전반의 Kubernetes 관리를 통합하고 온프레미스 및 엣지 애플리케이션을 위해 Kubernetes 컨트롤 플레인 관리를 AWS로 오프로드합니다.

Amazon EKS Hybrid Nodes는 모든 온프레미스 하드웨어 또는 가상 머신과 함께 작동하여 애플리케이션이 실행되어야 하는 모든 곳에 Amazon EKS의 효율성, 확장성, 가용성을 제공합니다. Amazon EKS 추가 기능, Amazon EKS Pod Identity, 클러스터 액세스 항목, 클러스터 인사이트, 확장된 Kubernetes 버전 지원을 포함하여 Amazon EKS Hybrid Nodes와 함께 다양한 Amazon EKS 기능을 사용할 수 있습니다. Amazon EKS Hybrid Nodes는 중앙 집중식 모니터링, 로깅, ID 관리를 위해 AWS Systems Manager, AWS IAM Roles Anywhere, Amazon Managed Service for Prometheus, Amazon CloudWatch를 포함한 AWS 서비스와 기본적으로 통합됩니다.

Amazon EKS Hybrid Nodes를 사용하면 선결제 약정이나 최소 요금이 없으며, Amazon EKS 클러스터에 연결될 때 하이브리드 노드의 vCPU 리소스에 대해 시간당 요금이 부과됩니다. 가격에 대한 자세한 내용은 [Amazon EKS Pricing](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)


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

EKS Hybrid Nodes에는 다음과 같은 상위 수준 기능이 있습니다.
+  **관리형 Kubernetes 컨트롤 플레인**: AWS는 EKS 클러스터의 AWS 호스팅 Kubernetes 컨트롤 플레인을 관리하고 사용자는 온프레미스 또는 엣지 환경에서 실행되는 하이브리드 노드를 관리합니다. 이를 통해 환경 전반의 Kubernetes 관리를 통합하고 온프레미스 및 엣지 애플리케이션을 위해 Kubernetes 컨트롤 플레인 관리를 AWS로 오프로드합니다. Kubernetes 컨트롤 플레인을 AWS로 이동하면 애플리케이션의 온프레미스 용량을 절약하고 Kubernetes 컨트롤 플레인이 워크로드에 따라 확장된다고 신뢰할 수 있습니다.
+  **일관된 EKS 경험**: 온프레미스 및 클라우드 환경에서 일관된 EKS 경험을 위해 EKS 추가 기능, EKS Pod Identity, 클러스터 액세스 항목, 클러스터 인사이트, 확장된 Kubernetes 버전 지원 등 대부분의 EKS 기능이 EKS Hybrid Nodes에서 지원됩니다. EKS Hybrid Nodes에서 지원되는 EKS 추가 기능에 대한 자세한 내용은 [하이브리드 노드에 대한 추가 기능 구성](hybrid-nodes-add-ons.md) 섹션을 참조하세요.
+  **중앙 집중식 관찰성 및 ID 관리**: EKS Hybrid Nodes는 중앙 집중식 모니터링, 로깅, ID 관리를 위해 AWS Systems Manager, AWS IAM Roles Anywhere, Amazon Managed Service for Prometheus, Amazon CloudWatch, Amazon GuardDuty를 포함한 AWS 서비스와 기본적으로 통합됩니다.
+  **클라우드로 버스트 또는 온프레미스 용량 추가**: 단일 EKS 클러스터를 사용하여 AWS 리전, AWS 로컬 영역 또는 AWS Outposts에서 하이브리드 노드 및 노드를 실행하여 클라우드로 버스트하거나 EKS 클러스터에 온프레미스 용량을 추가할 수 있습니다. 자세한 내용은 [혼합 모드 클러스터 고려 사항](hybrid-nodes-webhooks.md#hybrid-nodes-considerations-mixed-mode)을 참조하세요.
+  **유연한 인프라**: EKS Hybrid Nodes는 *자체 인프라 사용* 접근 방식을 따르며 하이브리드 노드에 사용하는 인프라에 구애받지 않습니다. 물리적 또는 가상 머신과 x86 및 ARM 아키텍처에서 하이브리드 노드를 실행할 수 있으므로 다양한 인프라 유형의 하이브리드 노드에서 실행되는 온프레미스 워크로드를 마이그레이션할 수 있습니다.
+  **유연한 네트워킹**: EKS Hybrid Nodes에서는 EKS 컨트롤 플레인과 하이브리드 노드 간의 통신이 클러스터 생성 중에 전달하는 VPC 및 서브넷을 통해 라우팅되며, 이는 컨트롤 플레인-노드 네트워킹을 위한 EKS의 [기존 메커니즘](https://docs.aws.amazon.com/eks/latest/best-practices/subnets.html)을 기반으로 합니다. 이는 온프레미스 네트워크를 AWS의 VPC에 연결하는 기본 방법에 유연성을 제공합니다. AWS Site-to-Site VPN, AWS Direct Connect, 자체 VPN 솔루션을 포함하여 몇 가지 [문서화된 옵션](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/network-to-amazon-vpc-connectivity-options.html)을 사용하고 사용 사례에 가장 적합한 방법을 선택할 수 있습니다.

## Limits
<a name="hybrid-node-limits"></a>
+ 클러스터당 최대 15개의 원격 노드 네트워크 CIDR과 최대 15개의 원격 포드 네트워크 CIDR이 지원됩니다.

## 고려 사항
<a name="hybrid-nodes-general"></a>
+ EKS Hybrid Nodes는 신규 또는 기존 EKS 클러스터와 함께 사용할 수 있습니다.
+ EKS Hybrid Nodes는 AWS GovCloud(미국) 리전 및 AWS 중국 리전을 제외한 모든 AWS 리전에서 사용할 수 있습니다.
+ EKS Hybrid Nodes에는 온프레미스 환경과 AWS 간에 신뢰할 수 있는 연결이 있어야 합니다. EKS Hybrid Nodes는 연결 해제, 중단, 간헐적 또는 제한된(DDIL) 환경에 적합하지 않습니다. DDIL 환경에서 실행하는 경우 [Amazon EKS Anywhere](https://aws.amazon.com/eks/eks-anywhere/)를 고려하세요. 네트워크 연결 해제 시나리오 중 하이브리드 노드 작동 방식에 대한 자세한 내용은 [EKS Hybrid Nodes 모범 사례](https://docs.aws.amazon.com/eks/latest/best-practices/hybrid-nodes-network-disconnections.html)를 참조하세요.
+ AWS 리전, AWS 로컬 영역, AWS Outposts를 포함한 클라우드 인프라 또는 다른 클라우드에서 EKS Hybrid Nodes를 실행하는 것은 지원되지 않습니다. 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): EKS Hybrid Nodes 출시를 소개하는 AWS re:Inven 세션입니다. 고객이 자신의 환경에서 EKS Hybrid Nodes를 어떻게 사용하고 있는지 보여줍니다.
+  [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 Hybrid Nodes용 네트워킹을 설정하는 다양한 방법을 설명하는 문서입니다.
+  [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 Hybrid Nodes를 사용하여 환경 전반에서 GenAI 추론을 실행하는 방법을 보여주는 블로그 게시물입니다.

# 하이브리드 노드에 대한 사전 조건 설정
<a name="hybrid-nodes-prereqs"></a>

Amazon EKS Hybrid Nodes를 사용하려면 온프레미스 환경에서 지원되는 운영 체제가 있는 AWS, 베어 메탈 서버 또는 가상 머신으로의 프라이빗 연결과 AWS IAM Roles Anywhere 또는 AWS Systems Manager(SSM) 하이브리드 활성화가 구성되어 있어야 합니다. 하이브리드 노드 수명 주기 전반에 걸쳐 이러한 사전 조건을 관리할 책임은 사용자에게 있습니다.
+ 온프레미스 환경과 AWS 간의 하이브리드 네트워크 연결 
+ 물리적 또는 가상 머신 형태의 인프라
+ 하이브리드 노드와 호환되는 운영 체제
+ 구성된 온프레미스 IAM 자격 증명 공급자

![\[하이브리드 노드 네트워크 연결.\]](http://docs.aws.amazon.com/ko_kr/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/)을 기반으로 합니다. AWS Site-to-Site VPN, AWS Direct Connect 또는 자체 VPN 연결을 포함하여 온프레미스 환경을 VPC와 연결하는 데 사용할 수 있는 몇 가지 [문서화된 옵션](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/network-to-amazon-vpc-connectivity-options.html)이 있습니다. 하이브리드 네트워크 연결에 이러한 솔루션을 사용하는 방법에 대한 자세한 내용은 [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) 사용 설명서를 참조하세요.

최적의 경험을 위해 AWS 리전의 하이브리드 노드 연결에 최소 100Mbps 및 최대 200ms의 왕복 지연 시간을 제공하는 안정적인 네트워크 연결을 권장합니다. 이는 대부분의 사용 사례에 적용되는 일반적인 지침이지만 엄격한 요구 사항은 아닙니다. 대역폭 및 지연 시간 요구 사항은 하이브리드 노드 수와 애플리케이션 이미지 크기, 애플리케이션 탄력성, 모니터링 및 로깅 구성, 다른 AWS 서비스에 저장된 데이터에 대한 애플리케이션 종속성과 같은 워크로드 특성에 따라 달라질 수 있습니다. 네트워킹 설정이 워크로드의 요구 사항을 충족하는지 확인하려면 프로덕션에 배포하기 전에 자체 애플리케이션 및 환경을 사용하여 테스트하는 것이 좋습니다.

## 온프레미스 네트워크 구성
<a name="hybrid-nodes-prereqs-onprem"></a>

Amazon EKS 컨트롤 플레인에서 온프레미스 환경으로의 인바운드 네트워크 액세스를 활성화해야 Amazon EKS 컨트롤 플레인이 하이브리드 노드에서 실행 중인 `kubelet`와 통신하고, 선택적으로 하이브리드 노드에서 실행 중인 웹후크와 통신할 수 있습니다. 또한 Amazon EKS 컨트롤 플레인과 통신하려면 하이브리드 노드 및 해당 노드에서 실행되는 구성 요소에 대해 아웃바운드 네트워크 액세스를 활성화해야 합니다. AWS Direct Connect, AWS Site-to-Site VPN 또는 자체 VPN 연결에 대해 완전히 비공개로 유지되도록 이 통신을 구성할 수 있습니다.

온프레미스 노드 및 포드 네트워크에 사용하는 CIDR(Classless Inter-Domain Routing) 범위는 IPv4 RFC-1918 또는 CGNAT 주소 범위를 사용해야 합니다. 온프레미스 라우터는 온프레미스 노드와 선택적으로 포드에 대한 경로로 구성되어야 합니다. 방화벽과 온프레미스 환경에서 활성화해야 하는 필수 포트와 프로토콜의 전체 목록을 포함하여 온프레미스 네트워크 요구 사항에 대한 자세한 내용은 [온프레미스 네트워킹 구성](hybrid-nodes-networking.md#hybrid-nodes-networking-on-prem)을 참조하세요.

## EKS 클러스터 구성
<a name="hybrid-nodes-prereqs-cluster"></a>

지연 시간을 최소화하려면 온프레미스 또는 엣지 환경에 가장 가까운 AWS 리전에서 Amazon EKS 클러스터를 생성하는 것이 좋습니다. Amazon EKS 클러스터를 생성하는 동안 온프레미스 노드 및 포드 CIDR을 두 개의 API 필드인 `RemoteNodeNetwork` 및 `RemotePodNetwork`를 통해 전달합니다. 온프레미스 네트워크 팀과 상의하여 온프레미스 노드 및 포드 CIDR을 식별해야 할 수 있습니다. 노드 CIDR은 온프레미스 네트워크에서 할당되고 포드 CIDR은 CNI에 오버레이 네트워크를 사용하는 경우, 사용하는 컨테이너 네트워크 인터페이스(CNI)에서 할당됩니다. Cilium과 Calico는 기본적으로 오버레이 네트워크를 사용합니다.

`RemoteNodeNetwork` 및 `RemotePodNetwork` 필드를 통해 구성하는 온프레미스 노드 및 포드 CIDR은 VPC를 통해 하이브리드 노드에서 실행되는 `kubelet`과 포드로 트래픽을 라우팅하도록 Amazon EKS 컨트롤 플레인을 구성하는 데 사용됩니다. 온프레미스 노드 및 포드 CIDR은 서로, 클러스터 생성 중에 전달하는 VPC CIDR 또는 Amazon EKS 클러스터의 서비스 IPv4 구성과 중첩될 수 없습니다. 또한 온프레미스 라우터가 트래픽을 라우팅할 수 있도록 포드 CIDR이 각 EKS 클러스터에 고유해야 합니다.

Amazon EKS Kubernetes API 서버 엔드포인트에 퍼블릭 또는 프라이빗 엔드포인트 액세스 중 하나를 사용하는 것이 좋습니다. '퍼블릭 및 프라이빗'을 선택하면 Amazon EKS Kubernetes API 서버 엔드포인트가 항상 VPC 외부에서 실행되는 하이브리드 노드의 퍼블릭 IP로 확인되므로 하이브리드 노드가 클러스터에 조인하지 못할 수 있습니다. 퍼블릭 엔드포인트 액세스를 사용하면 Kubernetes API 서버 엔드포인트가 퍼블릭 IP로 확인되고 하이브리드 노드에서 Amazon EKS 컨트롤 플레인으로의 통신이 인터넷을 통해 라우팅됩니다. 프라이빗 엔드포인트 액세스를 선택하면 Kubernetes API 서버 엔드포인트가 프라이빗 IP로 확인되고 하이브리드 노드에서 Amazon EKS 컨트롤 플레인으로의 통신이 프라이빗 연결 링크를 통해 라우팅되며, 대부분의 경우 AWS Direct Connect 또는 AWS Site-to-Site VPN으로 라우팅됩니다.

## VPC 구성
<a name="hybrid-nodes-prereqs-vpc"></a>

온프레미스 노드의 라우팅 테이블에 있는 경로와 선택적으로 가상 프라이빗 게이트웨이(VGW) 또는 전송 게이트웨이(TGW)를 대상으로 하는 포드 네트워크로 Amazon EKS 클러스터 생성 중에 전달하는 VPC를 구성해야 합니다. 예를 들면 다음과 같습니다. `REMOTE_NODE_CIDR` 및 `REMOTE_POD_CIDR`을 온프레미스 네트워크의 값으로 바꿉니다.


| 대상 주소 | 대상 | 설명 | 
| --- | --- | --- | 
|  10.226.0.0/16  |  로컬  |  VPC 내의 VPC 경로에 대한 로컬 트래픽  | 
|  REMOTE\$1NODE\$1CIDR  |  tgw-abcdef123456  |  온프레미스 노드 CIDR, 트래픽을 TGW로 라우팅  | 
|  REMODE\$1POD\$1CIDR  |  tgw-abcdef123456  |  온프레미스 포드 CIDR, 트래픽을 TGW로 라우팅  | 

## 보안 그룹 구성
<a name="hybrid-nodes-prereqs-sg"></a>

클러스터를 생성할 때 Amazon EKS에서 `eks-cluster-sg-<cluster-name>-<uniqueID>`라는 보안 그룹을 만듭니다. 이 클러스터 보안 그룹의 인바운드 규칙은 변경할 수 없지만 아웃바운드 규칙을 제한할 수 있습니다. 하이브리드 노드에서 실행되는 kubelet와 선택적으로 웹후크가 Amazon EKS 컨트롤 플레인에 연결할 수 있게 하려면 클러스터에 보안 그룹을 추가해야 합니다. 이 추가 보안 그룹에 필요한 인바운드 규칙은 다음과 같습니다. `REMOTE_NODE_CIDR` 및 `REMOTE_POD_CIDR`을 온프레미스 네트워크의 값으로 바꿉니다.


| 이름 | 보안 그룹 규칙 ID | IP 버전 | Type | 프로토콜 | 포트 범위 | 소스 | 
| --- | --- | --- | --- | --- | --- | --- | 
|  온프레미스 노드 인바운드  |  sgr-abcdef123456  |  IPv4  |  HTTPS  |  TCP  |  443  |  REMOTE\$1NODE\$1CIDR  | 
|  온프레미스 포드 인바운드  |  sgr-abcdef654321  |  IPv4  |  HTTPS  |  TCP  |  443  |  REMOTE\$1POD\$1CIDR  | 

## 인프라
<a name="hybrid-nodes-prereqs-infra"></a>

하이브리드 노드로 사용할 수 있는 베어 메탈 서버 또는 가상 머신이 있어야 합니다. 하이브리드 노드는 기본 인프라에 구애받지 않으며 x86 및 ARM 아키텍처를 지원합니다. Amazon EKS Hybrid Nodes는 '자체 인프라 구축' 접근 방식을 따르며, 이 방식에서 하이브리드 노드에 사용하는 베어 메탈 서버 또는 가상 머신의 프로비저닝 및 관리는 사용자의 책임입니다. 엄격한 최소 리소스 요구 사항은 없지만 하이브리드 노드에 대해 최소 1개의 vCPU 및 1GiB RAM이 있는 호스트를 사용하는 것이 좋습니다.

## 운영 체제
<a name="hybrid-nodes-prereqs-os"></a>

Bottlerocket, Amazon Linux 2023(AL2023), Ubuntu 및 RHEL은 하이브리드 노드의 노드 운영 체제로 사용하기 위해 지속적으로 검증됩니다. Bottlerocket은 VMware vSphere 환경에서만 AWS에서 지원됩니다. AL2023은 Amazon EC2 외부에서 실행되는 경우 AWS 지원 플랜의 적용을 받지 않습니다. AL2023은 온프레미스 가상화 환경에서만 사용할 수 있습니다. 자세한 내용은 [Amazon Linux 2023 사용 설명서](https://docs.aws.amazon.com/linux/al2023/ug/outside-ec2.html)를 참조하세요. AWS는 Ubuntu 및 RHEL 운영 체제와의 하이브리드 노드 통합을 지원하지만 운영 체제 자체에 대한 지원은 제공하지 않습니다.

운영 체제 프로비저닝 및 관리는 사용자의 책임입니다. 하이브리드 노드를 처음 테스트하는 경우 이미 프로비저닝된 호스트에서 Amazon EKS Hybrid Nodes CLI(`nodeadm`)를 실행하는 것이 가장 쉽습니다. 프로덕션 배포의 경우 호스트 시작 시 호스트를 Amazon EKS 클러스터에 자동으로 조인하기 위해 systemd 서비스로 실행되도록 구성된 `nodeadm`을 골든 운영 체제 이미지에 포함하는 것이 좋습니다.

## 온프레미스 IAM 자격 증명 공급자
<a name="hybrid-nodes-prereqs-iam"></a>

Amazon EKS Hybrid Nodes는 AWS SSM 하이브리드 활성화 또는 AWS IAM Roles Anywhere에서 프로비저닝한 임시 IAM 자격 증명을 사용하여 Amazon EKS 클러스터로 인증합니다. Amazon EKS Hybrid Nodes CLI(`nodeadm`)와 함께 AWS SSM 하이브리드 활성화 또는 AWS IAM Roles Anywhere를 사용해야 합니다. 인증 기관(CA)이 있는 기존 퍼블릭 키 인프라(PKI)와 온프레미스 환경에 대한 인증서가 없는 경우 AWS SSM 하이브리드 활성화를 사용하는 것이 좋습니다. 온프레미스에 기존 PKI 및 인증서가 있는 경우 AWS IAM Roles Anywhere를 사용합니다.

Amazon EC2에서 실행되는 노드의 [Amazon EKS 노드 IAM 역할](create-node-role.md)과 마찬가지로 하이브리드 노드를 Amazon EKS 클러스터에 조인하는 데 필요한 권한이 있는 하이브리드 노드 IAM 역할을 생성합니다. AWS IAM Roles Anywhere를 사용하는 경우 AWS IAM Roles Anywhere가 하이브리드 노드 IAM 역할을 수임하고 하이브리드 노드 IAM 역할을 수임 가능한 역할로 사용하여 AWS 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/ko_kr/eks/latest/userguide/images/hybrid-prereq-diagram.png)


## 온프레미스 네트워킹 구성
<a name="hybrid-nodes-networking-on-prem"></a>

### 최소 네트워크 요구 사항
<a name="hybrid-nodes-networking-min-reqs"></a>

최적의 경험을 위해 AWS 리전의 하이브리드 노드 연결에 최소 100Mbps 및 최대 200ms의 왕복 지연 시간을 제공하는 안정적인 네트워크 연결을 권장합니다. 이는 대부분의 사용 사례에 적용되는 일반적인 지침이지만 엄격한 요구 사항은 아닙니다. 대역폭 및 지연 시간 요구 사항은 하이브리드 노드 수와 애플리케이션 이미지 크기, 애플리케이션 탄력성, 모니터링 및 로깅 구성, 다른 AWS 서비스에 저장된 데이터에 대한 애플리케이션 종속성과 같은 워크로드 특성에 따라 달라질 수 있습니다. 네트워킹 설정이 워크로드의 요구 사항을 충족하는지 확인하려면 프로덕션에 배포하기 전에 자체 애플리케이션 및 환경을 사용하여 테스트하는 것이 좋습니다.

### 온프레미스 노드 및 포드 CIDR
<a name="hybrid-nodes-networking-on-prem-cidrs"></a>

하이브리드 노드에 사용할 노드 및 포드 CIDR과 해당 노드에서 실행되는 워크로드를 식별합니다. 노드 CIDR은 온프레미스 네트워크에서 할당되고 포드 CIDR은 CNI에 오버레이 네트워크를 사용하는 경우 컨테이너 네트워크 인터페이스(CNI)에서 할당됩니다. `RemoteNodeNetwork` 및 `RemotePodNetwork` 필드를 사용하여 EKS 클러스터를 생성할 때 온프레미스 노드 CIDR과 포드 CIDR을 입력으로 전달합니다. 온프레미스 노드 CIDR은 온프레미스 네트워크에서 라우팅 가능해야 합니다. 온프레미스 포드 CIDR 라우팅 가능성에 대한 자세한 내용은 다음 섹션을 참조하세요.

온프레미스 노드 및 포드 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 서비스 `IPv4` CIDR과 중첩되지 않습니다.

### 온프레미스 포드 네트워크 라우팅
<a name="hybrid-nodes-networking-on-prem-pod-routing"></a>

EKS Hybrid Nodes를 사용할 때 일반적으로 클라우드와 온프레미스 환경 간에 완전한 클러스터 통신 및 기능을 사용할 수 있도록 온프레미스 네트워크에서 온프레미스 포드 CIDR을 라우팅할 수 있게 만드는 것이 좋습니다.

 **라우팅 가능한 포드 네트워크** 

온프레미스 네트워크에서 포드 네트워크를 라우팅할 수 있게 만들 수 있는 경우 아래 지침을 따르세요.

1. 온프레미스 포드 CIDR을 사용하여 EKS 클러스터의 `RemotePodNetwork` 필드를 구성하고, 온프레미스 포드 CIDR을 사용하여 VPC 라우팅 테이블을 구성하고, 온프레미스 포드 CIDR을 사용하여 EKS 클러스터 보안 그룹을 구성합니다.

1. Border Gateway Protocol(BGP), 정적 경로 또는 기타 사용자 지정 라우팅 솔루션을 포함하여 온프레미스 네트워크에서 온프레미스 포드 CIDR을 라우팅 가능하도록 하는 데 몇 가지 기법을 사용할 수 있습니다. BGP는 사용자 지정 또는 수동 라우팅 구성이 필요한 대체 솔루션보다 더 확장성이 뛰어나고 관리하기 쉽기 때문에 권장되는 솔루션입니다. AWS는 포드 CIDR을 알리는 데 Cilium 및 Calico의 BGP 기능을 지원합니다. 자세한 내용은 [하이브리드 노드에 대한 CNI 구성](hybrid-nodes-cni.md) 및 [라우팅 가능한 원격 포드 CIDR](hybrid-nodes-concepts-kubernetes.md#hybrid-nodes-concepts-k8s-pod-cidrs) 섹션을 참조하세요.

1. EKS 컨트롤 플레인이 웹후크에 할당된 포드 IP 주소와 통신할 수 있으므로 웹후크가 하이브리드 노드에서 실행될 수 있습니다.

1. 클라우드 노드에서 실행되는 워크로드는 동일한 EKS 클러스터의 하이브리드 노드에서 실행되는 워크로드와 직접 통신할 수 있습니다.

1. AWS Application Load Balancer, Amazon Managed Service for Prometheus 등의 다른 AWS 서비스는 하이브리드 노드에서 실행되는 워크로드와 통신하여 네트워크 트래픽의 균형을 맞추고 포드 지표를 스크래핑할 수 있습니다.

 **라우팅 불가능한 포드 네트워크** 

온프레미스 네트워크에서 포드 네트워크를 라우팅할 수 있게 만들 수 *없는* 경우 아래 지침을 따르세요.

1. 웹후크는 EKS 컨트롤 플레인에서 웹후크에 할당된 포드 IP 주소로 연결해야 하므로 하이브리드 노드에서 웹후크를 실행할 수 없습니다. 이 경우 하이브리드 노드와 동일한 EKS 클러스터의 클라우드 노드에서 웹후크를 실행하는 것이 좋습니다. 자세한 내용은 [하이브리드 노드용 웹후크 구성](hybrid-nodes-webhooks.md)을 참조하세요.

1. 클라우드 노드에서 실행되는 워크로드는 클라우드 노드에 VPC CNI를 사용하고 하이브리드 노드에 Cilium이나 Calico를 사용할 때 하이브리드 노드에서 실행되는 워크로드와 직접 통신할 수 없습니다.

1. 서비스 트래픽 분산을 사용하여 트래픽이 시작되는 영역에 트래픽을 로컬로 유지합니다. 서비스 트래픽 분산에 대한 자세한 내용은 [서비스 트래픽 분산 구성](hybrid-nodes-webhooks.md#hybrid-nodes-mixed-service-traffic-distribution)을 참조하세요.

1. 온프레미스 호스트를 떠나는 포드 트래픽에 대해 송신 매스커레이드 또는 네트워크 주소 변환(NAT)을 사용하도록 CNI를 구성합니다. 이 기능은 Cilium에서 기본적으로 활성화되어 있습니다. Calico에서는 `natOutgoing`을 `true`로 설정해야 합니다.

1. AWS Application Load Balancer, Amazon Managed Service for Prometheus 등의 다른 AWS 서비스는 하이브리드 노드에서 실행되는 워크로드와 통신할 수 없습니다.

### 하이브리드 노드 설치 및 업그레이드 중에 필요한 액세스
<a name="hybrid-nodes-networking-access-reqs"></a>

호스트에 하이브리드 노드 종속성을 설치하는 설치 프로세스 중에 다음 도메인에 액세스할 수 있어야 합니다. 이 프로세스는 운영 체제 이미지를 빌드할 때 한 번 수행하거나 런타임 시 각 호스트에서 수행할 수 있습니다. 여기에는 초기 설치와 하이브리드 노드의 Kubernetes 버전을 업그레이드할 때도 포함됩니다.

일부 패키지는 OS의 기본 패키지 관리자를 사용하여 설치됩니다. 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  | 
|  운영 체제 패키지 관리자 엔드포인트  |  패키지 리포지토리 엔드포인트는 OS별로 다르며 지리적 리전에 따라 다를 수 있습니다.  |  HTTPS  |  443  | 

**참고**  
 1 AWS SSM 엔드포인트에 대한 액세스는 온프레미스 IAM 자격 증명 공급자에 AWS SSM 하이브리드 활성화를 사용하는 경우에만 필요합니다.  
 2 AWS IAM 엔드포인트에 대한 액세스는 온프레미스 IAM 자격 증명 공급자에 AWS IAM Roles Anywhere를 사용하는 경우에만 필요합니다.

### 지속적인 클러스터 작업에 필요한 액세스
<a name="hybrid-nodes-networking-access-reqs-ongoing"></a>

지속적인 클러스터 작업을 위해서는 온프레미스 방화벽에 대한 다음 네트워크 액세스가 필요합니다.

**중요**  
CNI 선택에 따라 CNI 포트에 대한 추가 네트워크 액세스 규칙을 구성해야 합니다. 자세한 내용은 [Cilium documentation](https://docs.cilium.io/en/stable/operations/system_requirements/#firewall-rules) 및 [Calico documentation](https://docs.tigera.io/calico/latest/getting-started/kubernetes/requirements#network-requirements)를 참조하세요.


| Type | 프로토콜 | Direction | 포트 | 소스 | Destination | 사용법 | 
| --- | --- | --- | --- | --- | --- | --- | 
|  HTTPS  |  TCP  |  아웃바운드  |  443  |  원격 노드 CIDR  |  EKS 클러스터 IP 1   |  kubelet에서 Kubernetes API 서버로  | 
|  HTTPS  |  TCP  |  아웃바운드  |  443  |  원격 포드 CIDR  |  EKS 클러스터 IP 1   |  포드에서 Kubernetes API 서버로  | 
|  HTTPS  |  TCP  |  아웃바운드  |  443  |  원격 노드 CIDR  |   [SSM 서비스 엔드포인트](https://docs.aws.amazon.com/general/latest/gr/ssm.html)   |  5분마다 SSM 하이브리드 활성화 자격 증명 새로 고침 및 SSM 하트비트  | 
|  HTTPS  |  TCP  |  아웃바운드  |  443  |  원격 노드 CIDR  |   [IAM Anywhere 서비스 엔드포인트](https://docs.aws.amazon.com/general/latest/gr/rolesanywhere.html)   |  IAM Roles Anywhere 자격 증명 새로 고침  | 
|  HTTPS  |  TCP  |  아웃바운드  |  443  |  원격 포드 CIDR  |   [STS 리전 엔드포인트](https://docs.aws.amazon.com/general/latest/gr/sts.html)   |  포드에서 STS 엔드포인트로, IRSA에만 필요  | 
|  HTTPS  |  TCP  |  아웃바운드  |  443  |  원격 노드 CIDR  |   [Amazon EKS 인증 서비스 엔드포인트](https://docs.aws.amazon.com/general/latest/gr/eks.html)   |  노드에서 Amazon EKS 인증 엔드포인트로, Amazon EKS Pod Identity에만 필요  | 
|  HTTPS  |  TCP  |  인바운드  |  10250  |  EKS 클러스터 IP 1   |  원격 노드 CIDR  |  Kubernetes API 서버에서 kubelet으로  | 
|  HTTPS  |  TCP  |  인바운드  |  웹후크 포트  |  EKS 클러스터 IP 1   |  원격 포드 CIDR  |  Kubernetes API 서버에서 웹후크로  | 
|  HTTPS  |  TCP, UDP  |  인바운드, 아웃바운드  |  53  |  원격 포드 CIDR  |  원격 포드 CIDR  |  포드와 CoreDNS 간. 클라우드에서 CoreDNS 복제본을 1개 이상 실행하는 경우 CoreDNS가 실행 중인 VPC에 대한 DNS 트래픽을 허용해야 합니다.  | 
|  사용자 정의  |  사용자 정의  |  인바운드, 아웃바운드  |  앱 포트  |  원격 포드 CIDR  |  원격 포드 CIDR  |  포드 간  | 

**참고**  
 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를 사용하여 클러스터를 생성한 후에 찾을 수 있습니다. Kubernetes 버전 업그레이드와 같이 EKS 클러스터에 변경 사항이 적용되면 원래 네트워크 인터페이스가 삭제되고 새 네트워크 인터페이스가 생성됩니다. 클러스터 생성 중에 전달하는 서브넷에 대해 제한된 서브넷 크기를 사용하여 Amazon EKS 네트워크 인터페이스의 IP 범위를 제한할 수 있습니다. 이렇게 하면 알려진 제한된 IP 세트에 대한 인바운드/아웃바운드 연결을 허용하도록 온프레미스 방화벽을 쉽게 구성할 수 있습니다. 네트워크 인터페이스가 생성되는 서브넷을 제어하려면 클러스터를 생성하거나 클러스터를 생성한 후 서브넷을 업데이트할 때 지정하는 서브넷 수를 제한할 수 있습니다.

Amazon EKS에서 프로비저닝한 네트워크 인터페이스에는 `Amazon EKS your-cluster-name ` 형식에 대한 설명이 있습니다. Amazon EKS가 프로비저닝하는 네트워크 인터페이스의 IP 주소를 찾는 데 사용할 수 있는 AWS 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은 온프레미스 노드 및 포드 CIDR과 중첩될 수 없습니다. 온프레미스 노드와 선택적으로 포드 CIDR에 대해 VPC 라우팅 테이블에서 경로를 구성해야 합니다. 이 경로는 일반적으로 가상 프라이빗 게이트웨이(VGW) 또는 전송 게이트웨이(TGW)인 하이브리드 네트워크 연결에 사용 중인 게이트웨이로 트래픽을 라우팅하도록 설정되어야 합니다. TGW 또는 VGW를 사용하여 VPC를 온프레미스 환경에 연결하는 경우 VPC에 대한 TGW 또는 VGW 연결을 생성해야 합니다. VPC는 DNS 호스트 이름과 DNS 확인을 모두 지원해야 합니다.

다음 단계에서는 AWS CLI를 사용합니다. AWS Management Console에서 또는 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 범위로 바꿉니다. 참고: EKS 요구 사항인 DNS 확인은 기본적으로 VPC에 대해 활성화됩니다.

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

1. VPC의 DNS 호스트 이름을 활성화합니다. 참고로 DNS 확인은 기본적으로 VPC에 대해 활성화됩니다. `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는 클러스터 네트워크 인터페이스에 이러한 서브넷을 사용합니다. 자세한 내용은 [Subnets requirements and considerations](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로 바꿉니다. `SUBNET_CIDR`을 서브넷의 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 attachments in Amazon VPC Transit Gateways](https://docs.aws.amazon.com/vpc/latest/tgw/tgw-vpc-attachments.html) 또는 [AWS Direct Connect virtual private gateway associations](https://docs.aws.amazon.com/vpn/latest/s2svpn/how_it_works.html#VPNGateway).를 참조하세요.

 **전송 게이트웨이** 

다음 명령을 실행하여 전송 게이웨이를 연결합니다. `VPC_ID`를 VPC의 ID로 바꿉니다. `SUBNET_ID1` 및 `SUBNET_ID2`를 이전 단계에서 생성한 서브넷의 ID로 바꿉니다. `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
```

 **가상 프라이빗 게이트웨이** 

다음 명령을 실행하여 전송 게이웨이를 연결합니다. `VPN_ID`를 VGW의 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의 기본 라우팅 테이블을 수정하거나 사용자 지정 라우팅 테이블을 생성할 수 있습니다. 다음 단계에서는 온프레미스 노드 및 포드 CIDR에 대한 경로가 포함된 사용자 지정 라우팅 테이블을 생성합니다. 자세한 내용은 [Subnet route tables](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단계: 온프레미스 노드 및 포드에 대한 경로 생성
<a name="_step_5_create_routes_for_on_premises_nodes_and_pods"></a>

각 온프레미스 원격 노드의 라우팅 테이블에서 경로를 생성합니다. VPC의 기본 라우팅 테이블을 수정하거나 이전 단계에서 생성한 사용자 지정 라우팅 테이블을 사용할 수 있습니다.

아래 예제에서는 온프레미스 노드 및 포드 CIDR에 대한 경로를 생성하는 방법을 보여줍니다. 이 예제에서는 전송 게이트웨이(TGW)를 사용하여 VPC를 온프레미스 환경에 연결합니다. 온프레미스 노드와 포드 CIDR이 여러 개인 경우 각 CIDR에 대해 단계를 반복합니다.
+ 인터넷 게이트웨이 또는 가상 프라이빗 게이트웨이(VGW)를 사용하는 경우 `--transit-gateway-id`를 `--gateway-id`로 바꿉니다.
+ `RT_ID`를 이전 단계에서 생성한 라우팅 테이블의 ID로 바꿉니다.
+ `REMOTE_NODE_CIDR`을 하이브리드 노드에 사용할 CIDR 범위로 바꿉니다.
+ `REMOTE_POD_CIDR`을 하이브리드 노드에서 실행되는 포드에 사용할 CIDR 범위로 바꿉니다. 포드 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
```

 **원격 포드 네트워크** 

```
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`를 이전 단계에서 생성한 라우팅 테이블로 바꿉니다. `SUBNET_ID`를 서브넷의 ID로 바꿉니다.

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

## 클러스터 보안 그룹 고려 사항
<a name="hybrid-nodes-networking-cluster-sg"></a>

지속적인 클러스터 작업을 위해서는 EKS 클러스터 보안 그룹에 대한 다음 액세스 권한이 필요합니다. Amazon EKS는 원격 노드 및 포드 네트워크가 구성된 클러스터를 생성하거나 업데이트할 때 하이브리드 노드에 필요한 **인바운드** 보안 그룹 규칙을 자동으로 생성합니다. 보안 그룹은 기본적으로 모든 **아웃바운드** 트래픽을 허용하므로 Amazon EKS는 하이브리드 노드에 대한 클러스터 보안 그룹의 **아웃바운드** 규칙을 자동으로 수정하지 않습니다. 클러스터 보안 그룹을 사용자 지정하려면 다음 표의 규칙으로 트래픽을 제한할 수 있습니다.


| Type | 프로토콜 | Direction | 포트 | 소스 | Destination | 사용법 | 
| --- | --- | --- | --- | --- | --- | --- | 
|  HTTPS  |  TCP  |  인바운드  |  443  |  원격 노드 CIDR  |  해당 사항 없음  |  Kubelet에서 Kubernetes API 서버로  | 
|  HTTPS  |  TCP  |  인바운드  |  443  |  원격 포드 CIDR  |  해당 사항 없음  |  CNI가 포드 트래픽에 NAT를 사용하지 않을 때 K8s API 서버에 대한 액세스가 필요한 포드입니다.  | 
|  HTTPS  |  TCP  |  아웃바운드  |  10250  |  해당 사항 없음  |  원격 노드 CIDR  |  Kubernetes API 서버에서 Kubelet으로  | 
|  HTTPS  |  TCP  |  아웃바운드  |  웹후크 포트  |  해당 사항 없음  |  원격 포드 CIDR  |  Kubernetes API 서버에서 웹후크로(하이브리드 노드에서 웹후크를 실행하는 경우)  | 

**중요**  
 **보안 그룹 규칙 제한**: Amazon EC2 보안 그룹에는 기본적으로 최대 60개의 인바운드 규칙이 있습니다. 클러스터 보안 그룹이 이 제한에 근접하면 보안 그룹 인바운드 규칙이 적용되지 않을 수 있습니다. 이 경우 누락된 인바운드 규칙에 수동으로 추가해야 할 수 있습니다.  
 **CIDR 정리 책임**: EKS 클러스터에서 원격 노드 또는 포드 네트워크를 제거하는 경우 EKS는 해당 보안 그룹 규칙을 자동으로 제거하지 않습니다. 사용자가 직접 보안 그룹 규칙에서 사용하지 않은 원격 노드 또는 포드 네트워크를 수동으로 제거해야 합니다.

Amazon EKS에서 생성하는 클러스터 보안 그룹에 대한 자세한 내용을 알아보려면 [클러스터에 대한 Amazon EKS 보안 그룹 요구 사항 보기](sec-group-reqs.md) 부분을 참조하세요.

### (선택 사항) 수동 보안 그룹 구성
<a name="_optional_manual_security_group_configuration"></a>

추가 보안 그룹을 생성하거나 자동으로 생성된 규칙을 수정해야 하는 경우 다음 명령을 참조로 사용할 수 있습니다. 기본적으로 아래 명령은 모든 아웃바운드 액세스를 허용하는 보안 그룹을 생성합니다. 위의 규칙만 포함하도록 아웃바운드 액세스를 제한할 수 있습니다. 아웃바운드 규칙을 제한하려는 경우 변경된 규칙을 프로덕션 클러스터에 적용하기 전에 모든 애플리케이션 및 포드 연결을 철저히 테스트하는 것이 좋습니다.
+ 첫 번째 명령에서 `SG_NAME`을 보안 그룹의 이름으로 변경
+ 첫 번째 명령에서 `VPC_ID`를 이전 단계에서 생성한 VPC의 ID로 변경
+ 두 번째 명령에서 `SG_ID`를 첫 번째 명령에서 생성한 보안 그룹의 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에서 지원됩니다. AL2023은 Amazon EC2 외부에서 실행되는 경우 AWS 지원 플랜의 적용을 받지 않습니다. AL2023은 온프레미스 가상화 환경에서만 사용할 수 있습니다. 자세한 내용은 [Amazon Linux 2023 사용 설명서](https://docs.aws.amazon.com/linux/al2023/ug/outside-ec2.html)를 참조하세요. AWS는 Ubuntu 및 RHEL 운영 체제와의 하이브리드 노드 통합을 지원하지만 운영 체제 자체에 대한 지원은 제공하지 않습니다.

운영 체제 프로비저닝 및 관리는 사용자의 책임입니다. 하이브리드 노드를 처음 테스트하는 경우 이미 프로비저닝된 호스트에서 Amazon EKS Hybrid Nodes CLI(`nodeadm`)를 실행하는 것이 가장 쉽습니다. 프로덕션 배포의 경우 호스트 시작 시 호스트를 Amazon EKS 클러스터에 자동으로 조인하기 위해 systemd 서비스로 실행되도록 구성된 `nodeadm`을 운영 체제 이미지에 포함하는 것이 좋습니다. Bottlerocket을 vSphere의 노드 운영 체제로 사용하는 경우 Bottlerocket은 하이브리드 노드에 필요한 종속성을 이미 포함하고 호스트 시작 시 구성한 클러스터에 자동으로 연결되므로 `nodeadm`을 사용할 필요가 없습니다.

## 버전 호환성
<a name="_version_compatibility"></a>

아래 표는 하이브리드 노드의 노드 운영 체제로 사용할 수 있도록 호환되고 검증된 운영 체제 버전을 나타냅니다. 이 표에 포함되지 않은 다른 운영 체제 변형 또는 버전을 사용하는 경우 하이브리드 노드와 운영 체제 변형 또는 버전의 호환성은 AWS 지원에 포함되지 않습니다. 하이브리드 노드는 기본 인프라에 구애받지 않으며 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 Hybrid Nodes CLI(`nodeadm`)를 사용하여 하이브리드 노드 구성 요소 및 종속성의 설치 및 구성을 간소화할 수 있습니다. 운영 체제 이미지 빌드 파이프라인 중에 또는 각 온프레미스 호스트의 런타임에 `nodeadm install` 프로세스를 실행할 수 있습니다. `nodeadm`이 설치하는 구성 요소에 대한 자세한 내용은 [하이브리드 노드 `nodeadm` 참조](hybrid-nodes-nodeadm.md) 섹션을 참조하세요.
+ 온프레미스 환경에서 프록시를 사용하여 인터넷에 연결하는 경우 설치 및 업그레이드 프로세스에서 프록시를 사용하도록 패키지 관리자를 구성하기 위해 추가 운영 체제 구성이 필요합니다. 자세한 내용은 [하이브리드 노드용 프록시 구성](hybrid-nodes-proxy.md) 섹션을 참조하세요.

### Bottlerocket
<a name="_bottlerocket"></a>
+ Bottlerocket 노드를 연결하는 단계 및 도구는 다른 운영 체제의 단계와 다르며 [하이브리드 노드 연결](hybrid-nodes-join.md)의 단계 대신 [Bottlerocket을 실행하는 하이브리드 노드 연결](hybrid-nodes-bottlerocket.md)에서 별도로 다룹니다.
+ Bottlerocket의 단계에서는 하이브리드 노드 CLI 도구인 `nodeadm`을 사용하지 않습니다.
+ Bottlerocket 버전 v1.37.0 이상의 VMware 변형만 EKS Hybrid Nodes에서 지원됩니다. Bottlerocket의 VMware 변형은 Kubernetes 버전 v1.28 이상에서 사용할 수 있습니다. [다른 Bottlerocket 변형](https://bottlerocket.dev/en/os/1.36.x/concepts/variants)은 하이브리드 노드 운영 체제로 지원되지 않습니다. 참고: Bottlerocket의 VMware 변형은 x86\$164 아키텍처에서만 사용할 수 있습니다.

### Containered
<a name="_containerd"></a>
+ Containerd는 표준 Kubernetes 컨테이너 런타임이며 하이브리드 노드와 모든 Amazon EKS 노드 컴퓨팅 유형에 대한 종속성입니다. Amazon EKS Hybrid Nodes CLI(`nodeadm`)는 `nodeadm install` 프로세스 중에 Containered 설치를 시도합니다. `--containerd-source` 명령줄 옵션을 사용하여 `nodeadm install` 런타임에 Containered 설치를 구성할 수 있습니다. 유효한 옵션은 `none`, `distro`, `docker`입니다. RHEL을 사용하는 경우 `distro`는 유효한 옵션이 아니며 Docker의 리포지토리에서 Containered 빌드를 설치하도록 `nodeadm`을 구성하거나 Containered를 수동으로 설치할 수 있습니다. AL2023 또는 Ubuntu를 사용하는 경우는 `nodeadm`은 기본적으로 운영 체제 배포에서 Containered를 설치합니다. nodeadm이 Containered를 설치하지 않게 하려면 `--containerd-source none` 옵션을 사용합니다.

### Ubuntu
<a name="_ubuntu"></a>
+ Ubuntu 24.04를 사용하는 경우 Containered 버전을 업데이트하거나 포드가 올바르게 종료되게 하는 수정 사항을 채택하도록 AppArmor 구성을 변경해야 할 수 있습니다. [Ubuntu \$12065423](https://bugs.launchpad.net/ubuntu/+source/containerd-app/\+bug/2065423)을 참조하세요. AppArmor 프로필에 변경 사항을 적용하려면 재부팅해야 합니다. 최신 버전의 Ubuntu 24.04에는 패키지 관리자에 수정 사항이 포함되어 업데이트된 Containered 버전이 있습니다(Containered 버전 1.7.19 이상).

### ARM
<a name="_arm"></a>
+ ARM 하드웨어를 사용하는 경우 EKS kube-proxy 추가 기능 버전 1.31 이상을 실행하려면 Cryptography Extension(ARMv8.2\$1crypto)이 포함된 ARMv8.2 호환 프로세서가 필요합니다. Raspberry Pi 5 이전의 모든 Raspberry Pi 시스템과 Cortex-A72 기반 프로세서는 이 요구 사항을 충족하지 않습니다. 해결 방법으로 2026년 7월에 확장 지원이 종료될 때까지 EKS kube-proxy 추가 기능 1.30 버전을 계속 사용하거나, [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`을 포함하는 운영 체제 이미지를 생성할 수 있습니다. 이 프로세스는 각 호스트에서 하이브리드 노드 종속성을 개별적으로 가져오지 않도록 하고 하이브리드 노드 부트스트랩 프로세스를 자동화하기 위해 권장됩니다. Packer 템플릿 예제를 Ubuntu 22.04, Ubuntu 24.04, RHEL 8 또는 RHEL 9 ISO 이미지와 함께 사용하고 OVA, Qcow2 또는 원시 형식으로 이미지를 출력할 수 있습니다.

### 사전 조건
<a name="_prerequisites"></a>

Packer 템플릿 예제를 사용하기 전에 Packer를 실행 중인 시스템에 다음이 설치되어 있어야 합니다.
+ Packer 버전 1.11.0 이상. Packer 설치에 대한 지침은 Packer 설명서에서 [Install 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  |  문자열  |  Packer는 `ssh_username` 및 `ssh_password` 변수를 사용하여 프로비저닝 시 생성된 시스템으로 SSH를 적용합니다. 이는 각 OS의 시작 또는 사용자 데이터 파일 내에서 초기 사용자를 생성하는 데 사용되는 암호와 일치해야 합니다. 기본값은 OS에 따라 '빌더' 또는 'ubuntu'로 설정됩니다. 암호를 설정할 때 일치하는 해당 `ks.cfg` 또는 `user-data` 파일 내에서 암호를 변경해야 합니다.  | 
|  ISO\$1URL  |  문자열  |  사용할 ISO의 URL입니다. 서버에서 다운로드할 웹 링크 또는 로컬 파일의 절대 경로일 수 있습니다.  | 
|  ISO\$1CHECKSUM  |  문자열  |  제공된 ISO에 대한 관련 체크섬입니다.  | 
|  CREDENTIAL\$1PROVIDER  |  문자열  |  하이브리드 노드의 자격 증명 공급자입니다. 유효한 값은 SSM 하이브리드 활성화의 경우 `ssm`(기본값), IAM Roles Anywhere의 경우 `iam`입니다.  | 
|  K8S\$1VERSION  |  문자열  |  하이브리드 노드용 Kubernetes 버전(예: `1.31`)입니다. 지원되는 Kubernetes 버전은 [Amazon EKS 지원 버전](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)을 참조하세요.  | 
|  NODEADM\$1ARCH  |  문자열  |  `nodeadm install`용 아키텍처입니다. `amd` 또는 `arm`을 선택합니다.  | 

 **RHEL** 

RHEL을 사용하는 경우 다음 환경 변수를 설정해야 합니다.


| 환경 변수 | Type | 설명 | 
| --- | --- | --- | 
|  RH\$1USERNAME  |  문자열  |  RHEL 구독 관리자 사용자 이름  | 
|  RH\$1PASSWORD  |  문자열  |  RHEL 구독 관리자 암호  | 
|  RHEL\$1VERSION  |  문자열  |  사용 중인 Rhel iso 버전입니다. 유효한 값은 `8` 또는 `9`입니다.  | 

 **Ubuntu** 

Ubuntu별 환경 변수는 필요하지 않습니다.

 **vSphere** 

VMware vSphere OVA를 빌드하는 경우 다음 환경 변수를 설정해야 합니다.


| 환경 변수 | Type | 설명 | 
| --- | --- | --- | 
|  VSPHERE\$1SERVER  |  문자열  |  vSphere 서버 주소  | 
|  VSPHERE\$1USER  |  문자열  |  vSphere 사용자 이름  | 
|  VSPHERE\$1PASSWORD  |  문자열  |  vSphere 암호  | 
|  VSPHERE\$1DATACENTER  |  문자열  |  vSphere 데이터 센터 이름  | 
|  VSPHERE\$1CLUSTER  |  문자열  |  vSphere 클러스터 이름  | 
|  VSPHERE\$1DATASTORE  |  문자열  |  vSphere 데이터 저장소 이름  | 
|  VSPHERE\$1NETWORK  |  문자열  |  vSphere 네트워크 이름  | 
|  VSPHERE\$1OUTPUT\$1FOLDER  |  문자열  |  템플릿의 vSphere 출력 폴더  | 

 **QEMU** 


| 환경 변수 | Type | 설명 | 
| --- | --- | --- | 
|  PACKER\$1OUTPUT\$1FORMAT  |  문자열  |  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의 이미지를 빌드하는 경우 호스트 CPU와 일치하는 이름에 대한 [QEMU](https://www.qemu.org/docs/master/system/qemu-cpu-models.html) 설명서를 참조하고 다음 명령을 실행할 때 `-cpu` 플래그를 호스트 CPU 이름과 함께 사용합니다.

 **Ubuntu 22.04 Qcow2 / 원시** 

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

 **Ubuntu 24.04 Qcow2 / 원시** 

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

 **RHEL 8 Qcow2 / 원시** 

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

 **RHEL 9 Qcow2 / 원시** 

```
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마다 템플릿을 복제해야 합니다. 아래 명령에서 다음 변수를 해당 환경의 값으로 바꿉니다. 아래 명령의 `VM_NAME`은 `metadata.yaml` 파일을 통해 VM의 이름을 주입할 때 `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_NAME`을 업데이트 중인 VM의 이름으로 바꿉니다.

   ```
   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. 구성한 EKS 클러스터에 자동으로 연결되어야 하는 새 VM의 전원을 켭니다.

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

# 하이브리드 노드에 대한 자격 증명 준비
<a name="hybrid-nodes-creds"></a>

Amazon EKS Hybrid Nodes는 AWS SSM 하이브리드 활성화 또는 AWS IAM Roles Anywhere에서 프로비저닝한 임시 IAM 자격 증명을 사용하여 Amazon EKS 클러스터로 인증합니다. Amazon EKS Hybrid Nodes CLI(`nodeadm`)와 함께 AWS SSM 하이브리드 활성화 또는 AWS IAM Roles Anywhere를 사용해야 합니다. AWS SSM 하이브리드 활성화와 AWS IAM Roles Anywhere를 둘 다 사용해서는 안 됩니다. 인증 기관(CA)이 있는 기존 퍼블릭 키 인프라(PKI)와 온프레미스 환경에 대한 인증서가 없는 경우 AWS SSM 하이브리드 활성화를 사용하는 것이 좋습니다. 온프레미스에 기존 PKI 및 인증서가 있는 경우 AWS IAM Roles Anywhere를 사용합니다.

## 하이브리드 노드 IAM 역할
<a name="hybrid-nodes-role"></a>

하이브리드 노드를 Amazon EKS 클러스터에 연결하려면 먼저 하이브리드 노드 자격 증명에 대해 AWS SSM 하이브리드 활성화 또는 AWS IAM Roles Anywhere와 함께 사용할 IAM 역할을 생성해야 합니다. 클러스터를 생성한 후 이 역할을 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` 플래그를 전달해야 합니다.
+ [AmazonEC2ContainerRegistryPullOnly](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonEC2ContainerRegistryPullOnly.html) 정책의 정의에 따라 kubelet이 Amazon Elastic Container Registry(Amazon ECR)의 컨테이너 이미지를 사용할 수 있는 권한입니다.
+ AWS SSM을 사용하는 경우 [https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonSSMManagedInstanceCore.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonSSMManagedInstanceCore.html) 정책에 정의된 대로 `nodeadm init`에서 AWS SSM 하이브리드 활성화를 사용할 수 있는 권한.
+ AWS SSM을 사용하는 경우 `nodeadm uninstall`에서 인스턴스 등록을 취소하기 위해 `ssm:DeregisterManagedInstance` 작업과 `ssm:DescribeInstanceInformation` 작업을 사용할 수 있는 권한입니다.
+ (선택사항) Amazon EKS Pod Identity 에이전트에서 `eks-auth:AssumeRoleForPodIdentity` 작업을 사용하여 포드에 대한 보안 인증 정보를 검색할 수 있는 권한.

## AWS SSM 하이브리드 활성화 설정
<a name="hybrid-nodes-ssm"></a>

AWS SSM 하이브리드 활성화를 설정하기 전에 하이브리드 노드 IAM 역할을 생성하고 구성해야 합니다. 자세한 내용은 [하이브리드 노드 IAM 역할 생성](#hybrid-nodes-create-role) 섹션을 참조하세요. AWS Systems Manager 사용 설명서의 [하이브리드 활성화를 생성하여 Systems Manager에 노드 등록](https://docs.aws.amazon.com/systems-manager/latest/userguide/hybrid-activation-managed-nodes.html) 지침에 따라 하이브리드 노드에 대한 AWS SSM 하이브리드 활성화를 생성합니다. 수신한 활성화 코드와 ID는 호스트를 Amazon EKS 클러스터에 하이브리드 노드로 등록할 때 `nodeadm`과 함께 사용됩니다. 하이브리드 노드용 Amazon EKS 클러스터를 생성하고 준비한 후 나중에 이 단계로 돌아갈 수 있습니다.

**중요**  
활성화를 생성한 방법에 따라, Systems Manager는 활성화 코드 및 ID를 콘솔이나 명령 창에 즉시 반환합니다. 이 정보를 복사하여 안전한 장소에 보관하십시오. 콘솔에서 벗어나거나 명령 창을 닫으면 이 정보가 손실될 수 있습니다. 이 정보가 손실하면 새로운 정품 인증을 생성해야 합니다.

기본적으로 AWS SSM 하이브리드 활성화는 24시간 동안 활성화됩니다. 또는 `2024-08-01T00:00:00`과 같은 타임스탬프 형식으로 하이브리드 활성화를 생성할 때 `--expiration-date`를 지정할 수 있습니다. AWS SSM을 자격 증명 공급자로 사용하는 경우 하이브리드 노드의 노드 이름은 구성할 수 없으며 AWS SSM에서 자동으로 생성됩니다. AWS Systems Manager 콘솔의 Fleet Manager에서 AWS SSM 관리형 인스턴스를 보고 관리할 수 있습니다. 추가 비용 없이 AWS 리전별로 계정당 최대 1,000개의 표준 [하이브리드 활성화 노드](https://docs.aws.amazon.com/systems-manager/latest/userguide/activations.html)를 등록할 수 있습니다. 그러나 1,000개 이상의 하이브리드 노드를 등록하려면 고급 인스턴스 티어를 활성화해야 합니다. [Amazon EKS Hybrid Nodes 요금](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을 자격 증명 공급자로 사용하는 경우 노드 이름 또는 자격 증명 기간을 변경할 수 없습니다. 임시 자격 증명은 AWS SSM에 의해 자동으로 교체되며 교체는 노드 또는 애플리케이션의 상태에 영향을 주지 않습니다.

EKS 클러스터당 하나의 AWS SSM 하이브리드 활성화를 사용하여 AWS SSM 하이브리드 활성화와 연결된 인스턴스만 등록 취소할 수 있도록 하이브리드 노드 IAM 역할의 AWS SSM `ssm:DeregisterManagedInstance` 권한 범위를 조정하는 것이 좋습니다. 이 페이지의 예제에서는 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 Roles Anywhere 설정
<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 역할을 프로필에 추가할 때 AWS IAM Roles Anywhere 콘솔의 **프로필 편집** 페이지 하단의 **사용자 지정 역할** 세션 이름 패널에서** 사용자 지정 역할 세션 이름 수락**을 선택합니다. 이는 `CreateProfile` API의 [acceptRoleSessionName](https://docs.aws.amazon.com/rolesanywhere/latest/APIReference/API_CreateProfile.html#rolesanywhere-CreateProfile-request-acceptRoleSessionName) 필드에 해당합니다. 이렇게 하면 부트스트랩 프로세스 중에 `nodeadm`으로 전달하는 구성에서 하이브리드 노드의 사용자 지정 노드 이름을 제공할 수 있습니다. `nodeadm init` 프로세스 중에 사용자 지정 노드 이름을 전달해야 합니다. 프로필을 생성한 후 사용자 지정 역할 세션 이름을 수락하도록 프로필을 업데이트할 수 있습니다.

AWS IAM Roles Anywhere 프로필의 [durationSeconds](https://docs.aws.amazon.com/rolesanywhere/latest/userguide/authentication-create-session#credentials-object) 필드를 통해 AWS IAM Roles Anywhere로 자격 증명 유효 기간을 구성할 수 있습니다. 기본 지속 시간은 1시간이고 최대 12시간입니다. 하이브리드 노드 IAM 역할의 `MaxSessionDuration` 설정은 AWS IAM Roles Anywhere 프로필의 `durationSeconds` 설정보다 커야 합니다. `MaxSessionDuration`에 대한 자세한 내용은 [UpdateRole API documentation](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 콘솔 또는 AWS CLI를 사용하는 IAM 보안 주체에 다음 권한이 있어야 합니다.
+  `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. `ROLE_NAME`을 하이브리드 노드 IAM 역할의 이름으로 바꿉니다. 기본적으로 이름을 지정하지 않으면 CloudFormation 템플릿은 `AmazonEKSHybridNodesRole`을 생성하는 역할의 이름으로 사용합니다.

   1. `TAG_KEY`을 AWSSSM 하이브리드 활성화를 생성할 때 사용한 AWS SSM 리소스 태그 키로 바꿉니다. 태그 키와 태그 값의 조합은 하이브리드 노드 IAM 역할이 AWS SSM 하이브리드 활성화와 연결된 AWS SSM 관리형 인스턴스의 등록을 취소할 수 있도록 허용하는 `ssm:DeregisterManagedInstance`의 조건에서 사용됩니다. CloudFormation 템플릿에서 `TAG_KEY`의 기본값은 `EKSClusterARN`입니다.

   1. `TAG_VALUE`를 AWS SSM 하이브리드 활성화를 생성할 때 사용한 AWS SSM 리소스 태그 값으로 바꿉니다. 태그 키와 태그 값의 조합은 하이브리드 노드 IAM 역할이 AWS SSM 하이브리드 활성화와 연결된 AWS SSM 관리형 인스턴스의 등록을 취소할 수 있도록 허용하는 `ssm:DeregisterManagedInstance`의 조건에서 사용됩니다. `TAG_KEY`의 기본값인 `EKSClusterARN`을 사용하는 경우 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 스택 배포 `STACK_NAME`을 CloudFormation 스택의 이름으로 바꿉니다.

   ```
   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 스택은 사용자가 구성한 인증 기관(CA)을 사용하여 AWS IAM Roles Anywhere 트러스트 앵커를 생성하고, AWS IAM Roles Anywhere 프로필을 생성하고, 앞서 설명한 권한을 사용하여 하이브리드 노드 IAM 역할을 생성합니다.

1. 인증 기관(CA)을 설정하려면

   1. AWS 프라이빗 CA 리소스를 사용하려면 [AWS 프라이빗 인증 기관 콘솔](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. `ROLE_NAME`을 하이브리드 노드 IAM 역할의 이름으로 바꿉니다. 기본적으로 이름을 지정하지 않으면 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_CERT_BODY`를 줄 바꿈 없이 CA의 인증서 본문으로 바꿉니다. `CA_CERT_BODY`는 PEM(Privacy Enhanced Mail) 형식이어야 합니다. PEM 형식의 CA 인증서가 있는 경우 CA 인증서 본문을 `cfn-iamra-parameters.json` 파일에 배치하기 전에 줄 바꿈과 BEGIN CERTIFICATE 및 END CERTIFICATE 줄을 제거합니다.

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

1. CloudFormation 템플릿을 배포합니다. `STACK_NAME`을 CloudFormation 스택의 이름으로 바꿉니다.

   ```
   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` 두 작업에 대한 권한을 부여합니다. 이 정책은 신뢰 정책에 지정한 리소스 태그를 기반으로 AWS SSM 하이브리드 활성화와 연결된 AWS SSM 관리형 인스턴스에 대한 `ssm:DeregisterManagedInstance` 권한을 제한합니다.

   1. `AWS_REGION`을 AWS SSM 하이브리드 활성화를 위한 AWS 리전으로 바꿉니다.

   1. `AWS_ACCOUNT_ID`를 AWS 계정 ID로 바꿉니다.

   1. `TAG_KEY`을 AWSSSM 하이브리드 활성화를 생성할 때 사용한 AWS SSM 리소스 태그 키로 바꿉니다. 태그 키와 태그 값의 조합은 하이브리드 노드 IAM 역할이 AWS SSM 하이브리드 활성화와 연결된 AWS SSM 관리형 인스턴스의 등록을 취소할 수 있도록 허용하는 `ssm:DeregisterManagedInstance`의 조건에서 사용됩니다. CloudFormation 템플릿에서 `TAG_KEY`의 기본값은 `EKSClusterARN`입니다.

   1. `TAG_VALUE`를 AWS SSM 하이브리드 활성화를 생성할 때 사용한 AWS SSM 리소스 태그 값으로 바꿉니다. 태그 키와 태그 값의 조합은 하이브리드 노드 IAM 역할이 AWS SSM 하이브리드 활성화와 연결된 AWS SSM 관리형 인스턴스의 등록을 취소할 수 있도록 허용하는 `ssm:DeregisterManagedInstance`의 조건에서 사용됩니다. `TAG_KEY`의 기본값인 `EKSClusterARN`을 사용하는 경우 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. 이전 단계에서 생성한 `EKSDescribeClusterPolicy`와 `EKSHybridSSMPolicy`를 연결합니다. `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
   ```

 **AWS IAM Roles Anywhere의 단계** 

AWS IAM Roles Anywhere를 사용하려면 하이브리드 노드 IAM 역할을 생성하기 전에 AWS IAM Roles Anywhere 트러스트 앵커를 설정해야 합니다. 자세한 내용은 [AWS IAM Roles Anywhere 설정](#hybrid-nodes-iam-roles-anywhere) 섹션을 참조하세요.

1. `eks-hybrid-iamra-trust.json`이라는 이름의 파일을 만듭니다. `TRUST_ANCHOR ARN`을 [AWS IAM Roles Anywhere 설정](#hybrid-nodes-iam-roles-anywhere) 단계에서 생성한 트러스트 앵커의 ARN으로 바꿉니다. 이 신뢰 정책의 조건은 역할 세션 이름이 하이브리드 노드에 설치된 x509 인증서의 CN과 일치하는 경우에만 AWS IAM Roles Anywhere가 하이브리드 노드 IAM 역할을 수임하여 임시 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 Management Console
<a name="hybrid-nodes-creds-console"></a>

 **EKS 설명 클러스터 정책 생성** 

1. [Amazon IAM 콘솔](https://console.aws.amazon.com/iam/home)을 엽니다.

1. 왼쪽 탐색 창에서 **정책**을 선택합니다.

1. **정책** 페이지에서 **정책 생성**을 선택합니다.

1. 권한 지정 페이지의 서비스 선택 패널에서 EKS를 선택합니다.

   1. **DescribeCluster**에 대한 작업을 필터링하고 **DescribeCluster** 읽기 작업을 선택합니다.

   1. **다음**을 선택합니다.

1. **검토 및 생성** 페이지에서

   1. 정책에 **정책 이름**(예: `EKSDescribeClusterPolicy`)을 입력합니다.

   1. **정책 생성**을 선택합니다.

 **AWS SSM 하이브리드 활성화 단계** 

1. [Amazon IAM 콘솔](https://console.aws.amazon.com/iam/home)을 엽니다.

1. 왼쪽 탐색 창에서 **정책**을 선택합니다.

1. **정책** 페이지에서 **정책 생성**을 선택합니다.

1. **권한 지정** 페이지의 **정책 편집기** 오른쪽 상단에서 **JSON**을 선택합니다. 다음 조각을 붙여 넣습니다. `AWS_REGION`을 AWS SSM 하이브리드 활성화의 AWS 리전으로 바꾸고 `AWS_ACCOUNT_ID`를 AWS 계정 ID로 바꿉니다. `TAG_KEY` 및 `TAG_VALUE`를 AWS SSM 하이브리드 활성화를 생성할 때 사용한 AWS SSM 리소스 태그 키로 바꿉니다.

   ```
   {
       "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. 왼쪽 탐색 창에서 **역할**을 선택합니다.

1. **역할** 페이지에서 **역할 생성**을 선택합니다.

1. **신뢰할 수 있는 엔터티 선택** 페이지에서 다음을 수행합니다.

   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. [Next]를 선택합니다.

1. **권한 추가** 페이지에서 사용자 지정 정책을 연결하거나 다음과 같이 합니다.

   1. **정책 필터링** 상자에 `EKSDescribeClusterPolicy` 또는 위에서 생성한 정책의 이름을 입력합니다. 검색 결과의 정책 이름 왼쪽에 있는 확인란을 선택합니다.

   1. **정책 필터링** 상자에 `EKSHybridSSMPolicy` 또는 위에서 생성한 정책의 이름을 입력합니다. 검색 결과의 정책 이름 왼쪽에 있는 확인란을 선택합니다.

   1. **필터 정책** 상자에 `AmazonEC2ContainerRegistryPullOnly`를 입력합니다. 검색 결과의 `AmazonEC2ContainerRegistryPullOnly` 왼쪽에 있는 확인란을 선택합니다.

   1. **필터 정책** 상자에 `AmazonSSMManagedInstanceCore`를 입력합니다. 검색 결과의 `AmazonSSMManagedInstanceCore` 왼쪽에 있는 확인란을 선택합니다.

   1. **다음**을 선택합니다.

1. **이름, 검토 및 생성** 페이지에서 다음을 수행합니다.

   1. **역할 이름**에 역할의 고유한 이름(예: `AmazonEKSHybridNodesRole`)을 입력합니다.

   1. **설명(Description)**에서 현재 텍스트를 설명이 포함된 텍스트(예: `Amazon EKS - Hybrid Nodes role`)로 바꿉니다.

   1. **역할 생성**을 선택합니다.

 **AWS IAM Roles Anywhere의 단계** 

AWS IAM Roles Anywhere를 사용하려면 하이브리드 노드 IAM 역할을 생성하기 전에 AWS IAM Roles Anywhere 트러스트 앵커를 설정해야 합니다. 자세한 내용은 [AWS IAM Roles Anywhere 설정](#hybrid-nodes-iam-roles-anywhere) 섹션을 참조하세요.

1. [Amazon IAM 콘솔](https://console.aws.amazon.com/iam/home)을 엽니다.

1. 왼쪽 탐색 창에서 **역할**을 선택합니다.

1. **역할** 페이지에서 **역할 생성**을 선택합니다.

1. **신뢰할 수 있는 엔터티 선택** 페이지에서 다음을 수행합니다.

   1. **신뢰할 수 있는 엔터티 유형 섹션**에서 **사용자 지정 신뢰 정책**을 선택합니다. 사용자 지정 신뢰 정책 편집기에 다음을 붙여 넣습니다. `TRUST_ANCHOR ARN`을 [AWS IAM Roles Anywhere 설정](#hybrid-nodes-iam-roles-anywhere) 단계에서 생성한 트러스트 앵커의 ARN으로 바꿉니다. 이 신뢰 정책의 조건은 역할 세션 이름이 하이브리드 노드에 설치된 x509 인증서의 CN과 일치하는 경우에만 AWS IAM Roles Anywhere가 하이브리드 노드 IAM 역할을 수임하여 임시 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. [Next]를 선택합니다.

1. **권한 추가** 페이지에서 사용자 지정 정책을 연결하거나 다음과 같이 합니다.

   1. **정책 필터링** 상자에 `EKSDescribeClusterPolicy` 또는 위에서 생성한 정책의 이름을 입력합니다. 검색 결과의 정책 이름 왼쪽에 있는 확인란을 선택합니다.

   1. **필터 정책** 상자에 `AmazonEC2ContainerRegistryPullOnly`를 입력합니다. 검색 결과의 `AmazonEC2ContainerRegistryPullOnly` 왼쪽에 있는 확인란을 선택합니다.

   1. **다음**을 선택합니다.

1. **이름, 검토 및 생성** 페이지에서 다음을 수행합니다.

   1. **역할 이름**에 역할의 고유한 이름(예: `AmazonEKSHybridNodesRole`)을 입력합니다.

   1. **설명(Description)**에서 현재 텍스트를 설명이 포함된 텍스트(예: `Amazon EKS - Hybrid Nodes role`)로 바꿉니다.

   1. **역할 생성**을 선택합니다.

# 하이브리드 노드를 사용하여 Amazon EKS 클러스터 생성
<a name="hybrid-nodes-cluster-create"></a>

이 주제에서는 사용 가능한 옵션에 대한 개요와 하이브리드 노드 지원 Amazon EKS 클러스터를 생성할 때 고려해야 할 사항을 설명합니다. EKS Hybrid Nodes는 표준 및 확장 지원을 포함하여 클라우드 노드가 있는 Amazon EKS 클러스터와 동일한 [Kubernetes 버전 지원](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)을 제공합니다.

EKS Hybrid Nodes를 사용할 계획이 없는 경우 [Amazon EKS 클러스터 생성](create-cluster.md)의 기본 Amazon EKS 클러스터 생성 설명서를 참조하세요.

## 사전 조건
<a name="hybrid-nodes-cluster-create-prep"></a>
+ [하이브리드 노드에 대한 사전 조건 설정](hybrid-nodes-prereqs.md)가 완료되었습니다. 하이브리드 노드 지원 클러스터를 생성하기 전에 온프레미스 노드와 선택적으로 포드 CIDR을 식별하고, EKS 요구 사항 및 하이브리드 노드 요구 사항에 따라 VPC 및 서브넷을 생성하고, 온프레미스와 선택적으로 포드 CIDR에 대한 인바운드 규칙이 있는 보안 그룹을 지정해야 합니다. 이러한 사전 조건에 대한 자세한 내용은 [하이브리드 노드용 네트워킹 준비](hybrid-nodes-networking.md) 섹션을 참조하세요.
+ 장치에 최신 버전의 AWS Command Line Interface(AWS CLI)가 설치 및 구성되어 있습니다. 현재 버전을 확인하려면 `aws --version`을 사용합니다. yum, apt-get 또는 macOS용 Homebrew와 같은 패키지 관리자는 최신 버전 AWS CLI 이전에 나온 버전이 몇 가지 있을 때도 있습니다. 최신 버전을 설치하려면 AWS Command Line Interface 사용 설명서의 [최신 버전의 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로 확인되므로 클러스터는 '퍼블릭 및 프라이빗' 클러스터 엔드포인트 연결을 사용할 수 없습니다.
+ OIDC 인증은 하이브리드 노드가 있는 EKS 클러스터에서 지원됩니다.
+ 기존 클러스터의 하이브리드 노드 구성을 추가, 변경 또는 제거할 수 있습니다. 자세한 내용은 [기존 Amazon EKS 클러스터에서 하이브리드 노드 활성화 또는 구성 수정](hybrid-nodes-cluster-update.md) 섹션을 참조하세요.

## 1단계: 클러스터 IAM 역할 만들기
<a name="hybrid-nodes-cluster-create-iam"></a>

이미 클러스터 IAM 역할이 있거나 `eksctl` 또는 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 역할](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles#iam-term-principal)을 생성하려면 역할을 생성하는 IAM 보안 주체에 `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)을(를) 참조하십시오. Amazon EKS 관리형 `AmazonEKSClusterPolicy`를 역할에 연결합니다. IAM 정책을 [IAM 보안 주체](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles#iam-term-principal)에 연결하려면 정책을 연결하는 보안 주체에 `iam:AttachUserPolicy` 또는 `iam:AttachRolePolicy`의 IAM 작업(권한) 중 하나를 할당해야 합니다.

   ```
   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 Management Console](#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. `K8S_VERSION`를 모든 [Amazon EKS 지원 버전](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)으로 변경합니다.

   1. [하이브리드 노드에 대한 자격 증명 준비](hybrid-nodes-creds.md)의 단계에서 구성한 자격 증명 공급자를 기반으로 `CREDS_PROVIDER`를 `ssm` 또는 `ira`로 바꿉니다.

   1. AWS IAM Roles Anywhere를 자격 증명 공급자로 사용하는 `ira`로 자격 증명 공급자가 설정된 경우 `CA_BUNDLE_CERT`를 바꿉니다. CA\$1BUNDLE\$1CERT는 CA(인증 기관) 인증서 본문이며 CA 선택에 따라 달라집니다. 인증서는 PEM(Privacy Enhanced Mail) 형식이어야 합니다.

   1. `GATEWAY_ID`를 VPC에 연결할 가상 프라이빗 게이트웨이 또는 전송 게이트웨이의 ID로 바꿉니다.

   1. `REMOTE_NODE_CIDRS`를 하이브리드 노드의 온프레미스 노드 CIDR로 바꿉니다.

   1. `REMOTE_POD_CIDRS`를 하이브리드 노드에서 실행되는 워크로드의 온프레미스 포드 CIDR로 바꾸거나 하이브리드 노드에서 웹후크를 실행하지 않는 경우 구성에서 라인을 제거합니다. 포드 트래픽이 온프레미스 호스트에서 나갈 때 CNI가 포드 IP 주소에 네트워크 주소 변환(NAT) 또는 매스커레이딩을 사용하지 않는 경우 `REMOTE_POD_CIDRS`를 구성해야 합니다. 하이브리드 노드에서 웹후크를 실행하는 경우 `REMOTE_POD_CIDRS`를 구성해야 합니다. [하이브리드 노드용 웹후크 구성](hybrid-nodes-webhooks.md)에서 자세한 내용을 참조하세요.

   1. 온프레미스 노드 및 포드 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 서비스 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 템플릿에 노출되지 않은 EKS 클러스터의 설정을 사용자 지정해야 하는 경우 CloudFormation 템플릿을 수정합니다.

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`: 하이브리드 노드에서 실행되는 워크로드에 대한 온프레미스 포드 CIDR입니다. 포드 트래픽이 온프레미스 호스트에서 나갈 때 CNI가 포드 IP 주소에 네트워크 주소 변환(NAT) 또는 매스커레이딩을 사용하지 않는 경우 `REMOTE_POD_CIDRS`를 구성해야 합니다. 하이브리드 노드에서 웹후크를 실행하는 경우 `REMOTE_POD_CIDRS`를 구성해야 합니다. [하이브리드 노드용 웹후크 구성](hybrid-nodes-webhooks.md)에서 자세한 내용을 참조하세요.

   1. 온프레미스 노드 및 포드 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 서비스 IPv4 CIDR과 중첩되지 않습니다.

   1.  `CLUSTER_AUTH`: 클러스터의 클러스터 인증 모드입니다. 유효 값은 `API` 및 `API_AND_CONFIG_MAP`입니다. 템플릿의 기본값은 `API_AND_CONFIG_MAP`입니다.

   1.  `CLUSTER_ENDPOINT`: 클러스터의 클러스터 엔드포인트 연결입니다. 유효한 값은 '퍼블릭' 또는 '프라이빗'입니다. 템플릿의 기본값은 프라이빗입니다. 즉, VPC 내에서만 Kubernetes API 엔드포인트에 연결할 수 있습니다.

   1.  `K8S_VERSION`: 클러스터에 사용할 Kubernetes 버전입니다. [Amazon EKS supported versions](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` (선택 사항): 하이브리드 노드에서 실행되는 워크로드에 대한 온프레미스 포드 CIDR입니다.

   1. 온프레미스 노드 및 포드 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 서비스 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 Management Console
<a name="hybrid-nodes-cluster-create-console"></a>

1. [Amazon EKS 콘솔](https://console.aws.amazon.com/eks/home#/clusters)에서 Amazon EKS 콘솔을 엽니다.

1. 클러스터 추가를 선택하고 생성을 선택합니다.

1. 클러스터 구성 페이지에서 다음 필드를 입력합니다.

   1.  **이름** - 클러스터의 이름 이름에는 영숫자(대소문자 구분)와 하이픈, 밑줄만 사용할 수 있습니다. 영숫자로 시작해야 하며 100자 이하여야 합니다. 이름은 클러스터를 생성하는 AWS 리전과 AWS 계정 내에서 고유해야 합니다.

   1.  **클러스터 IAM 역할**-생성한 Amazon EKS 클러스터 IAM 역할을 선택하여 Kubernetes 컨트롤 플레인이 사용자 대신 AWS 리소스를 관리하게 할 수 있습니다.

   1.  **Kubernetes 버전(Kubernetes version)** - 클러스터에 대해 사용할 Kubernetes 버전 이전 버전이 필요한 경우가 아니면 최신 버전을 선택하는 것이 좋습니다.

   1.  **업그레이드 정책**-확장 또는 표준을 선택합니다.

      1.  **확장:** 이 옵션은 릴리스 날짜 이후 26개월 동안 Kubernetes 버전을 지원합니다. 연장 지원 기간에는 표준 지원 기간이 종료된 후 시작되는 시간당 추가 비용이 발생합니다. 확장 지원이 종료되면 클러스터가 다음 버전으로 자동 업그레이드됩니다.

      1.  **표준:** 이 옵션은 릴리스 날짜 이후 14개월 동안 Kubernetes 버전을 지원합니다. 추가 비용은 없습니다. 표준 지원이 종료되면 클러스터가 다음 버전으로 자동 업그레이드됩니다.

   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 영역 전환에 등록하여 영역 전환을 통해 애플리케이션 트래픽을 AZ에서 다른 위치로 전환할 수 있습니다.

   1.  **태그**-(선택사항) 클러스터에 태그를 추가합니다. 자세한 내용은 [태그를 사용하여 Amazon EKS 리소스 구성](eks-using-tags.md) 섹션을 참조하세요.

   1. 이 페이지를 모두 완료하면 **다음**을 선택합니다.

1. **네트워킹 지정** 페이지에서 다음 필드의 값을 선택합니다.

   1.  **VPC**-[VPC 및 서브넷에 대한 Amazon EKS 네트워킹 요구 사항 보기](network-reqs.md) 및 [Amazon EKS Hybrid Nodes 요구 사항](hybrid-nodes-prereqs.md)을 충족하는 기존 VPC를 선택합니다. VPC를 선택하기 전에 VPC, 서브넷, 하이브리드 노드에 대한 Amazon EKS 네트워킹 요구 사항 보기의 모든 요구 사항과 고려 사항을 숙지하는 것이 좋습니다. 클러스터 생성 후에는 사용하려는 VPC를 변경할 수 없습니다. 목록에 기존 VPC가 없는 경우 먼저 VPC를 생성해야 합니다. 자세한 내용은 [Amazon EKS 클러스터에 대한 Amazon VPC 생성](creating-a-vpc.md) 및 [Amazon EKS Hybrid Nodes 네트워킹 요구 사항](hybrid-nodes-prereqs.md)을 참조하세요.

   1.  **서브넷**-기본적으로 이전 필드에서 지정한 VPC에서 사용 가능한 모든 서브넷이 사전 선택됩니다. 두 개 이상을 선택해야 합니다.

   1.  **보안 그룹** – (선택사항) 생성하는 네트워크 인터페이스에 Amazon EKS가 연결하려는 보안 그룹을 하나 이상 지정합니다. 지정하는 보안 그룹 중 하나 이상에 온프레미스 노드와 선택적으로 포드 CIDR에 대한 인바운드 규칙이 있어야 합니다. 자세한 내용은 [Amazon EKS Hybrid Nodes networking requirements](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.  **하이브리드 노드를 활성화하도록 원격 네트워크 구성을 선택**하고 하이브리드 노드에 대한 온프레미스 노드와 포드 CIDR을 지정합니다.

   1. 포드 트래픽이 온프레미스 호스트에서 나갈 때 CNI가 포드 IP 주소에 네트워크 주소 변환(NAT) 또는 매스커레이딩을 사용하지 않는 경우 원격 포드 CIDR을 구성해야 합니다. 하이브리드 노드에서 웹후크를 실행하는 경우 원격 포드 CIDR을 구성해야 합니다.

   1. 온프레미스 노드 및 포드 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 서비스 IPv4 CIDR과 중첩되지 않습니다.

   1. **클러스터 엔드포인트 액세스**에서 옵션을 선택합니다. 클러스터를 생성한 후에는 이 옵션을 변경할 수 있습니다. 하이브리드 노드 지원 클러스터의 경우 퍼블릭 또는 프라이빗을 선택해야 합니다. 기본값이 아닌 옵션을 선택하기 전에 옵션과 그 의미를 숙지해야 합니다. 자세한 내용은 [클러스터 API 서버 엔드포인트](cluster-endpoint.md) 섹션을 참조하세요.

   1. 이 페이지를 모두 완료하면 **다음**을 선택합니다.

1. (선택사항) 관찰성 **구성** 페이지에서 설정할 지표 및 컨트롤 플레인 로깅 옵션을 선택합니다. 기본적으로 각 로그 유형은 해제되어 있습니다.

   1. Prometheus 지표 옵션에 자세한 내용은 [Prometheus를 사용한 클러스터 지표 모니터링](prometheus.md) 섹션을 참조하세요.

   1. EKS 컨트롤 로깅 옵션에 대한 자세한 내용은 [CloudWatch Logs에 컨트롤 플레인 로그 전송](control-plane-logs.md) 섹션을 참조하세요.

   1. 이 페이지를 모두 완료하면 **다음**을 선택합니다.

1. **추가 기능 선택** 페이지에서 클러스터에 추가할 추가 기능을 선택합니다.

   1. 필요한 만큼 **Amazon EKS 애드온** 및 **AWS 마켓플레이스 애드온**을 선택할 수 있습니다. 하이브리드 노드와 호환되지 않는 Amazon EKS 추가 기능은 '하이브리드 노드와 호환되지 않음'으로 표시되며 추가 기능에는 하이브리드 노드에서 실행되지 않게 하는 반선호도 규칙이 있습니다. 자세한 내용은 하이브리드 노드용 추가 기능 구성을 참조하세요. 설치하려는 **AWS 마켓플레이스 애드온**이 목록에 없는 경우 검색창에 텍스트를 입력하여 사용 가능한 **AWS 마켓플레이스 애드온**을 검색할 수 있습니다. **카테고리**, **공급업체** 또는 **요금 모델**로 검색한 다음에 검색 결과 중에서 추가 기능을 선택할 수도 있습니다.

   1. CoreDNS, kube-proxy와 같은 일부 추가 기능은 기본적으로 설치됩니다. 기본 추가 기능을 비활성화하면 Kubernetes 애플리케이션 실행 기능에 영향을 미칠 수 있습니다.

   1. 이 페이지를 모두 완료하면 `Next`을 선택합니다.

1. **선택한 추가 기능 설정 구성** 페이지에서 설치할 버전을 선택합니다.

   1. 클러스터 생성 후 언제든지 최신 버전으로 업데이트할 수 있습니다. 클러스터 생성 후 각 추가 기능의 구성을 업데이트할 수 있습니다. 추가 기능 구성에 대한 자세한 내용은 [Amazon EKS 추가 기능 업데이트](updating-an-add-on.md) 섹션을 참조하세요. 하이브리드 노드와 호환되는 추가 기능 버전은 [하이브리드 노드에 대한 추가 기능 구성](hybrid-nodes-add-ons.md) 섹션을 참조하세요.

   1. 이 페이지를 모두 완료하면 다음을 선택합니다.

1. **검토 및 생성** 페이지에서 이전 페이지에서 입력하거나 선택한 정보를 검토합니다. 변경해야 하는 경우 **편집**을 선택합니다 만족하는 경우 **생성**을 선택합니다. 클러스터가 프로비저닝되는 동안 **상태** 필드에는 **생성 중**이 표시됩니다. 클러스터 프로비저닝에는 몇 분 정도 걸립니다.

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 범위를 추가합니다. EKS는 이 CIDR 목록을 사용하여 클러스터와 온프레미스 네트워크 간의 연결을 활성화합니다. 클러스터 구성을 업데이트할 때의 전체 옵션 목록은 *Amazon EKS API 참조*의 [UpdateClusterConfig](https://docs.aws.amazon.com/eks/latest/APIReference/API_UpdateClusterConfig.html)를 참조하세요.

클러스터의 EKS Hybrid Nodes 네트워킹 구성에 대해 다음 작업 중 하나를 수행할 수 있습니다.
+  [원격 네트워크 구성을 추가하여 기존 클러스터에서 EKS Hybrid Nodes를 활성화합니다.](#hybrid-nodes-cluster-enable-existing)
+  [기존 클러스터에서 원격 노드 네트워크나 원격 포드 네트워크를 추가, 변경 또는 제거합니다.](#hybrid-nodes-cluster-update-config)
+  [모든 원격 노드 네트워크 CIDR 범위를 제거하여 기존 클러스터에서 EKS Hybrid Nodes를 비활성화합니다.](#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 Command Line Interface(AWS CLI)가 설치 및 구성되어 있습니다. 현재 버전을 확인하려면 `aws --version`을 사용합니다. yum, apt-get 또는 macOS용 Homebrew와 같은 패키지 관리자는 최신 버전 AWS CLI 이전에 나온 버전이 몇 가지 있을 때도 있습니다. 최신 버전을 설치하려면 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가 원래 목록을 대체합니다.
+ 온프레미스 노드 및 포드 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 서비스 IPv4 CIDR과 중첩되지 않아야 합니다.

## 기존 클러스터에서 하이브리드 노드 활성화
<a name="hybrid-nodes-cluster-enable-existing"></a>

다음을 사용하여 기존 클러스터에서 EKS Hybrid Nodes를 활성화할 수 있습니다.
+  [AWS CloudFormation](#hybrid-nodes-cluster-enable-cfn) 
+  [AWS CLI](#hybrid-nodes-cluster-enable-cli) 
+  [AWS Management Console](#hybrid-nodes-cluster-enable-console) 

### 기존 클러스터에서 EKS Hybrid Nodes 활성화 - AWS CloudFormation
<a name="hybrid-nodes-cluster-enable-cfn"></a>

1. 클러스터에서 EKS Hybrid Nodes를 활성화하려면 CloudFormation 템플릿에 `RemoteNodeNetwork`와 `RemotePodNetwork`(선택 사항)를 추가하고 스택을 업데이트합니다. `RemoteNodeNetwork`는 최대 하나의 `Cidrs` 항목이 포함된 목록이고, `Cidrs`는 여러 IP CIDR 범위의 목록입니다.

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

1. 계속해서 [하이브리드 노드에 대한 클러스터 액세스 준비](hybrid-nodes-cluster-prep.md)로 이동하세요.

### 기존 클러스터에서 EKS Hybrid Nodes 활성화 - AWS CLI
<a name="hybrid-nodes-cluster-enable-cli"></a>

1. 다음 명령을 실행하여 EKS 클러스터의 EKS Hybrid Nodes에 대해 `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` (선택 사항): 하이브리드 노드에서 실행되는 워크로드에 대한 온프레미스 포드 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 Hybrid Nodes 활성화 - AWS Management Console
<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.  **하이브리드 노드를 활성화하도록 원격 네트워크 구성을 선택**하고 하이브리드 노드에 대한 온프레미스 노드와 포드 CIDR을 지정합니다.

1. **변경 사항 저장**을 선택하여 종료합니다. 클러스터가 **활성** 상태로 돌아갈 때까지 기다립니다.

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 Management Console](#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 Management Console
<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 pod networks - Optional` 및 `Remote node networks`에서 CIDR을 업데이트합니다.

1. **변경 사항 저장**을 선택하고 클러스터 상태가 **활성**으로 돌아갈 때까지 기다립니다.

## 기존 클러스터에서 하이브리드 노드 비활성화
<a name="hybrid-nodes-cluster-disable"></a>

다음을 사용하여 기존 클러스터에서 EKS Hybrid Nodes를 비활성화할 수 있습니다.
+  [AWS CloudFormation](#hybrid-nodes-cluster-disable-cfn) 
+  [AWS CLI](#hybrid-nodes-cluster-disable-cli) 
+  [AWS Management Console](#hybrid-nodes-cluster-disable-console) 

### 기존 클러스터에서 EKS Hybrid Nodes 비활성화 - AWS CloudFormation
<a name="hybrid-nodes-cluster-disable-cfn"></a>

1. 클러스터에서 EKS Hybrid Nodes를 비활성화하려면 CloudFormation 템플릿에서 `RemoteNodeNetworks`와 `RemotePodNetworks`를 빈 어레이로 설정하고 스택을 업데이트합니다.

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

### 기존 클러스터에서 EKS Hybrid Nodes 비활성화 - 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 Hybrid Nodes 비활성화 - AWS Management Console
<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. **변경 사항 저장**을 선택하여 종료합니다. 클러스터가 **활성** 상태로 돌아갈 때까지 기다립니다.

# 하이브리드 노드에 대한 클러스터 액세스 준비
<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 API에 대한 액세스 권한 부여](grant-k8s-access.md) 섹션을 참조하세요.

아래 절차에 따라 하이브리드 노드 IAM 역할을 Kubernetes 권한과 연결합니다. Amazon EKS 액세스 항목을 사용하려면 클러스터가 `API` 또는 `API_AND_CONFIG_MAP` 인증 모드로 생성되어야 합니다. `aws-auth` ConfigMap을 사용하려면 클러스터가 `API_AND_CONFIG_MAP` 인증 모드로 생성되어야 합니다. 하이브리드 노드 지원 Amazon EKS 클러스터에는 `CONFIG_MAP` 전용 인증 모드가 지원되지 않습니다.

## 하이브리드 노드 IAM 역할에 Amazon EKS 액세스 항목 사용
<a name="_using_amazon_eks_access_entries_for_hybrid_nodes_iam_role"></a>

IAM 역할과 함께 사용할 수 있는 하이브리드 노드의 Amazon EKS 액세스 항목 유형인 HYBRID\$1LINUX가 있습니다. 이 액세스 항목 유형에서는 사용자 이름이 system:node:\$1\$1SessionName\$1\$1으로 자동 설정됩니다. 액세스 항목 생성에 대한 자세한 내용은 [액세스 항목 생성](creating-access-entries.md) 섹션을 참조하세요.

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

1. 장치에 최신 버전의 AWS CLI가 설치 및 구성되어 있어야 합니다. 현재 버전을 확인하려면 `aws --version`을 사용합니다. yum, apt-get 또는 macOS용 Homebrew와 같은 패키지 관리자는 최신 버전 AWS CLI 이전에 나온 버전이 몇 가지 있을 때도 있습니다. 최신 버전을 설치하려면 AWS 명령줄 인터페이스 사용 설명서에서 설치 및 aws config를 사용하여 빠른 구성을 참조하세요.

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 Management Console
<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>

다음 단계에서는 [하이브리드 노드에 대한 자격 증명 준비](hybrid-nodes-creds.md)의 단계에서 생성한 하이브리드 노드 IAM 역할의 ARN으로 `aws-auth` 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` 항목을 추가합니다. `HYBRID_NODES_ROLE_ARN`을 하이브리드 노드 IAM 역할의 ARN으로 바꿉니다. 참고로 `{{SessionName}}`은 ConfigMap에 저장할 올바른 템플릿 형식입니다. 다른 값으로 바꾸지 마세요.

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

   1. 파일을 저장하고 텍스트 편집기를 종료합니다.

1. 클러스터에 대한 기존 `aws-auth` ConfigMap이 없는 경우 다음 명령을 사용하여 생성합니다. `HYBRID_NODES_ROLE_ARN`을 하이브리드 노드 IAM 역할의 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 콘솔이나 kubectl과 같은 Kubernetes 호환 도구에 준비되지 않음 상태로 표시됩니다. 이 페이지의 단계를 완료한 후 [하이브리드 노드에 대한 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 Hybrid Nodes 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` 명령을 사용하여 하이브리드 노드에 필요한 모든 종속성을 설치할 수 있습니다. 하이브리드 노드 종속성에는 Containered, 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 액세스 권한이 있는 사용자와 함께 실행해야 합니다.
+ 예를 들어 `K8S_VERSION`을 Amazon EKS 클러스터의 Kubernetes 마이너 버전(예: `1.31`)으로 바꿉니다. 지원되는 Kubernetes 버전 목록은 [Amazon EKS 지원 버전](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)을 참조하세요.
+ `CREDS_PROVIDER`를 사용 중인 온프레미스 자격 증명 공급자로 바꿉니다. 유효한 값은 `ssm`(AWS SSM) 및 `iam-ra`(AWS IAM Roles Anywhere)입니다.

```
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 서비스 IPv4 CIDR을 전달해야 합니다.

   1. 온프레미스 자격 증명 공급자에 대해 AWS SSM 하이브리드 활성화를 사용하는 경우 아래 `nodeConfig.yaml` 예제를 사용합니다.

      1. `CLUSTER_NAME`를 클러스터 이름으로 바꿉니다.

      1. `AWS_REGION`을 클러스터를 호스팅하는 AWS 리전으로 바꿉니다. 예를 들어 `us-west-2`입니다.

      1. `ACTIVATION_CODE`를 AWS SSM 하이브리드 활성화를 생성할 때 받은 활성화 코드로 바꿉니다. 자세한 정보는 [하이브리드 노드에 대한 자격 증명 준비](hybrid-nodes-creds.md)을 참조하세요.

      1. `ACTIVATION_ID`를 AWS SSM 하이브리드 활성화를 생성할 때 받은 활성화 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_REGION`을 클러스터를 호스팅하는 AWS 리전으로 바꿉니다. 예를 들어 `us-west-2`입니다.

      1. `NODE_NAME`을 노드의 이름으로 바꿉니다. 하이브리드 노드 IAM 역할의 신뢰 정책을 `"sts:RoleSessionName": "${aws:PrincipalTag/x509Subject/CN}"` 리소스 조건으로 구성한 경우 노드 이름은 호스트에서 인증서의 CN과 일치해야 합니다. 사용하는 `nodeName`은 64자를 초과할 수 없습니다.

      1. 하이브리드 노드에 대한 자격 증명 준비 단계에서 구성한 트러스트 앵커의 ARN으로 `TRUST_ANCHOR_ARN`을 바꿉니다.

      1. [하이브리드 노드에 대한 자격 증명 준비](hybrid-nodes-creds.md) 단계에서 구성한 트러스트 앵커의 ARN으로 `PROFILE_ARN`을 바꿉니다.

      1. `ROLE_ARN`을 하이브리드 노드 IAM 역할의 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 클러스터에 조인된 것입니다. 클러스터의 컴퓨팅 탭으로 이동하거나([IAM 보안 주체가 볼 수 있는 권한이 있는지 확인](view-kubernetes-resources.md#view-kubernetes-resources-permissions)) `kubectl get nodes`를 사용하여 Amazon EKS 콘솔에서 이를 확인할 수 있습니다.

**중요**  
노드의 상태는 `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/)은 AWS에서 후원하고 지원하는 오픈 소스 Linux 배포판입니다. Bottlerocket은 컨테이너 워크로드 호스팅용으로 특별히 설계되었습니다. Bottlerocket을 사용하면 컨테이너 인프라 업데이트를 자동화하여 컨테이너화된 배포의 가용성을 개선하고 운영 비용을 절감할 수 있습니다. Bottlerocket에는 컨테이너를 실행하는 데 필수적인 소프트웨어만 포함되어 있어 리소스 사용량이 개선되고 보안 위협과 관리 오버헤드가 감소합니다.

Bottlerocket 버전 v1.37.0 이상의 VMware 변형만 EKS Hybrid Nodes에서 지원됩니다. Bottlerocket의 VMware 변형은 Kubernetes 버전 v1.28 이상에서 사용할 수 있습니다. 이러한 변형의 OS 이미지에는 kubelet, containerd, aws-iam-authenticator 및 기타 EKS Hybrid Nodes용 소프트웨어 사전 조건이 포함됩니다. Bottlerocket 부트스트랩 및 관리자 컨테이너에 대한 base64 인코딩된 사용자 데이터가 포함된 Bottlerocket [설정](https://github.com/bottlerocket-os/bottlerocket#settings) 파일을 사용하여 이러한 구성 요소를 구성할 수 있습니다. 이러한 설정을 구성하면 Bottlerocket이 하이브리드 노드 자격 증명 공급자를 사용하여 하이브리드 노드를 클러스터에 인증할 수 있습니다. 하이브리드 노드가 클러스터에 조인되면 Amazon EKS 콘솔이나 `kubectl`과 같은 Kubernetes 호환 도구에 `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 파일은 EKS 클러스터에서 Bottlerocket VMWare 시스템을 노드로 초기화하는 데 필요한 최소 설정만 나타냅니다. Bottlerocket은 여러 사용 사례를 해결하기 위해 다양한 설정을 제공하므로, 하이브리드 노드 초기화 이후 추가 구성 옵션의 경우 [Bottlerocket 설명서](https://bottlerocket.dev/en)에서 사용 중인 Bottlerocket 버전에 대해 문서화된 모든 설정의 전체 목록을 참조하세요(예를 들어 Bottlerocket 1.51.x에 대해 사용할 수 있는 모든 설정은 [여기](https://bottlerocket.dev/en/os/1.51.x/api/settings-index)를 참조).

### 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 ECS 클러스터의 이름입니다.
+  `<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)를 참조하세요. 관리자 컨테이너는 예를 들어 SSH 사용자 및 키 입력을 JSON 형식으로 사용합니다.

```
{
  "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 ECS 클러스터의 이름입니다.
+  `<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 공급자를 사용하는 경우 하이브리드 노드 IAM 역할의 신뢰 정책을 `"sts:RoleSessionName": "${aws:PrincipalTag/x509Subject/CN}"` 리소스 조건으로 구성했으면 노드 이름은 호스트에서 인증서의 CN과 일치해야 합니다.
+  `<base64-encoded-aws-config-file>`: AWS config 파일의 base64로 인코딩된 내용입니다. 파일의 내용은 다음과 같습니다.

```
[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)를 참조하세요. 관리자 컨테이너는 예를 들어 SSH 사용자 및 키 입력을 JSON 형식으로 사용합니다.

```
{
  "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이 poweredOff 상태여야 합니다. 예를 들어 `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 Hybrid Nodes는 표준 및 확장 지원을 포함하여클라우드 노드가 있는 Amazon EKS 클러스터에 대해 동일한 [Kubernetes 버전 지원](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)을 제공합니다.

Amazon EKS Hybrid Nodes는 노드에 대해 업스트림 Kubernetes와 동일한 [버전 스큐 정책](https://kubernetes.io/releases/version-skew-policy/#supported-version-skew)을 따릅니다. Amazon EKS Hybrid Nodes는 Amazon EKS 컨트롤 플레인보다 최신 버전일 수 없으며, 하이브리드 노드는 Amazon EKS 컨트롤 플레인 마이너 버전보다 최대 3개의 Kubernetes 마이너 버전일 수 있습니다.

전환 마이그레이션 업그레이드 전략을 위해 대상 Kubernetes 버전에 새 하이브리드 노드를 생성할 예비 용량이 없는 경우 Amazon EKS Hybrid Nodes 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 버전의 하이브리드 노드로 마이그레이션하는 동안 포드가 서로 통신할 수 있습니다.

1. 대상 Kubernetes 버전의 하이브리드 노드가 클러스터에 성공적으로 조인되었고 준비됨 상태인지 확인합니다.

1. 다음 명령을 사용하여 제거하려는 각 노드를 예약 불가로 표시합니다. 이는 바꾸고 있는 노드에서 새 포드가 예약되거나 다시 예약되지 않도록 하기 위한 것입니다. 자세한 내용은 Kubernetes 문서의 [kubectl cordon](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_cordon/)을 참조하세요. `NODE_NAME`을 이전 Kubernetes 버전의 하이브리드 노드 이름으로 바꿉니다.

   ```
   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. 현재 배포가 하이브리드 노드에서 2개 미만의 CoreDNS 복제본을 실행하고 있는 경우, 배포를 복제본 2개 이상으로 확장합니다. 정상 작업 중에 복원력을 위해 하이브리드 노드에서 최소 2개의 CoreDNS 복제본을 실행하는 것이 좋습니다.

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

1. 다음 명령을 사용하여 클러스터에서 제거할 기존 Kubernetes 버전의 각 하이브리드 노드를 드레이닝합니다. 노드 드레이닝에 대한 자세한 내용은 Kubernetes 설명서의 [Safely Drain a Node](https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/)을 참조하세요. `NODE_NAME`을 이전 Kubernetes 버전의 하이브리드 노드 이름으로 바꿉니다.

   ```
   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`을 실행해야 합니다. 노드에 포드가 남아 있는 경우 기본적으로 `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. 다음 명령을 사용하여 업그레이드하는 노드를 예약 불가로 표시합니다. 이는 업그레이드하는 노드에서 새 포드가 예약되거나 다시 예약되지 않도록 하기 위한 것입니다. 자세한 내용은 Kubernetes 문서의 [kubectl cordon](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_cordon/)을 참조하세요. `NODE_NAME`을 업그레이드하려는 하이브리드 노드의 이름으로 바꿉니다.

   ```
   kubectl cordon NODE_NAME
   ```

1. 다음 명령을 사용하여 업그레이드하려는 노드를 드레이닝합니다. 노드 드레이닝에 대한 자세한 내용은 Kubernetes 설명서의 [Safely Drain a Node](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 및 AWS IAM Roles Anywhere 자격 증명 공급자 모두에 대한 업그레이드를 통해 보존됩니다. 업그레이드 프로세스 중에는 자격 증명 공급자를 변경할 수 없습니다. [하이브리드 노드 `nodeadm` 참조](hybrid-nodes-nodeadm.md)의 구성 값은 `nodeConfig.yaml` 섹션을 참조하세요. `K8S_VERSION`을 업그레이드할 대상 Kubernetes 버전으로 바꿉니다.

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

1. 업그레이드한 후 노드에서 포드를 예약하도록 허용하려면 다음을 입력합니다. `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 Hybrid Nodes의 표준 Kubernetes 컨테이너 런타임 및 핵심 종속성으로, 이미지 가져오기 및 컨테이너 실행 관리를 포함하여 컨테이너 수명 주기를 관리하는 데 사용됩니다. 하이브리드 노드에서는 [nodeadm CLI](https://docs.aws.amazon.com/eks/latest/userguide/hybrid-nodes-nodeadm.html)를 통해 또는 수동으로 `containerd`를 설치할 수 있습니다. 노드의 운영 체제에 따라 `nodeadm`은 OS 배포 패키지 또는 Docker 패키지에서 `containerd`를 설치합니다.

`containerd`의 CVE가 게시되면 하이브리드 노드에서 다음 옵션으로 패치된 버전의 `containerd`로 업그레이드합니다.

## 1단계: 패치가 패키지 관리자에 게시되었는지 확인
<a name="_step_1_check_if_the_patch_published_to_package_managers"></a>

해당 보안 게시판을 참조하여 `containerd` CVE 패치가 각 OS 패키지 관리자에 게시되었는지 확인할 수 있습니다.
+  [Amazon Linux 2023](https://alas.aws.amazon.com/alas2023.html) 
+  [RHEL](https://access.redhat.com/security/security-updates/security-advisories) 
+  [Ubuntu 22.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 패치가 OS 또는 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>

GitHub 릴리스와 같이 패키지 관리자가 아닌 다른 방법으로만 패치 적용된 `containerd` 버전이 제공된 경우 공식 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. `--containerd-source` 인수가 `none`로 설정된 상태에서 `nodeadm install` 명령을 실행하면 `nodeadm`를 통해 `containerd` 설치를 건너뜁니다. 노드가 실행 중인 모든 운영 체제에 대해 `containerd` 소스의 `none` 값을 사용할 수 있습니다.

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

# 하이브리드 노드 제거
<a name="hybrid-nodes-remove"></a>

이 주제에서는 Amazon EKS 클러스터에서 하이브리드 노드를 삭제하는 방법을 설명합니다. [kubectl](https://kubernetes.io/docs/reference/kubectl/)과 같은 Kubernetes 호환 도구를 선택하여 하이브리드 노드를 삭제해야 합니다. 노드 객체가 Amazon EKS 클러스터에서 제거되면 하이브리드 노드에 대한 요금 부과가 중지됩니다. 하이브리드 노드 요금에 대한 자세한 내용은 [Amazon EKS Pricing](https://aws.amazon.com/eks/pricing/)을 참조하세요.

**중요**  
노드를 제거하면 노드에서 실행되는 워크로드가 중단됩니다. 하이브리드 노드를 삭제하기 전에 먼저 노드를 드레이닝하여 포드를 다른 활성 노드로 이동하는 것이 좋습니다. 노드 드레이닝에 대한 자세한 내용은 Kubernetes 설명서의 [Safely Drain a Node](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 drain](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 Hybrid Nodes CLI(`nodeadm`)를 사용하여 호스트에서 하이브리드 노드 아티팩트를 중지하고 제거할 수 있습니다. root/sudo 권한이 있는 사용자와 함께 `nodeadm`을 실행해야 합니다. 노드에 포드가 남아 있는 경우 기본적으로 `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)를 참조하세요.

# 하이브리드 노드에 대한 애플리케이션 네트워킹, 추가 기능 및 웹후크 구성
<a name="hybrid-nodes-configure"></a>

하이브리드 노드용 EKS 클러스터를 생성한 후 애플리케이션 네트워킹을 위한 추가 기능(CNI, BGP, Ingress, 로드 밸런싱, 네트워크 정책), 추가 기능, 웹후크 및 프록시 설정을 위한 추가 기능을 구성합니다. 하이브리드 노드와 호환되는 EKS 및 커뮤니티 추가 기능의 전체 목록은 [하이브리드 노드에 대한 추가 기능 구성](hybrid-nodes-add-ons.md) 섹션을 참조하세요.

 **EKS 클러스터 인사이트** EKS에는 클러스터 또는 워크로드의 기능을 손상시킬 수 있는 하이브리드 노드 설정의 잘못된 구성에 대한 인사이트 검사가 포함됩니다. 클러스터 인사이트에 대한 자세한 내용은 [클러스터 인사이트를 사용한 Kubernetes 버전 업그레이드 준비 및 잘못된 구성 문제 해결](cluster-insights.md) 섹션을 참조하세요.

다음은 하이브리드 노드에서 사용할 수 있는 일반적인 기능 및 추가 기능입니다.
+  **CNI(컨테이너 네트워킹 인터페이스)**: AWS는 하이브리드 노드의 CNI로 [Cilium](https://docs.cilium.io/en/stable/index.html)을 지원합니다. 자세한 내용은 [하이브리드 노드에 대한 CNI 구성](hybrid-nodes-cni.md) 섹션을 참조하세요. AWS VPC CNI는 하이브리드 노드와 함께 사용할 수 없습니다.
+  **CoreDNS 및 `kube-proxy`**: CoreDNS 및 `kube-proxy`는 하이브리드 노드가 EKS 클러스터에 조인할 때 자동으로 설치됩니다. 이러한 추가 기능은 클러스터 생성 후 EKS 추가 기능으로 관리할 수 있습니다.
+  **Ingress 및 로드 밸런싱**: 하이브리드 노드에서 실행되는 워크로드에 대해 대상 유형이 `ip`인 AWS Load Balancer Controller 및 ALB(Application Load Balancer) 또는 NLB(Network Load Balancer)를 사용할 수 있습니다. AWS는 하이브리드 노드에서 실행되는 워크로드에 대해 Cilium의 내장 Ingress, Gateway 및 Kubernetes Service 로드 밸런싱 기능을 지원합니다. 자세한 내용은 [하이브리드 노드에 대한 Kubernetes Ingress 구성](hybrid-nodes-ingress.md) 및 [하이브리드 노드에 대한 LoadBalancer 유형의 Service 구성](hybrid-nodes-load-balancing.md)(을)를 참조하세요.
+  **지표**: 하이브리드 노드에서 Amazon Managed Service for Prometheus(AMP) 에이전트 없는 스크레이퍼, AWS Distro for Open Telemetry(ADOT), Amazon CloudWatch 관찰성 에이전트를 사용할 수 있습니다. 하이브리드 노드의 포드 지표에 AMP 에이전트 없는 스크레이퍼를 사용하려면 EKS 클러스터에 사용하는 VPC에서 포드에 액세스할 수 있어야 합니다.
+  **로그**: 하이브리드 노드 지원 클러스터에 대해 EKS 컨트롤 플레인 로깅을 활성화할 수 있습니다. 하이브리드 노드 및 포드 로깅에 ADOT EKS 추가 기능과 Amazon CloudWatch 관찰성 에이전트 EKS 추가 기능을 사용할 수 있습니다.
+  **Pod Identity 및 IRSA**: 하이브리드 노드에서 실행되는 애플리케이션과 함께 EKS Pod Identity와 서비스 계정에 대한 IAM 역할(IRSA)을 사용하여 다른 AWS 서비스의 하이브리드 노드에서 실행되는 포드에 대한 세분화된 액세스를 활성화할 수 있습니다.
+  **웹후크**: 웹후크를 실행하는 경우 온프레미스 포드 네트워크를 라우팅할 수 없을 때 선택적으로 클라우드 노드에서 웹후크를 실행하기 위한 고려 사항 및 단계는 [하이브리드 노드용 웹후크 구성](hybrid-nodes-webhooks.md) 섹션을 참조하세요.
+  **프록시**: 데이터 센터 또는 엣지 환경에서 나가는 트래픽에 대해 온프레미스 환경에서 프록시 서버를 사용하는 경우 프록시 서버를 사용하도록 하이브리드 노드 및 클러스터를 구성할 수 있습니다. 자세한 내용은 [하이브리드 노드용 프록시 구성](hybrid-nodes-proxy.md) 섹션을 참조하세요.

**Topics**
+ [하이브리드 노드에 대한 CNI 구성](hybrid-nodes-cni.md)
+ [하이브리드 노드에 대한 추가 기능 구성](hybrid-nodes-add-ons.md)
+ [하이브리드 노드용 웹후크 구성](hybrid-nodes-webhooks.md)
+ [하이브리드 노드용 프록시 구성](hybrid-nodes-proxy.md)
+ [하이브리드 노드에 대한 Cilium BGP 구성](hybrid-nodes-cilium-bgp.md)
+ [하이브리드 노드에 대한 Kubernetes Ingress 구성](hybrid-nodes-ingress.md)
+ [하이브리드 노드에 대한 LoadBalancer 유형의 Service 구성](hybrid-nodes-load-balancing.md)
+ [하이브리드 노드에 대한 Kubernetes 네트워크 정책 구성](hybrid-nodes-network-policies.md)

# 하이브리드 노드에 대한 CNI 구성
<a name="hybrid-nodes-cni"></a>

Cilium은 Amazon EKS Hybrid Nodes용 AWS 지원 CNI(컨테이너 네트워킹 인터페이스)입니다. 워크로드에 대비하려면 하이브리드 노드용 CNI를 설치해야 합니다. 하이브리드 노드는 CNI가 실행될 때까지 `Not Ready` 상태로 표시됩니다. Helm과 같은 도구를 선택하여 이러한 CNI를 관리할 수 있습니다. 이 페이지의 지침에서는 Cilium 수명 주기 관리(설치, 업그레이드, 삭제)를 설명합니다. Ingress, 로드 밸런싱 운영 모범 사례 및 네트워크 정책에 맞게 Cilium을 구성하는 방법은 [Cilium Ingress 및 Cilium Gateway 개요](hybrid-nodes-ingress.md#hybrid-nodes-ingress-cilium), [Service 유형 LoadBalancer](hybrid-nodes-ingress.md#hybrid-nodes-ingress-cilium-loadbalancer) 및 [하이브리드 노드에 대한 Kubernetes 네트워크 정책 구성](hybrid-nodes-network-policies.md) 섹션을 참조하세요.

Cilium은 AWS 클라우드의 노드에서 실행할 때 AWS에서 지원되지 않습니다. Amazon VPC CNI는 하이브리드 노드와 호환되지 않으며 VPC CNI는 `eks.amazonaws.com/compute-type: hybrid` 레이블에 대한 반선호도로 구성됩니다.

이 페이지에 있었던 Calico 문서는 [EKS Hybrid 예시 리포지토리](https://github.com/aws-samples/eks-hybrid-examples)로 옮겨졌습니다.

## 버전 호환성
<a name="hybrid-nodes-cilium-version-compatibility"></a>

Amazon EKS에서 지원되는 모든 Kubernetes 버전에서 EKS 하이브리드 노드에 대해 Cilium 버전 `v1.17.x` 및 `v1.18.x`가 지원됩니다.

**참고**  
 **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 Hybrid Nodes는 클라우드 노드가 있는 Amazon EKS 클러스터와 동일한 Kubernetes 버전 지원을 제공합니다.

## 지원되는 기능
<a name="hybrid-nodes-cilium-support"></a>

 AWS는 오픈 소스 [Cilium 프로젝트](https://github.com/cilium/cilium)를 기반으로 하는 Cilium for EKS Hybrid Nodes 빌드를 유지 관리합니다. Cilium에 대한 AWS의 지원을 받으려면 AWS에서 유지 관리하는 Cilium 빌드 및 지원되는 Cilium 버전을 사용해야 합니다.

 AWS는 EKS Hybrid Nodes에서 사용할 수 있는 Cilium의 다음 기능에 대한 기본 구성의 기술 지원을 제공합니다. AWS 지원 범위 외에 기능을 사용하려는 경우 해당 플러그인에 대한 대체 상용 지원을 받거나 Cilium 프로젝트의 문제를 해결하고 프로젝트 수정에 기여할 수 있는 전문 지식을 내부적으로 보유하는 것이 좋습니다.


| Cilium 기능 | AWS 지원  | 
| --- | --- | 
|  Kubernetes 네트워크 적합성  |  예  | 
|  코어 클러스터 연결  |  예  | 
|  IP 패밀리  |  IPv4  | 
|  수명 주기 관리  |  Helm  | 
|  네트워킹 모드  |  VXLAN 캡슐화  | 
|  IP 주소 관리(IPAM)  |  Cilium IPAM 클러스터 범위  | 
|  정책 네트워크  |  Kubernetes 네트워크 정책  | 
|  Border Gateway Protocol(BGP)  |  Cilium BGP Control Plane  | 
|  Kubernetes Ingress  |  Cilium Ingress, Cilium Gateway  | 
|  Service LoadBalancer IP 할당  |  Cilium Load Balancer IPAM  | 
|  Service LoadBalancer IP 주소 알림  |  Cilium BGP Control Plane  | 
|  kube-proxy 대체  |  예  | 

## Cilium 고려 사항
<a name="hybrid-nodes-cilium-considerations"></a>
+  **Helm 리포지토리** - AWS는 [Amazon EKS Cilium/Cilium](https://gallery.ecr.aws/eks/cilium/cilium)의 Amazon Elastic Container Registry Public(Amazon ECR Public)에서 Cilium Helm 차트를 호스팅합니다. 사용 가능한 버전으로 다음이 포함됩니다.
  + Cilium v1.17.9: `oci://public.ecr.aws/eks/cilium/cilium:1.17.9-0` 
  + Cilium v1.18.3: `oci://public.ecr.aws/eks/cilium/cilium:1.18.3-0` 

    이 주제의 명령에서는 이 리포지토리를 사용합니다. Amazon ECR Public의 Helm 리포지토리에는 특정 `helm repo` 명령이 유효하지 않으므로 로컬 Helm 리포지토리 이름에서 이 리포지토리를 참조할 수 없습니다. 대신 대부분의 명령에서 전체 URI를 사용합니다.
+ 기본적으로 Cilium은 [캡슐화 방법](https://docs.cilium.io/en/stable/network/concepts/routing/#encapsulation)으로 VXLAN을 사용하여 오버레이/터널 모드에서 실행되도록 구성됩니다. 이 모드는 기본 물리적 네트워크에 대한 요구 사항이 가장 적습니다.
+ 기본적으로 Cilium은 클러스터를 떠나는 모든 포드 트래픽의 소스 IP 주소를 노드의 IP 주소로 [매스커레이딩](https://docs.cilium.io/en/stable/network/concepts/masquerading/)합니다. 매스커레이딩을 비활성화하면 포드 CIDR은 온프레미스 네트워크에서 라우팅 가능해야 합니다.
+ 하이브리드 노드에서 웹후크를 실행하는 경우 포드 CIDR이 온프레미스 네트워크에서 라우팅 가능해야 합니다. 온프레미스 네트워크에서 포드 CIDR이 라우팅 가능하지 않은 경우 동일한 클러스터의 클라우드 노드에서 웹후크를 실행하는 것이 좋습니다. 자세한 내용은 [하이브리드 노드용 웹후크 구성](hybrid-nodes-webhooks.md) 및 [하이브리드 노드용 네트워킹 준비](hybrid-nodes-networking.md) 섹션을 참조하세요.
+  AWS에서는 포드 CIDR이 온프레미스 네트워크에서 라우팅 가능하도록 Cilium의 내장 BGP 기능을 사용할 것을 권장합니다. 하이브리드 노드에서 Cilium BGP를 구성하는 방법에 대한 자세한 내용은 [하이브리드 노드에 대한 Cilium BGP 구성](hybrid-nodes-cilium-bgp.md) 섹션을 참조하세요.
+ Cilium의 기본 IP Address Management(IPAM)를 [Cluster Scope](https://docs.cilium.io/en/stable/network/concepts/ipam/cluster-pool/)라고 하며, 여기서 Cilium 연산자는 사용자가 구성한 포드 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 클러스터의 *원격 포드 네트워크*에 대해 구성한 것과 동일한 포드 CIDR로 `clusterPoolIpv4PodCIDRList`를 구성합니다. 예를 들어 `10.100.0.0/24`입니다. Cilium 운영자는 구성된 `clusterPoolIpv4PodCIDRList` IP 공간 내에서 IP 주소 조각을 할당합니다. 포드 CIDR이 온프레미스 노드 CIDR, VPC CIDR 또는 Kubernetes 서비스 CIDR과 겹치면 안 됩니다.
   + 노드당 필요한 포드를 기반으로 `clusterPoolIpv4MaskSize`를 구성합니다. 예를 들어, `25`로 구성하면 노드당 128개 포드의 세그먼트 크기는 /25가 됩니다.
   + 클러스터에 Cilium을 배포한 후에는 `clusterPoolIpv4PodCIDRList` 또는 `clusterPoolIpv4MaskSize`를 변경하지 마세요. 자세한 내용은 [Expanding the cluster pool](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 L7(계층 7) 프록시를 비활성화합니다. 자세한 내용은 [하이브리드 노드에 대한 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 reference](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` 상태여야 합니다. 온프레미스 네트워크에 포드 CIDR을 알리도록 Cilium BGP를 구성하는 방법에 대한 자세한 내용은 [하이브리드 노드에 대한 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_VERSION`을 대상 Cilium 버전으로 바꿉니다. Cilium 마이너 버전에 대한 최신 패치 버전을 실행하는 것이 좋습니다. 지정된 마이너 Cilium 릴리스에 대한 최신 패치 릴리스는 Cilium 설명서의 [안정적인 릴리스 섹션](https://github.com/cilium/cilium#stable-releases)에서 확인할 수 있습니다.

   ```
   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` 포드 수가 실행 중인 Cilium 포드 수와 동일한지 확인합니다.

   ```
   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. READY 포드 수가 같으면 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`에서 배포 값을 보존하거나 upgrade 명령을 실행할 때 설정에 `--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를 제거하면 노드 및 포드의 상태에 영향을 미칠 수 있으므로 프로덕션 클러스터에서 수행해서는 안 됩니다.

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

   CNI가 클러스터에서 제거되면 Cilium에서 구성한 인터페이스 및 경로가 기본적으로 제거되지 않습니다. 자세한 내용은 [GitHub issue](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 Hybrid Nodes에서 AWS 추가 기능 및 커뮤니티 추가 기능을 실행하기 위한 고려 사항을 설명합니다. Amazon EKS 추가 기능과 클러스터에서 추가 기능을 생성, 업그레이드, 제거하는 프로세스에 대한 자세한 내용은 [Amazon EKS 추가 기능](eks-add-ons.md) 섹션을 참조하세요. 이 페이지에서 별도로 명시되지 않는 한 Amazon EKS 추가 기능을 생성, 업그레이드, 제거하는 프로세스는 하이브리드 노드가 있는 Amazon EKS 클러스터의 경우 AWS 클라우드에서 실행 중인 노드가 있는 Amazon EKS 클러스터의 경우와 동일합니다. 이 페이지에 포함된 추가 기능만 Amazon EKS Hybrid Nodes와의 호환성이 검증되었습니다.

다음 AWS 추가 기능은 Amazon EKS Hybrid Nodes와 호환됩니다.


|  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 Observability Agent  |  v2.2.1-eksbuild.1 이상  | 
|  EKS Pod Identity 에이전트  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/hybrid-nodes-add-ons.html)  | 
|  노드 모니터링 에이전트  |  v1.2.0-eksbuild.1 이상  | 
|  CSI 스냅샷 컨트롤러  |  v8.1.0-eksbuild.1 이상  | 
|   AWS Private CA Connector for Kubernetes  |  v1.6.0-eksbuild.1 이상  | 
|  Amazon FSx CSI 드라이버  |  v1.7.0-eksbuild.1 이상  | 
|   AWS Secrets Store CSI 드라이버 공급자  |  v2.1.1-eksbuild.1 이상  | 

다음 커뮤니티 추가 기능은 Amazon EKS Hybrid Nodes와 호환됩니다. 커뮤니티 추가 기능에 대한 자세한 내용은 [커뮤니티 추가 기능](community-addons.md) 섹션을 참조하세요.


| 커뮤니티 추가 기능 | 호환되는 추가 기능 버전 | 
| --- | --- | 
|  Kubernetes 지표 서버  |  v0.7.2-eksbuild.1 이상  | 
|  cert-manager  |  v1.17.2-eksbuild.1 이상  | 
|  Prometheus 익스포터  |  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 Collector](prometheus.md)와 [애플리케이션 수신](alb-ingress.md)(HTTP) 및 [로드 밸런싱](network-load-balancing.md)(TCP/UDP)용 [AWS 로드 밸런서 컨트롤러](aws-load-balancer-controller.md)는 하이브리드 노드와 호환됩니다.

Amazon EKS Hybrid Nodes와 호환되지 않는 AWS 추가 기능 및 커뮤니티 추가 기능이 있습니다. 이러한 추가 기능의 최신 버전에는 하이브리드 노드에 적용되는 기본 `eks.amazonaws.com/compute-type: hybrid` 레이블에 대한 반선호도 규칙이 있습니다. 이렇게 하면 클러스터에 배포할 때 하이브리드 노드에서 실행되지 않습니다. 클러스터에 하이브리드 노드와 AWS 클라우드에서 실행되는 노드가 모두 있는 경우 AWS 클라우드에서 실행되는 노드에 클러스터의 추가 기능을 배포할 수 있습니다. Amazon VPC CNI는 하이브리드 노드와 호환되지 않으며, Cilium 및 Calico는 Amazon EKS Hybrid Nodes용 컨테이너 네트워킹 인터페이스(CNI)로 지원됩니다. 자세한 정보는 [하이브리드 노드에 대한 CNI 구성](hybrid-nodes-cni.md)을 참조하세요.

## AWS 추가 기능
<a name="hybrid-nodes-add-ons-aws-add-ons"></a>

다음 섹션에서는 다른 Amazon EKS 컴퓨팅 유형과 비교하여 하이브리드 노드에서 호환되는 AWS 추가 기능을 실행하는 것의 차이점을 설명합니다.

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

EKS는 AWS CLI를 포함하여 AWS API 및 AWS SDK를 사용하여 EKS 클러스터를 생성할 때 기본적으로 kube-proxy 및 CoreDNS를 자체 관리형 추가 기능으로 설치합니다. 클러스터 생성 후 Amazon EKS 추가 기능으로 이러한 추가 기능을 덮어쓸 수 있습니다. [Amazon EKS 클러스터에서 `kube-proxy` 관리](managing-kube-proxy.md) 및 [Amazon EKS 클러스터에서 DNS에 대한 CoreDNS 관리](managing-coredns.md)에 대한 자세한 내용은 EKS 설명서를 참조하세요. 하이브리드 노드와 AWS 클라우드의 노드가 있는 혼합 모드 클러스터를 실행하는 경우 AWS에서는 하이브리드 노드에는 하나 이상의 CoreDNS 복제본을, AWS 클라우드의 노드에는 하나 이상의 CoreDNS 복제본을 사용하는 것을 권장합니다. 구성 단계는 [CoreDNS 복제본 구성](hybrid-nodes-webhooks.md#hybrid-nodes-mixed-coredns) 섹션을 참조하세요.

## CloudWatch Observability Agent
<a name="hybrid-nodes-add-ons-cw"></a>

CloudWatch Observability Agent 연산자는 [웹후크](https://kubernetes.io/docs/reference/access-authn-authz/webhook/)를 사용합니다. 하이브리드 노드에서 연산자를 실행하는 경우 온프레미스 포드 CIDR은 온프레미스 네트워크에서 라우팅 가능해야 하며 원격 포드 네트워크로 EKS 클러스터를 구성해야 합니다. 자세한 내용은 [하이브리드 노드용 웹후크 구성](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)의 가용성에 좌우되기 때문에 노드 수준 지표는 하이브리드 노드에 사용할 수 없습니다. 클러스터, 워크로드, 포드, 컨테이너 수준 지표는 하이브리드 노드에 사용할 수 있습니다.

[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에서 원격 포드 네트워크 CIDR로의 경로와 온프레미스 방화벽에서 열린 포트를 포함하여 VPC에서 연결할 수 있어야 합니다. 또한 클러스터에는 [프라이빗 클러스터 엔드포인트 액세스](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 연산자는 승인 [웹후크](https://kubernetes.io/docs/reference/access-authn-authz/webhook/)를 사용하여 수집기 사용자 지정 리소스 요청을 변경 및 검증합니다. 하이브리드 노드에서 ADOT 연산자를 실행하는 경우 온프레미스 포드 CIDR은 온프레미스 네트워크에서 라우팅 가능해야 하며 원격 포드 네트워크로 EKS 클러스터를 구성해야 합니다. 자세한 내용은 [하이브리드 노드용 웹후크 구성](hybrid-nodes-webhooks.md)을 참조하세요.

*AWS Distro for OpenTelemetry* 설명서의 [EKS 추가 기능을 사용하여 AWS Distro for OpenTelemetry 시작하기](https://aws-otel.github.io/docs/getting-started/adot-eks-add-on)의 단계를 따릅니다.

## AWS 로드 밸런서 컨트롤러
<a name="hybrid-nodes-add-ons-lbc"></a>

하이브리드 노드의 워크로드에 대해 대상 유형이 `ip`인 [AWS Load Balancer Controller](aws-load-balancer-controller.md) 및 ALB(Application Load Balancer) 또는 NLB(Network Load Balancer)를 사용할 수 있습니다. ALB 또는 NLB에서 사용하는 IP 대상은 AWS에서 라우팅 가능해야 합니다. AWS Load Balancer Controller 역시 [웹후크](https://kubernetes.io/docs/reference/access-authn-authz/webhook/)를 사용합니다. 하이브리드 노드에서 AWS Load Balancer Controller 연산자를 실행하는 경우 온프레미스 포드 CIDR은 온프레미스 네트워크에서 라우팅 가능해야 하며 원격 포드 네트워크로 EKS 클러스터를 구성해야 합니다. 자세한 내용은 [하이브리드 노드용 웹후크 구성](hybrid-nodes-webhooks.md)을 참조하세요.

AWS 로드 밸런서 컨트롤러를 설치하려면 [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 Identity 에이전트
<a name="hybrid-nodes-add-ons-pod-id"></a>

**참고**  
Bottlerocket을 실행하는 하이브리드 노드에 EKS Pod Identity Agent 추가 기능을 성공적으로 배포하려면 Bottlerocket 버전이 v1.39.0 이상이어야 합니다. 하이브리드 노드 환경의 이전 Bottlerocket 버전에서는 Pod Identity Agent가 지원되지 않습니다.

원래 Amazon EKS Pod Identity 에이전트 DaemonSet는 노드에서 EC2 IMDS를 사용하여 필요한 AWS ID를 얻습니다. 버전 1.3.3-eksbuild.1부터는 하이브리드 노드에서 IMDS를 사용할 수 없으므로 Pod Identity Agent 추가 기능은 필요한 자격 증명을 탑재하는 DaemonSet를 선택적으로 배포합니다. Bottlerocket을 실행하는 하이브리드 노드는 자격 증명을 탑재하려면 다른 방법이 필요하며, 버전 1.3.7-eksbuild.2부터 Pod Identity Agent 추가 기능은 선택적으로 Bottlerocket 하이브리드 노드를 특별히 대상으로 하는 DaemonSet를 배포합니다. 다음 섹션에서는 선택적 DaemonSets를 활성화하는 프로세스를 설명합니다.

### Ubuntu/RHEL/AL2023
<a name="_ubunturhelal2023"></a>

1. Ubuntu/RHEL/Al2023 하이브리드 노드에서 Pod Identity 에이전트를 사용하려면 아래와 같이 `nodeadm` 구성의 하이브리드 섹션에서 `enableCredentialsFile: true`를 설정합니다.

   ```
   apiVersion: node.eks.aws/v1alpha1
   kind: NodeConfig
   spec:
       hybrid:
           enableCredentialsFile: true # <-- Add this
   ```

   이렇게 하면 `/eks-hybrid/.aws/credentials`에서 노드에 구성할 자격 증명 파일을 생성하도록 `nodeadm`이 구성되며, 이 파일은 `eks-pod-identity-agent` 포드에서 사용됩니다. 이 자격 증명 파일에는 주기적으로 새로 고침되는 임시 AWS 자격 증명이 포함됩니다.

1. *각* 노드에서 `nodeadm` 구성을 업데이트한 후 `nodeConfig.yaml`을 사용하여 다음 `nodeadm init` 명령을 실행하고 하이브리드 노드를 Amazon EKS 클러스터에 조인합니다. 노드가 이전에 클러스터에 조인한 경우 `nodeadm init` 명령을 다시 실행합니다.

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

1. AWS CLI 또는 AWS Management Console을 사용하여 하이브리드 노드에 대한 지원이 활성화된 상태로 `eks-pod-identity-agent`를 설치합니다.

   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 Management Console: AWS 콘솔을 통해 Pod Identity 에이전트 추가 기능을 설치하는 경우 선택적 구성에 다음을 추가하여 하이브리드 노드를 대상으로 하는 DaemonSet를 배포합니다.

      ```
      {"daemonsets":{"hybrid":{"create": true}}}
      ```

### Bottlerocket
<a name="_bottlerocket"></a>

1. Bottlerocket 하이브리드 노드에서 Pod Identity 에이전트를 사용하려면 [Bottlerocket을 실행하는 하이브리드 노드 연결](hybrid-nodes-bottlerocket.md)에 설명된 대로 Bottlerocket 부트스트랩 컨테이너 사용자 데이터에 사용되는 명령에 `--enable-credentials-file=true` 플래그를 추가합니다.

   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` 포드에서 사용됩니다. 이 자격 증명 파일에는 주기적으로 새로 고침되는 임시 AWS 자격 증명이 포함됩니다.

1. AWS CLI 또는 AWS Management Console을 사용하여 Bottlerocket 하이브리드 노드에 대한 지원이 활성화된 상태로 `eks-pod-identity-agent`를 설치합니다.

   1.  AWS CLI: 클러스터 관리에 사용하는 시스템에서 다음 명령을 실행하여 Bottlerocket 하이브리드 노드에 대한 지원이 활성화된 상태로 `eks-pod-identity-agent`를 설치합니다. `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 Management Console: AWS 콘솔을 통해 Pod Identity 에이전트 추가 기능을 설치하는 경우 선택적 구성에 다음을 추가하여 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)은 하이브리드 노드에 대해 소프트 반선호도 규칙을 적용하며, 컨트롤러 `deployment`가 Amazon EKS 컨트롤 플레인과 동일한 AWS 리전의 EC2에서 실행되는 것을 선호합니다. Amazon EKS 컨트롤 플레인과 동일한 AWS 리전에서 `deployment`를 공동 배치하면 지연 시간이 개선됩니다.

## 커뮤니티 추가 기능
<a name="hybrid-nodes-add-ons-community"></a>

다음 섹션에서는 다른 Amazon EKS 컴퓨팅 유형과 비교하여 하이브리드 노드에서 호환되는 커뮤니티 추가 기능을 실행하는 것의 차이점을 설명합니다.

## Kubernetes 지표 서버
<a name="hybrid-nodes-add-ons-metrics-server"></a>

컨트롤 플레인은 Metrics Server의 포드 IP(또는 hostNetwork가 활성화된 경우 노드 IP)에 도달해야 합니다. 따라서 hostNetwork 모드에서 Metrics Server를 실행하지 않는 한 Amazon EKS 클러스터를 생성할 때 원격 포드 네트워크를 구성해야 하고, 포드 IP 주소를 라우팅 가능하도록 설정해야 합니다. CNI를 사용하여 Border Gateway Protocol(BGP)을 구현하는 것은 포드 IP 주소를 라우팅 가능하도록 설정하는 일반적인 방법 중 하나입니다.

## cert-manager
<a name="hybrid-nodes-add-ons-cert-manager"></a>

 `cert-manager`는 [웹후크](https://kubernetes.io/docs/reference/access-authn-authz/webhook/)를 사용합니다. 하이브리드 노드에서 `cert-manager`를 실행하는 경우 온프레미스 포드 CIDR은 온프레미스 네트워크에서 라우팅 가능해야 하며 원격 포드 네트워크로 EKS 클러스터를 구성해야 합니다. 자세한 내용은 [하이브리드 노드용 웹후크 구성](hybrid-nodes-webhooks.md)을 참조하세요.

# 하이브리드 노드용 웹후크 구성
<a name="hybrid-nodes-webhooks"></a>

이 페이지에서는 하이브리드 노드에서 웹후크를 실행하는 것과 관련된 고려 사항을 자세히 설명합니다. 웹후크는 Kubernetes 애플리케이션과 AWS 로드 밸런서 컨트롤러 및 CloudWatch 관찰성 에이전트와 같은 오픈 소스 프로젝트에서 런타임 시 변경 및 검증 기능을 수행하는 데 사용됩니다.

 **라우팅 가능한 포드 네트워크** 

온프레미스 네트워크에서 온프레미스 포드 CIDR을 라우팅할 수 있는 경우 하이브리드 노드에서 웹후크를 실행할 수 있습니다. Border Gateway Protocol(BGP), 정적 경로 또는 기타 사용자 지정 라우팅 솔루션을 포함하여 온프레미스 네트워크에서 온프레미스 포드 CIDR을 라우팅 가능하도록 하는 데 몇 가지 기법을 사용할 수 있습니다. BGP는 사용자 지정 또는 수동 라우팅 구성이 필요한 대체 솔루션보다 더 확장성이 뛰어나고 관리하기 쉽기 때문에 권장되는 솔루션입니다. AWS는 포드 CIDR을 알리는 데 Cilium 및 Calico의 BGP 기능을 지원합니다. 자세한 내용은 [하이브리드 노드에 대한 CNI 구성](hybrid-nodes-cni.md) 및 [라우팅 가능한 원격 포드 CIDR](hybrid-nodes-concepts-kubernetes.md#hybrid-nodes-concepts-k8s-pod-cidrs) 섹션을 참조하세요.

 **라우팅 불가능한 포드 네트워크** 

온프레미스 네트워크에서 온프레미스 포드 CIDR을 라우팅 가능하도록 할 수 *없고* 웹후크를 실행해야 하는 경우 하이브리드 노드와 동일한 EKS 클러스터의 클라우드 노드에서 모든 웹후크를 실행하는 것이 좋습니다.

## 혼합 모드 클러스터 고려 사항
<a name="hybrid-nodes-considerations-mixed-mode"></a>

 *혼합 모드 클러스터*는 하이브리드 노드와 노드가 모두 AWS 클라우드에서 실행되는 EKS 클러스터로 정의됩니다. 혼합 모드 클러스터를 실행할 때는 다음 권장 사항을 고려하세요.
+ AWS 클라우드의 노드에서 VPC CNI를 실행하고 하이브리드 노드에서 Cilium 또는 Calico를 실행합니다. Cilium 및 Calico는 AWS 클라우드의 노드에서 실행할 때 AWS에서 지원되지 않습니다.
+ AWS 클라우드의 노드에서 실행되도록 웹후크를 구성합니다. AWS 및 커뮤니티 추가 기능용 웹후크를 구성하는 방법은 [추가 기능을 위한 웹후크 구성](#hybrid-nodes-webhooks-add-ons)을 참조하세요.
+ 애플리케이션이 하이브리드 노드에서 실행되는 포드와 직접 통신(‘동서 통신’)하기 위해 AWS 클라우드의 노드에서 실행되는 포드가 필요하고, 하이브리드 노드에서 AWS 클라우드 및 Cilium 또는 Calico의 노드에서 VPC CNI를 사용하는 경우 온프레미스 포드 CIDR은 온프레미스 네트워크에서 라우팅 가능해야 합니다.
+ AWS 클라우드의 노드에서 하나 이상의 CoreDNS 복제본을 실행하고 하이브리드 노드에서 하나 이상의 CoreDNS 복제본을 실행합니다.
+ 서비스 트래픽을 트래픽이 시작되는 영역에 로컬로 유지하도록 서비스 트래픽 분산을 구성합니다. 서비스 트래픽 분산에 대한 자세한 내용은 [서비스 트래픽 분산 구성](#hybrid-nodes-mixed-service-traffic-distribution)을 참조하세요.
+ 하이브리드 노드에서 실행되는 워크로드 트래픽에 AWS Application Load Balancer(ALB) 또는 Network Load Balancer(NLB)를 사용하는 경우 ALB 또는 NLB와 함께 사용되는 IP 대상이 AWS에서 라우팅 가능해야 합니다.
+ Metrics Server 추가 기능을 사용하려면 EKS 컨트롤 플레인에서 Metrics Server 포드 IP 주소로의 연결이 필요합니다. 하이브리드 노드에서 Metrics Server 추가 기능을 실행하는 경우 온프레미스 포드 CIDR이 온프레미스 네트워크에서 라우팅 가능해야 합니다.
+ Amazon Managed Service for Prometheus(AMP) 관리형 수집기를 사용하여 하이브리드 노드에 대한 지표를 수집하려면 온프레미스 포드 CIDR이 온프레미스 네트워크에서 라우팅 가능해야 합니다. 또는 AWS 클라우드에서 실행되는 EKS 컨트롤 플레인 지표와 리소스에 AMP 관리형 수집기를 사용하고, AWS Distro for OpenTelemetry(ADOT) 추가 기능을 사용하여 하이브리드 노드에 대한 지표를 수집할 수 있습니다.

## 혼합 모드 클러스터 구성
<a name="hybrid-nodes-mixed-mode"></a>

클러스터에서 실행되는 변형 및 검증 웹후크를 보려면 클러스터의 EKS 콘솔의 **리소스** 패널에서 **확장** 리소스 유형을 보거나 다음 명령을 사용할 수 있습니다. 또한 EKS는 클러스터 관찰성 대시보드에 웹후크 지표를 보고합니다. 자세한 내용은 [관찰성 대시보드를 사용하여 클러스터 모니터링](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로 사용하는 경우 `enable-service-topology`가 `true`로 설정된 CNI를 실행하여 서비스 트래픽 분산을 활성화해야 합니다. 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 복제본을 사용하는 것이 좋습니다. 혼합 모드 클러스터 설정에서 지연 및 네트워크 문제를 방지하려면 [서비스 트래픽 분산](https://kubernetes.io/docs/reference/networking/virtual-ips/#traffic-distribution)을 사용하여 가장 가까운 CoreDNS 복제본을 선호하도록 CoreDNS 서비스를 구성할 수 있습니다.

 *서비스 트래픽 분산*(EKS의 Kubernetes 버전 1.31 이상에서 사용 가능)은 예측 가능성이 더 높기 때문에 [토폴로지 인식 라우팅](https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/)보다 권장되는 솔루션입니다. 서비스 트래픽 분산에서는 영역 내의 정상 엔드포인트는 해당 영역의 모든 트래픽을 수신합니다. 토폴로지 인식 라우팅에서는 사용자 지정 라우팅을 적용하려면 각 서비스가 해당 영역의 여러 조건을 충족해야 합니다. 그렇지 않으면 트래픽을 모든 엔드포인트로 균등하게 라우팅합니다. 다음 단계에서는 서비스 트래픽 분산을 구성합니다.

Cilium을 CNI로 사용하는 경우 `enable-service-topology`가 `true`로 설정된 CNI를 실행하여 서비스 트래픽 분산을 활성화해야 합니다. 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. 토폴로지 영역 키가 있는 CoreDNS 배포에 `podAntiAffinity`를 추가합니다. 또는 설치 중에 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. 서비스 트래픽 분배를 활성화하려면 `kube-dns` 서비스 구성에 `trafficDistribution: PreferClose` 설정을 추가합니다.

   ```
   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
   ```

### 추가 기능을 위한 웹후크 구성
<a name="hybrid-nodes-webhooks-add-ons"></a>

다음 추가 기능은 웹후크를 사용하고 하이브리드 노드에서 사용할 수 있습니다.
+  AWS 로드 밸런서 컨트롤러
+ CloudWatch 관찰성 에이전트
+  AWS Distro for OpenTelemetry(ADOT)
+  `cert-manager` 

이러한 추가 기능이 AWS 클라우드의 노드에서 실행하도록 사용하는 웹후크를 구성하려면 다음 섹션을 참조하세요.

#### AWS 로드 밸런서 컨트롤러
<a name="hybrid-nodes-mixed-lbc"></a>

혼합 모드 클러스터 설정에서 AWS 로드 밸런서 컨트롤러를 사용하려면 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 관찰성 에이전트 추가 기능에는 웹후크를 사용하는 Kubernetes 연산자가 있습니다. 혼합 모드 클러스터 설정의 AWS 클라우드에 있는 노드에서 연산자를 실행하려면 CloudWatch Observability Agent 연산자 구성을 편집합니다. Helm 및 EKS 추가 기능을 사용하여 설치하는 동안에는 연산자 선호도를 구성할 수 없습니다([컨테이너-로드맵 문제 \$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) 추가 기능에는 웹후크를 사용하는 Kubernetes 연산자가 있습니다. 혼합 모드 클러스터 설정의 AWS 클라우드에 있는 노드에서 연산자를 실행하려면 Helm 값 구성에 다음을 추가하거나 EKS 추가 기능 구성을 사용하여 값을 지정합니다.

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

포드 CIDR이 온프레미스 네트워크에서 라우팅 가능하지 않은 경우 하이브리드 노드 및 해당 노드에서 실행 중인 워크로드에서 지표를 스크레이프할 수 있도록 ADOT Collector가 하이브리드 노드에서 실행되어야 합니다. 이렇게 하려면 사용자 지정 리소스 정의(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
```

ADOT Collector CRD 구성의 각 `scrape_configs`에 다음 `relabel_configs`를 추가하여 하이브리드 노드 및 하이브리드 노드에서 실행되는 리소스의 지표만 스크레이프하도록 ADOT Collector를 구성할 수 있습니다.

```
relabel_configs:
  - action: keep
    regex: hybrid
    source_labels:
    - __meta_kubernetes_node_label_eks_amazonaws_com_compute_type
```

ADOT 추가 기능에는 ADOT 연산자 웹후크에서 사용하는 TLS 인증서에 대해`cert-manager`를 설치하기 위한 사전 요구 사항이 있습니다. 또한 `cert-manager`는 웹후크를 실행하고 다음 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` 추가 기능은 웹후크를 실행하며, 다음 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의 기본 컨테이너 관리 런타임입니다. 인터넷 액세스에 프록시를 사용하는 경우 Kubernetes 및 Amazon EKS에 필요한 컨테이너 이미지를 가져올 수 있도록 `containerd`를 구성해야 합니다.

`/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 노드 에이전트이며 해당 노드에서 실행되는 노드 및 포드를 관리할 책임이 있습니다. 온프레미스 환경에서 프록시를 사용하는 경우 Amazon EKS 클러스터의 퍼블릭 또는 프라이빗 엔드포인트와 통신할 수 있도록 `kubelet`를 구성해야 합니다.

`/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`을 사용하는 경우 Amazon SSM 서비스 엔드포인트와 통신할 수 있도록 `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` 

노드에서 사용되는 운영 체제에 따라 아래 재시작 명령의 시스템 서비스 이름을 바꿉니다.
+ 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 Identity 에이전트](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는 하이브리드 노드가 클러스터에 조인할 때 각 하이브리드 노드에 DaemonSet로 `kube-proxy`를 자동으로 설치합니다. `kube-proxy`를 사용하면 Amazon EKS 클러스터의 포드가 지원하는 서비스 간에 라우팅할 수 있습니다. 각 호스트를 구성하려면 `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 Hybrid Nodes에 대한 Cilium Border Gateway Protocol(BGP)을 구성하는 방법을 설명합니다. Cilium의 BGP 기능은 [Cilium BGP Control Plane](https://docs.cilium.io/en/stable/network/bgp-control-plane/bgp-control-plane/)이라고 하며 포드 및 서비스 주소를 온프레미스 네트워크에 알리는 데 사용할 수 있습니다. 온프레미스 네트워크에서 포드 CIDR을 라우팅 가능하도록 하는 다른 방법은 [라우팅 가능한 원격 포드 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. BGP를 Cilium과 함께 사용하여 온프레미스 네트워크에 포드 또는 서비스 주소를 알리려면 `bgpControlPlane.enabled: true`로 Cilium을 설치해야 합니다. 기존 Cilium 배포에 대해 BGP를 활성화하는 경우 BGP가 이전에 활성화되지 않은 경우 BGP 구성을 적용하려면 Cilium 연산자를 다시 시작해야 합니다. 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. `CiliumBGPClusterConfig` 정의를 포함하여 `cilium-bgp-cluster.yaml` 파일을 생성합니다. 네트워크 관리자로부터 다음 정보를 얻어야 할 수 있습니다.
   + 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 Peer configuration](https://docs.cilium.io/en/latest/network/bgp-control-plane/bgp-control-plane-v2/#bgp-peer-configuration) 페이지를 참조하세요.

   다음 Cilium 피어 설정의 값은 피어링하려는 온프레미스 라우터의 값과 일치해야 합니다.
   + 세션의 중단 상태를 선언하기 전에 BGP 피어가 킵얼라이브 또는 업데이트 메시지를 기다리는 시간을 결정하는 `holdTimeSeconds`를 구성합니다. 기본값은 90초입니다.
   + BGP 피어가 계속 연결할 수 있고 BGP 세션이 활성 상태인지 여부를 결정하는 `keepAliveTimeSeconds`를 구성합니다. 기본값은 30초입니다.
   + 재시작 후 Cilium의 BGP Control Plane에서 BGP 세션을 다시 설정할 것으로 예상되는 시간을 결정하는 `restartTimeSeconds`를 구성합니다. 기본값은 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` 파일을 생성하여 포드 CIDR을 온프레미스 네트워크에 알립니다.
   + `CiliumBGPAdvertisement` 리소스는 광고 유형 및 이와 관련된 속성을 정의하는 데 사용됩니다. 아래 예시에서는 포드 CIDR만 알리도록 Cilium을 구성합니다. 서비스 주소를 알리도록 Cilium을 구성하는 방법에 대한 자세한 내용은 [Service 유형 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`로 설정된 경우 소유한 포드 CIDR 범위를 알립니다. 자세한 내용은 Cilium 문서의 [BGP Advertisements configuration](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` 명령을 사용하여 [Cilium CLI](https://docs.cilium.io/en/stable/gettingstarted/k8s-install-default/#install-the-cilium-cli)에서 작동하는 BGP 피어링을 확인할 수 있습니다. 환경에 대한 출력에 올바른 값이 표시되고 세션 상태가 `established`로 설정되어야 합니다. 문제 해결에 대한 자세한 내용은 Cilium 설명서의 [Troubleshooting and Operations Guide](https://docs.cilium.io/en/latest/network/bgp-control-plane/bgp-control-plane/#troubleshooting-and-operation-guide)를 참조하세요.

   아래 예시에서는 Cilium 에이전트를 실행하는 하이브리드 노드가 5개 있으며 각 노드는 소유한 포드 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 Hybrid Nodes에서 실행되는 워크로드에 대해 Kubernetes Ingress를 구성하는 방법을 설명합니다. [Kubernetes Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)는 클러스터 외부의 HTTP 및 HTTPS 경로를 클러스터 내의 서비스로 노출합니다. Ingress 리소스를 사용하려면 네트워크 트래픽을 처리하는 네트워킹 인프라 및 구성 요소 설정을 위해 Kubernetes Ingress 컨트롤러가 필요합니다.

 AWS는 EKS Hybrid Nodes에서 실행되는 워크로드에 대해 AWS ALB(Application Load Balancer) 및 Cilium for Kubernetes Ingress를 지원합니다. ALB 또는 Cilium for Ingress 중 무엇을 사용할지는 애플리케이션 트래픽의 소스를 기반으로 합니다. 애플리케이션 트래픽이 AWS 리전에서 발생하는 경우 AWS는 AWS ALB 및 AWS Load Balancer Controller 사용을 권장합니다. 애플리케이션 트래픽이 로컬 온프레미스 또는 엣지 환경에서 발생하는 경우 AWS는 환경에서 로드 밸런서 인프라 유무와 무관하게 사용할 수 있는 Cilium의 내장 Ingress 기능을 사용할 것을 권장합니다.

![\[EKS Hybrid Nodes Ingress\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/hybrid-nodes-ingress.png)


## AWS Application Load Balancer
<a name="hybrid-nodes-ingress-alb"></a>

하이브리드 노드에서 실행되는 워크로드의 대상 유형 `ip`에서 [AWS Load Balancer Controller](aws-load-balancer-controller.md) 및 ALB(Application Load Balancer)를 사용할 수 있습니다. 대상 유형 `ip`를 사용하는 경우 ALB는 Service 계층 네트워크 경로를 우회하여 트래픽을 포드로 직접 전달합니다. ALB가 하이브리드 노드의 포드 IP 대상에 도달하려면 온프레미스 포드 CIDR이 온프레미스 네트워크에서 라우팅 가능해야 합니다. 추가로 AWS Load Balancer Controller는 웹후크를 사용하며 EKS 컨트롤 플레인과의 직접 통신이 필요합니다. 자세한 내용은 [하이브리드 노드용 웹후크 구성](hybrid-nodes-webhooks.md) 섹션을 참조하세요.

### 고려 사항
<a name="_considerations"></a>
+ AWS Application Load Balancer 및 AWS Load Balancer Controller에 대한 자세한 내용은 [Application Load Balancer를 사용하여 애플리케이션 및 HTTP 트래픽 라우팅](alb-ingress.md) 및 [Helm을 사용하여 AWS Load Balancer Controller 설치](lbc-helm.md) 섹션을 참조하세요.
+ [로드 밸런싱 운영 모범 사례](https://docs.aws.amazon.com/eks/latest/best-practices/load-balacing.html) 섹션에서 AWS Application Load Balancer와 AWS Network Load Balancer 사이에서 선택하는 방법을 참조하세요.
+ [AWS Load Balancer Controller Ingress annotations](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/ingress/annotations/) 섹션에서 AWS Application Load Balancer로 Ingress 리소스에 대해 구성할 수 있는 주석 목록을 참조하세요.

### 사전 조건
<a name="_prerequisites"></a>
+ [하이브리드 노드에 대한 CNI 구성](hybrid-nodes-cni.md)의 지침에 따라 Cilium이 설치되어 있습니다.
+ [하이브리드 노드에 대한 Cilium BGP 구성](hybrid-nodes-cilium-bgp.md)의 지침에 따라 Cilium BGP 컨트롤 플레인이 활성화되어 있습니다. BGP를 사용하지 않으려면 다른 방법을 사용하여 온프레미스 포드 CIDR이 온프레미스 네트워크에서 라우팅할 수 있도록 해야 합니다. 온프레미스 포드 CIDR을 라우팅할 수 있도록 하지 않으면 ALB가 포드 IP 대상을 등록하거나 연결할 수 없습니다.
+ 명령줄 환경에 설치된 Helm에 대한 자세한 내용은 [Helm 설정 지침](helm.md)을 참조하세요.
+ 명령줄 환경에 설치된 eksctl에 대한 자세한 내용은 [eksctl 설정 지침](install-kubectl.md#eksctl-install-update)을 참조하세요.

### 절차
<a name="_procedure"></a>

1. 사용자 대신 AWS API를 직접 호출할 수 있는 AWS 로드 밸런서 컨트롤러의 IAM 정책을 다운로드합니다.

   ```
   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 차트 리포지토리를 추가하고 최신 차트가 적용되도록 로컬 Helm 리포지토리를 업데이트합니다.

   ```
   helm repo add eks https://aws.github.io/eks-charts
   ```

   ```
   helm repo update eks
   ```

1. AWS 로드 밸런서 컨트롤러를 설치합니다. 클러스터 이름(`CLUSTER_NAME`), AWS 리전(`AWS_REGION`), VPC ID(`VPC_ID`) 및 AWS Load Balancer Controller Helm 차트 버전(`AWS_LBC_HELM_VERSION`)의 값을 사용자 설정에 맞춰 바꾸고 다음 명령을 실행합니다. 하이브리드 노드와 AWS 클라우드의 노드가 모두 있는 혼합 모드 클러스터를 실행하는 경우 [AWS 로드 밸런서 컨트롤러](hybrid-nodes-webhooks.md#hybrid-nodes-mixed-lbc)의 지침에 따라 클라우드 노드에서 AWS Load Balancer Controller를 실행할 수 있습니다.
   + `helm search repo eks/aws-load-balancer-controller --versions`를 실행하여 최신 버전의 Helm 차트를 찾을 수 있습니다.

     ```
     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 Controller가 성공적으로 설치되었는지 확인합니다.

   ```
   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. 클러스터에 Ingress 구성을 적용합니다.

   ```
   kubectl apply -f my-ingress-alb.yaml
   ```

1. Ingress 리소스에 ALB를 프로비저닝하는 데 몇 분 정도 걸릴 수 있습니다. ALB가 프로비저닝되면 Ingress 리소스에 NLB 배포의 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의 주소를 사용하여 Service에 액세스합니다.

   ```
   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의 Ingress 기능은 Cilium의 아키텍처에 내장되어 있으며 Kubernetes Ingress API 또는 Gateway API로 관리할 수 있습니다. 기존 Ingress 리소스가 없는 경우 AWS에서는 Kubernetes 네트워킹 리소스를 정의하고 관리하는 보다 표현적이고 유연한 방법이므로 Gateway API로 시작할 것을 권장합니다. [Kubernetes Gateway API](https://gateway-api.sigs.k8s.io/)는 Kubernetes 클러스터에서 Ingress, 로드 밸런싱 및 서비스 메시에 대한 네트워킹 리소스를 정의 및 관리하는 방법을 표준화하는 것을 목표로 합니다.

Cilium의 Ingress 또는 Gateway 기능을 활성화하면 Cilium 운영자는 클러스터의 Ingress/Gateway 객체를 조정하고 각 노드의 Envoy 프록시는 L7(계층 7) 네트워크 트래픽을 처리합니다. Cilium은 로드 밸런서와 같은 Ingress/Gateway 인프라를 직접 프로비저닝하지 않습니다. 로드 밸런서에서 Cilium Ingress/Gateway를 사용하려는 경우 일반적으로 Ingress 또는 Gateway 컨트롤러인 로드 밸런서의 도구를 사용하여 로드 밸런서의 인프라를 배포 및 관리해야 합니다.

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 기능이 요약되어 있습니다.


| Feature | Ingress | 게이트웨이 | 
| --- | --- | --- | 
|  Service 유형 LoadBalancer  |  예  |  예  | 
|  Service 유형 NodePort  |  예  |  아니요1   | 
|  호스트 네트워크  |  예  |  예  | 
|  공유 로드 밸런서  |  예  |  예  | 
|  전용 로드 밸런서  |  예  |  아니요2   | 
|  네트워크 정책  |  예  |  예  | 
|  프로토콜  |  계층 7(HTTP(S), gRPC)  |  계층 7(HTTP(S), gRPC)3   | 
|  TLS 패스스루  |  예  |  예  | 
|  트래픽 관리  |  경로 및 호스트 라우팅  |  경로 및 호스트 라우팅, URL 리디렉션 및 재작성, 트래픽 분할, 헤더 수정  | 

 1 Cilium 버전 1.18.x에서 NodePort 서비스에 대한 Cilium Gateway 지원이 계획되어 있음([\$127273](https://github.com/cilium/cilium/pull/27273))

 2 전용 로드 밸런서에 대한 Cilium Gateway 지원([\$125567](https://github.com/cilium/cilium/issues/25567))

 3 TCP/UDP에 대한 Cilium Gateway 지원([\$121929](https://github.com/cilium/cilium/issues/21929))

## Cilium Gateway 설치
<a name="hybrid-nodes-ingress-cilium-gateway-install"></a>

### 고려 사항
<a name="_considerations_2"></a>
+ 아래 예시와 같이 `nodePort.enabled`가 `true`로 설정된 상태에서 Cilium을 구성해야 합니다. Cilium의 kube-proxy 대체 기능을 사용하는 경우 `nodePort.enabled`를 `true`로 설정할 필요가 없습니다.
+ 아래 예시와 같이 `envoy.enabled`가 `true`로 설정된 상태에서 Cilium을 구성해야 합니다.
+ Cilium Gateway는 로드 밸런서(기본값) 또는 호스트 네트워크 모드로 배포할 수 있습니다.
+ 로드 밸런서 모드에서 Cilium Gateway를 사용하는 경우 레거시 AWS 클라우드 공급자가 Cilium이 Gateway 리소스에 대해 생성하는 LoadBalancer 유형의 Service에 대해 Classic Load Balancer를 생성하지 못하도록 Gateway 리소스에 `service.beta.kubernetes.io/aws-load-balancer-type: "external"` 주석이 설정되어야 합니다.
+ 호스트 네트워크 모드에서 Cilium Gateway를 사용하는 경우 LoadBalancer 유형의 Service가 비활성화됩니다. 호스트 네트워크 모드는 로드 밸런서 인프라가 없는 환경에 유용합니다. 자세한 내용은 [호스트 네트워크](#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 Gateway 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`이라는 파일을 생성합니다: 아래 예시에서는 기본 로드 밸런서 모드를 사용하고 하이브리드 노드에서만 실행되도록 구성된 별도의 Envoy 프록시용 `cilium-envoy` DaemonSet를 사용하도록 Cilium Gateway를 구성합니다.

   ```
   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 포드가 실행 중인지 확인합니다.

   ```
   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>

Cilium Gateway는 `gatewayClassName`을 `cilium`으로 설정하여 Gateway 객체에서 활성화됩니다. Cilium이 Gateway 리소스에 대해 생성하는 Service는 Gateway 객체의 필드로 구성할 수 있습니다. Gateway 컨트롤러가 로드 밸런서 인프라를 구성하는 데 사용하는 일반적인 주석은 Gateway 객체의 `infrastructure` 필드를 사용하여 구성할 수 있습니다. Cilium의 LoadBalancer IPAM을 사용하는 경우([Service 유형 LoadBalancer](#hybrid-nodes-ingress-cilium-loadbalancer)의 예시 참조), LoadBalancer 유형의 Service에 사용할 IP 주소를 Gateway 객체의 `addresses` 필드에 구성할 수 있습니다. Gateway 구성에 대한 자세한 내용은 [Kubernetes Gateway API specification](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, Gateway, 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 클라우드 공급자가 Cilium이 Gateway 리소스에 대해 생성하는 LoadBalancer 유형의 Service에 대한 Classic Load Balancer를 생성하지 못하도록 합니다.

   ```
   ---
   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. Gateway 리소스를 클러스터에 적용합니다.

   ```
   kubectl apply -f my-gateway.yaml
   ```

1. Gateway 리소스와 해당 Service가 생성되었는지 확인합니다. 이 단계에서는 Gateway 리소스의 `ADDRESS` 필드가 IP 주소 또는 호스트 이름으로 채워지지 않고, Gateway 리소스에 대한 LoadBalancer 유형의 Service에 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. [Service 유형 LoadBalancer](#hybrid-nodes-ingress-cilium-loadbalancer)에서 Cilium LoadBalancer IPAM에 의해 할당된 IP 주소를 사용하도록 Gateway 리소스를 구성하고, [Service 유형 NodePort](#hybrid-nodes-ingress-cilium-nodeport) 또는 [호스트 네트워크](#hybrid-nodes-ingress-cilium-host-network)에서 NodePort 또는 호스트 네트워크 주소를 사용하도록 Gateway 리소스를 구성합니다.

## Cilium Ingress 설치
<a name="hybrid-nodes-ingress-cilium-ingress-install"></a>

### 고려 사항
<a name="_considerations_3"></a>
+ 아래 예시와 같이 `nodePort.enabled`가 `true`로 설정된 상태에서 Cilium을 구성해야 합니다. Cilium의 kube-proxy 대체 기능을 사용하는 경우 `nodePort.enabled`를 `true`로 설정할 필요가 없습니다.
+ 아래 예시와 같이 `envoy.enabled`가 `true`로 설정된 상태에서 Cilium을 구성해야 합니다.
+ `ingressController.loadbalancerMode`가 `dedicated`로 설정되면 Cilium은 각 Ingress 리소스에 대한 전용 Service를 생성합니다. `ingressController.loadbalancerMode`가 `shared`로 설정되면 Cilium은 클러스터의 모든 Ingress 리소스에 대해 LoadBalancer 유형의 공유 Service를 생성합니다. `shared` 로드 밸런서 모드를 사용하는 경우 `labels`, `annotations`, `type` 및 `loadBalancerIP` 등 공유 Service에 대한 설정이 Helm 값의 `ingressController.service` 섹션에 구성됩니다. 자세한 내용은 [Cilium Helm values reference](https://github.com/cilium/cilium/blob/v1.17.6/install/kubernetes/cilium/values.yaml#L887) 페이지를 참조하세요.
+ `ingressController.default`가 `true`로 설정되면 Cilium이 클러스터의 기본 Ingress 컨트롤러로 구성되고 `ingressClassName`가 Ingress 리소스에 지정되지 않은 경우에도 Ingress 항목을 생성합니다.
+ Cilium Ingress는 로드 밸런서(기본값), 노드 포트 또는 호스트 네트워크 모드에서 배포될 수 있습니다. 호스트 네트워크 모드에서 Cilium이 설치되면 LoadBalancer 유형의 Service 및 NodePort 유형의 Service가 비활성화됩니다. 자세한 정보는 [호스트 네트워크](#hybrid-nodes-ingress-cilium-host-network)을 참조하세요.
+ 레거시 AWS 클라우드 공급자가 [Cilium Helm 차트](https://github.com/cilium/cilium/blob/main/install/kubernetes/cilium/templates/cilium-ingress-service.yaml)에서 생성된 기본 `cilium-ingress` 서비스에 대해 Classic Load Balancer를 생성하지 못하도록 항상 Helm 값에서 `ingressController.service.annotations`를 `service.beta.kubernetes.io/aws-load-balancer-type: "external"`로 설정합니다.

### 사전 조건
<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`이라는 파일을 생성합니다: 아래 예시에서는 기본 로드 밸런서 `dedicated` 모드를 사용하고 하이브리드 노드에서만 실행되도록 구성된 별도의 Envoy 프록시용 `cilium-envoy` DaemonSet를 사용하도록 Cilium Ingress를 구성합니다.

   ```
   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 포드가 실행 중인지 확인합니다.

   ```
   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>

Cilium Ingress는 `ingressClassName`을 `cilium`으로 설정하여 Ingress 객체에서 활성화됩니다. Cilium이 Ingress 리소스에 대해 생성하는 Service는 `dedicated` 로드 밸런서 모드를 사용할 때 Ingress 객체의 주석으로, 그리고 `shared` 로드 밸런서 모드를 사용할 때 Cilium/Helm 구성으로 구성할 수 있습니다. 이러한 주석은 일반적으로 Ingress 컨트롤러에서 로드 밸런서 인프라, 또는 서비스 유형, 로드 밸런서 모드, 포트 및 TLS 패스스루 등 Service의 기타 속성을 구성하는 데 사용됩니다. 주요 주석은 아래에서 설명합니다. 지원되는 주석의 전체 목록은 Cilium 문서의 [Cilium Ingress annotations](https://docs.cilium.io/en/stable/network/servicemesh/ingress/#supported-ingress-annotations) 페이지를 참조하세요.


| Annotation | 설명 | 
| --- | --- | 
|   `ingress.cilium.io/loadbalancer-mode`   |   `dedicated`: 각 Ingress 리소스에 대한 LoadBalancer 유형의 전용 Service입니다(기본값).  `shared`: 모든 Ingress 리소스에 대해 LoadBalancer 유형의 단일 Service입니다.  | 
|   `ingress.cilium.io/service-type`   |   `LoadBalancer`: Service는 LoadBalancer 유형입니다(기본값).  `NodePort`: Service는 NodePort 유형입니다.  | 
|   `service.beta.kubernetes.io/aws-load-balancer-type`   |   `"external"`: 레거시 AWS 클라우드 공급자가 LoadBalancer 유형의 Service에 대해 Classic Load Balancer를 프로비저닝할 수 없습니다.  | 
|   `lbipam.cilium.io/ips`   |  Cilium LoadBalancer IPAM에서 할당할 IP 주소 목록  | 

Cilium 및 Kubernetes Ingress 사양은 Ingress 경로에 대해 정확, 접두사 및 구현별 일치 규칙을 지원합니다. Cilium은 정규식을 구현별 일치 규칙으로 지원합니다. 자세한 내용은 Cilium 문서의 [Ingress path types and precedence](https://docs.cilium.io/en/stable/network/servicemesh/ingress/#ingress-path-types-and-precedence) 및 [Path types examples](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 클라우드 공급자가 Cilium이 Ingress 리소스에 대해 생성하는 LoadBalancer 유형의 Service에 대한 Classic Load Balancer를 생성하지 못하도록 합니다.

   ```
   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. 클러스터에 Ingress 리소스를 적용합니다.

   ```
   kubectl apply -f my-ingress.yaml
   ```

1. Ingress 리소스와 해당 Service가 생성되었는지 확인합니다. 이 단계에서는 Ingress 리소스의 `ADDRESS` 필드가 IP 주소 또는 호스트 이름으로 채워지지 않고, Ingress 리소스에 대한 LoadBalancer 유형의 공유 또는 전용 Service에 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. [Service 유형 LoadBalancer](#hybrid-nodes-ingress-cilium-loadbalancer)에서 Cilium LoadBalancer IPAM에 의해 할당된 IP 주소를 사용하도록 Ingress 리소스를 구성하고, [Service 유형 NodePort](#hybrid-nodes-ingress-cilium-nodeport) 또는 [호스트 네트워크](#hybrid-nodes-ingress-cilium-host-network)에서 NodePort 또는 호스트 네트워크 주소를 사용하도록 Ingress 리소스를 구성합니다.

## Service 유형 LoadBalancer
<a name="hybrid-nodes-ingress-cilium-loadbalancer"></a>

### 기존 로드 밸런서 인프라
<a name="_existing_load_balancer_infrastructure"></a>

기본적으로 Cilium Ingress 및 Cilium Gateway 모두에서 Cilium은 Ingress/Gateway 리소스에 대해 LoadBalancer 유형의 Kubernetes Service를 생성합니다. Cilium에서 생성하는 Service의 속성은 Ingress 및 Gateway 리소스를 통해 구성할 수 있습니다. Ingress 또는 Gateway 리소스를 생성할 때 Ingress 또는 Gateway에 대해 외부에 노출된 IP 주소 또는 호스트 이름은 일반적으로 Ingress 또는 Gateway 컨트롤러에 의해 프로비저닝되는 로드 밸런서 인프라에서 할당됩니다.

많은 Ingress 및 Gateway 컨트롤러가 주석을 사용하여 로드 밸런서 인프라를 감지 및 구성합니다. 이러한 Ingress 및 Gateway 컨트롤러에 대한 주석은 위의 이전 예시와 같이 Ingress 또는 Gateway 리소스에 구성됩니다. 지원되는 주석은 Ingress 또는 Gateway 컨트롤러 문서를 참조하고, 주로 사용하는 컨트롤러 목록은 [Kubernetes Ingress 문서](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/) 및 [Kubernetes Gateway 문서](https://gateway-api.sigs.k8s.io/implementations/)를 참조하세요.

**중요**  
Cilium Ingress 및 Gateway는 EKS Hybrid Nodes와 함께 AWS Load Balancer Controller 및 AWS NLB(Network Load Balancer)에서 사용할 수 없습니다. 함께 사용하려고 하면 NLB의 `target-type`이 `ip`로 설정된 경우 NLB가 LoadBalancer 유형의 Service를 지원하는 포드 IP에 직접 연결하려고 시도하므로 등록되지 않은 대상이 됩니다(ETS Hybrid Nodes에서 실행되는 워크로드에서 NLB를 사용하는 경우의 요구 사항).

### 로드 밸런서 인프라 없음
<a name="_no_load_balancer_infrastructure"></a>

환경에 로드 밸런서 인프라 및 해당 Ingress/Gateway 컨트롤러가 없는 경우 Cilium의 [LB IAM(로드 밸런서 IP 주소 관리)](https://docs.cilium.io/en/stable/network/lb-ipam/)을 사용하도록 Ingress/Gateway 리소스와 해당하는 LoadBalancer 유형의 Service를 구성할 수 있습니다. Cilium LB IPAM은 온프레미스 환경의 알려진 IP 주소 범위로 구성할 수 있고, Cilium의 기본 제공 Border Gateway Protocol(BGP) 지원 또는 L2 알림을 사용하여 LoadBalancer IP 주소를 온프레미스 네트워크에 알릴 수 있습니다.

아래 예시에서는 Ingress/Gateway 리소스에 사용할 IP 주소로 Cilium의 LB IPAM을 구성하는 방법과 온프레미스 네트워크로 LoadBalancer IP 주소를 알리도록 Cilium BGP Control Plane을 구성하는 방법을 보여줍니다. 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 주소가 온프레미스 네트워크에서 라우팅될 때까지 Ingress 또는 Gateway 리소스에 액세스할 수 없습니다.

#### 절차
<a name="_procedure_4"></a>

1. 선택적으로 Ingress 또는 Gateway 리소스 패치를 적용하여 LoadBalancer 유형의 Service에 사용할 특정 IP 주소를 요청합니다. 특정 IP 주소를 요청하지 않으면 Cilium은 후속 단계에서 `CiliumLoadBalancerIPPool` 리소스에 구성된 IP 주소 범위에서 IP 주소를 할당합니다. 아래 명령에서 `LB_IP_ADDRESS`를 LoadBalancer 유형의 Service에 요청할 IP 주소로 바꿉니다.

    **Gateway** 

   ```
   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. Ingress/Gateway 리소스에 대한 로드 밸런서 IP 주소 범위를 구성하는 `CiliumLoadBalancerIPPool` 리소스를 포함하여 `cilium-lbip-pool-ingress.yaml` 파일을 생성합니다.
   + Cilium Ingress를 사용하는 경우 Cilium은 Ingress 리소스에 대해 생성한 Service에 `cilium.io/ingress: "true"` 레이블을 자동으로 적용합니다. `CiliumLoadBalancerIPPool` 리소스 정의의 `serviceSelector` 필드에서 이 레이블을 사용하여 LB IPAM에 적합한 Service를 선택할 수 있습니다.
   + Cilium Gateway를 사용하는 경우 `CiliumLoadBalancerIPPool` 리소스 정의의 `serviceSelector` 필드에 있는 `gateway.networking.k8s.io/gateway-name` 레이블을 사용하여 LB IPAM에 적합한 Gateway 리소스를 선택할 수 있습니다.
   + `LB_IP_CIDR`을 로드 밸런서 IP 주소에 사용할 IP 주소 범위로 바꿉니다. 단일 IP 주소를 선택하려면 `/32` CIDR을 사용합니다. 자세한 내용은 Cilium 설명서의 [LoadBalancer IP Address Management](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. Ingress/Gateway 리소스에 대해 Cilium LB IPAM에서 IP 주소가 할당되었는지 확인합니다.

    **Gateway** 

   ```
   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. Ingress/Gateway 리소스에 대한 LoadBalancer IP 주소를 알리는 `CiliumBGPAdvertisement` 리소스를 포함하여 `cilium-bgp-advertisement-ingress.yaml` 파일을 생성합니다. Cilium BGP를 사용하지 않는 경우 이 단계를 건너뛸 수 있습니다. Ingress/Gateway 리소스에 사용되는 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 주소를 사용하여 Service에 액세스합니다.

   ```
   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"
   }
   ```

## Service 유형 NodePort
<a name="hybrid-nodes-ingress-cilium-nodeport"></a>

환경에 로드 밸런서 인프라와 해당 Ingress 컨트롤러가 없는 경우, 또는 로드 밸런서 인프라를 자체 관리하거나 DNS 기반 로드 밸런싱을 사용하는 경우 Cilium Ingress를 구성하여 Ingress 리소스에 대해 NodePort 유형의 Service를 생성할 수 있습니다. Cilium Ingress에서 NodePort를 사용하는 경우 NodePort 유형의 Service는 포트 범위 30000-32767의 각 노드에 있는 포트에 노출됩니다. 이 모드에서 트래픽이 NodePort의 클러스터에 있는 노드에 도달하면 동일한 노드 또는 다른 노드에 있을 수 있는 서비스를 지원하는 포드로 전달됩니다.

**참고**  
Cilium 버전 1.18.x에서 NodePort 서비스에 대한 Cilium Gateway 지원이 계획되어 있음([\$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. 기존 Ingress 리소스 `my-ingress`에 패치를 적용하여 Service 유형을 LoadBalancer에서 NodePort로 변경합니다.

   ```
   kubectl patch ingress my-ingress --type=merge -p '{
       "metadata": {"annotations": {"ingress.cilium.io/service-type": "NodePort"}}
   }'
   ```

   Ingress 리소스를 생성하지 않은 경우 다음 Ingress 정의를 클러스터에 적용하여 생성할 수 있습니다. 아래 Ingress 정의는 [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. Service 유형 NodePort를 사용하도록 Ingress 리소스에 대한 Service가 업데이트되었는지 확인합니다. 출력에서 HTTP 프로토콜의 포트를 기록합니다. 아래 예시에서 이 HTTP 포트는 `32353`이고, 이는 후속 단계에서 Service를 쿼리하는 데 사용됩니다. NodePort 유형의 Service에서 Cilium Ingress를 사용하면 Ingress 트래픽에 대한 네트워크 정책뿐만 아니라 경로 및 호스트 기반 라우팅을 적용할 수 있으며, Ingress가 없는 NodePort 유형의 표준 Service에서는 적용할 수 없습니다.

   ```
   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 유형의 Service에 액세스합니다. 아래 예시에서 사용된 노드 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 유형의 Service와 마찬가지로 로드 밸런서 인프라와 Ingress 또는 Gateway 컨트롤러가 없는 경우, 또는 외부 로드 밸런서를 사용하여 로드 밸런싱을 자체 관리하는 경우 호스트 네트워크에서 직접 Ingress 및 Gateway 리소스를 노출하도록 Cilium Ingress 및 Cilium Gateway를 구성할 수 있습니다. Ingress 또는 Gateway 리소스에 대해 호스트 네트워크 모드가 활성화되면 LoadBalancer 유형의 Service 및 NodePort 모드가 자동으로 비활성화되고, 호스트 네트워크 모드는 각 Ingress 또는 Gateway 리소스에 대해 이러한 대체 모드와 상호 배타적입니다. NodePort 유형의 Service에 비해 호스트 네트워크 모드는 추가로 유연하게 포트 범위를 사용할 수 있고(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
   ```

   Gateway 리소스를 생성하지 않은 경우 다음 Gateway 정의를 클러스터에 적용하여 생성할 수 있습니다. 아래 Gateway 정의는 [Cilium Gateway 배포](#hybrid-nodes-ingress-cilium-gateway-deploy)에서 설명하는 Istio Bookinfo 샘플 애플리케이션을 사용합니다. 아래 예시에서 Gateway 리소스는 호스트 네트워크에서 실행되는 Envoy 프록시의 공유 리스너 포트인 HTTP 리스너의 `8111` 포트를 사용하도록 구성됩니다. Gateway 리소스에 대한 권한 있는 포트(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` Service에 대한 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` 리소스의 리스너 포트를 사용하여 Service에 액세스합니다. 아래 예시에서 사용된 노드 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` 사용이 필요하고, 이로 인해 클러스터의 모든 Ingress 리소스에 대해 ClusterIP 유형의 단일 Service가 생성됩니다. Ingress 리소스에 대한 권한 있는 포트(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
   ```

   Ingress 리소스를 생성하지 않은 경우 다음 Ingress 정의를 클러스터에 적용하여 생성할 수 있습니다. 아래 Ingress 정의는 [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` Service에 대한 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`를 사용하여 Service에 액세스합니다. 아래 예시에서 사용된 노드 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 유형의 Service 구성
<a name="hybrid-nodes-load-balancing"></a>

이 주제에서는 Amazon EKS Hybrid Nodes에서 실행되는 애플리케이션에 대해 계층 4(L4) 로드 밸런싱을 구성하는 방법을 설명합니다. LoadBalancer 유형의 Kubernetes Service는 클러스터 외부에 Kubernetes 애플리케이션을 노출하는 데 사용됩니다. LoadBalancer 유형의 Service는 일반적으로 클라우드 또는 온프레미스 환경의 물리적 로드 밸런서 인프라에서 사용되어 워크로드의 트래픽을 처리합니다. 이 로드 밸런서 인프라는 일반적으로 환경별 컨트롤러로 프로비저닝됩니다.

 AWS는 EKS Hybrid Nodes에서 실행되는 LoadBalancer 유형의 Service에 대해 AWS Network Load Balancer(NLB) 및 Cilium을 지원합니다. NLB 또는 Cilium 중 무엇을 사용할지는 애플리케이션 트래픽의 소스를 기반으로 합니다. 애플리케이션 트래픽이 AWS 리전에서 발생하는 경우 AWS는 AWS NLB 및 AWS Load Balancer Controller 사용을 권장합니다. 애플리케이션 트래픽이 로컬 온프레미스 또는 엣지 환경에서 발생하는 경우 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 Controller](aws-load-balancer-controller.md) 및 NLB를 사용할 수 있습니다. 대상 유형 `ip`를 사용하는 경우 NLB는 Service 계층 네트워크 경로를 우회하여 트래픽을 포드로 직접 전달합니다. NLB가 하이브리드 노드의 포드 IP 대상에 도달하려면 온프레미스 포드 CIDR이 온프레미스 네트워크에서 라우팅 가능해야 합니다. 추가로 AWS Load Balancer Controller는 웹후크를 사용하며 EKS 컨트롤 플레인과의 직접 통신이 필요합니다. 자세한 내용은 [하이브리드 노드용 웹후크 구성](hybrid-nodes-webhooks.md) 섹션을 참조하세요.
+ 서브넷 구성 요구 사항은 [Network Load Balancer를 사용하여 TCP 및 UDP 트래픽 라우팅](network-load-balancing.md) 섹션을 참조하고, [Helm을 사용하여 AWS Load Balancer Controller 설치](lbc-helm.md) 및 [로드 밸런싱 운영 모범 사례](https://docs.aws.amazon.com/eks/latest/best-practices/load-balancing.html) 섹션에서 AWS Network Load Balancer 및 AWS Load Balancer Controller에 대한 추가 정보를 참조하세요.
+ [AWS Load Balancer Controller NLB configurations](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/service/nlb/) 섹션에서 AWS Network Load Balancer를 사용하는 `LoadBalancer` 유형의 Service에 적용할 수 있는 구성을 참조하세요.

### 사전 조건
<a name="_prerequisites"></a>
+ [하이브리드 노드에 대한 CNI 구성](hybrid-nodes-cni.md)의 지침에 따라 Cilium이 설치되어 있습니다.
+ [하이브리드 노드에 대한 Cilium BGP 구성](hybrid-nodes-cilium-bgp.md)의 지침에 따라 Cilium BGP 컨트롤 플레인이 활성화되어 있습니다. BGP를 사용하지 않으려면 다른 방법을 사용하여 온프레미스 포드 CIDR이 온프레미스 네트워크에서 라우팅할 수 있도록 해야 합니다. 자세한 내용은 [라우팅 가능한 원격 포드 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 API를 직접 호출할 수 있는 AWS 로드 밸런서 컨트롤러의 IAM 정책을 다운로드합니다.

   ```
   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 차트 리포지토리를 추가합니다. AWS에서는 이 리포지토리를 GitHub에 유지합니다.

   ```
   helm repo add eks https://aws.github.io/eks-charts
   ```

1. 최신 차트가 적용되도록 로컬 Helm 리포지토리를 업데이트합니다.

   ```
   helm repo update eks
   ```

1. AWS 로드 밸런서 컨트롤러를 설치합니다. 클러스터 이름(`CLUSTER_NAME`), AWS 리전(`AWS_REGION`), VPC ID(`VPC_ID`) 및 AWS Load Balancer Controller Helm 차트 버전(`AWS_LBC_HELM_VERSION`)의 값을 사용자 설정에 맞춰 바꿉니다. `helm search repo eks/aws-load-balancer-controller --versions`를 실행하여 최신 버전의 Helm 차트를 찾을 수 있습니다. 하이브리드 노드와 AWS 클라우드의 노드가 모두 있는 혼합 모드 클러스터를 실행하는 경우 [AWS 로드 밸런서 컨트롤러](hybrid-nodes-webhooks.md#hybrid-nodes-mixed-lbc)의 지침에 따라 클라우드 노드에서 AWS Load Balancer Controller를 실행할 수 있습니다.

   ```
   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 Controller가 성공적으로 설치되었는지 확인합니다.

   ```
   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 유형의 Service를 정의합니다.

   ```
   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. 클러스터에 Service 구성을 적용합니다.

   ```
   kubectl apply -f tcp-sample-service.yaml
   ```

1. Service에 대한 NLB를 프로비저닝하는 데 몇 분 정도 걸릴 수 있습니다. NLB가 프로비저닝되면 Service에 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의 주소를 사용하여 Service에 액세스합니다.

   ```
   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 Hybrid Nodes에서 실행되는 워크로드의 클러스터 내 로드 밸런서로 사용할 수 있으며, 로드 밸런서 인프라가 없는 환경에 유용할 수 있습니다. Cilium의 로드 밸런싱 기능은 kube-proxy 대체, LoadBalancer IPAM(IP Address Management) 및 BGP Control Plane을 포함한 Cilium 기능의 조합을 기반으로 합니다. 이러한 기능의 책임은 아래에서 자세히 설명합니다.
+  **Cilium kube-proxy 대체**: 백엔드 포드로 Service 트래픽 라우팅을 처리합니다.
+  **Cilium LoadBalancer IPAM**: `LoadBalancer` 유형의 Service에 할당할 수 있는 IP 주소를 관리합니다.
+  **Cilium BGP Control Plane**: LoadBalancer IPAM이 할당한 IP 주소를 온프레미스 네트워크에 알립니다.

Cilium의 kube-proxy 대체를 사용하지 않는 경우에도 Cilium LoadBalancer IPAM 및 BGP Control Plane을 사용하여 LoadBalancer 유형의 Service에 IP 주소를 할당할 수 있습니다. Cilium의 kube-proxy 대체를 사용하지 않는 경우 백엔드 포드에 대한 Service의 로드 밸런싱은 기본적으로 EKS의 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를 사용하지 않으려면 다른 방법을 사용하여 온프레미스 포드 CIDR이 온프레미스 네트워크에서 라우팅할 수 있도록 해야 합니다. 자세한 내용은 [라우팅 가능한 원격 포드 CIDR](hybrid-nodes-concepts-kubernetes.md#hybrid-nodes-concepts-k8s-pod-cidrs) 섹션을 참조하세요.
+ 명령줄 환경에 Helm이 설치되어 있습니다. [Helm 설정 지침](helm.md)을 참조하세요.

### 절차
<a name="_procedure_2"></a>

1. LoadBalancer 유형의 Service에 대한 로드 밸런서 IP 주소 범위를 구성하는 `CiliumLoadBalancerIPPool` 리소스를 포함하여 `cilium-lbip-pool-loadbalancer.yaml` 파일을 생성합니다.
   + `LB_IP_CIDR`을 로드 밸런서 IP 주소에 사용할 IP 주소 범위로 바꿉니다. 단일 IP 주소를 선택하려면 `/32` CIDR을 사용합니다. 자세한 내용은 Cilium 설명서의 [LoadBalancer IP Address Management](https://docs.cilium.io/en/stable/network/lb-ipam/) 섹션을 참조하세요.
   + `serviceSelector` 필드는 후속 단계에서 생성할 Service의 이름과 일치하도록 구성됩니다. 이 구성을 사용하면 이 풀의 IP는 이름이 `tcp-sample-service`인 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` 파일을 생성하여 다음 단계에서 생성할 Service의 로드 밸런서 IP 주소를 알립니다. Cilium BGP를 사용하지 않는 경우 이 단계를 건너뛸 수 있습니다. Service에 사용되는 로드 밸런서 IP 주소는 마지막 단계에서 서비스를 쿼리할 수 있도록 온프레미스 네트워크에서 라우팅 가능해야 합니다.
   + `advertisementType` 필드는 `Service`로 설정되고 `service.addresses`는 `LoadBalancer` 유형의 Service에 대한 `LoadBalancerIP`만 알리도록 `LoadBalancerIP`로 설정됩니다.
   + `selector` 필드는 후속 단계에서 생성할 Service의 이름과 일치하도록 구성됩니다. 이 구성을 사용하면 이름이 `tcp-sample-service`인 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 유형의 Service를 정의합니다.
   + Service 객체의 `lbipam.cilium.io/ips` 주석을 사용하여 로드 밸런서 IP 풀에서 특정 IP 주소를 요청할 수 있습니다. Service에 대한 특정 IP 주소를 요청하지 않으려면 이 주석을 제거할 수 있습니다.
   + `loadBalancerClass` 사양 필드는 레거시 AWS 클라우드 공급자가 Service에 대한 Classic Load Balancer를 생성하지 못하도록 하는 경우 필요합니다. 아래 예시에서는 Cilium의 BGP 컨트롤 플레인을 로드 밸런서 클래스로 사용하도록 `io.cilium/bgp-control-plane`가 구성됩니다. 또는 Cilium의 [L2 Announcements 기능](https://docs.cilium.io/en/latest/network/l2-announcements/)(현재 베타 버전이며, AWS에서 공식적으로 지원되지 않음)을 사용하도록 `io.cilium/l2-announcer`에 이 필드를 구성할 수 있습니다.

     ```
     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. Service를 클러스터에 적용합니다. Service는 애플리케이션에 액세스하는 데 사용할 수 있는 외부 IP 주소로 생성됩니다.

   ```
   kubectl apply -f tcp-sample-service.yaml
   ```

1. Service가 성공적으로 생성되었고 이전 단계에서 생성된 `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이 Service에 대한 로드 밸런싱을 처리하고 있는지 확인할 수 있습니다. 아래 출력에서 `10.86.2.x` 주소는 Service에 대한 백엔드 포드의 포드 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 주소를 알리는지 확인합니다. 아래 예시에는 5개의 하이브리드 노드가 있고, 각 노드는 `tcp-sample-service` 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. 할당된 로드 밸런서 IP 주소를 사용하여 Service에 액세스합니다.

   ```
   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>

 AWS는 Cilium을 EKS Hybrid Nodes에서 CNI로 사용할 때 포드 수신 및 송신 트래픽에 대해 Kubernetes 네트워크 정책(계층 3/계층 4)을 지원합니다. AWS 클라우드의 노드에서 EKS 클러스터를 실행하는 경우 AWS는 [Amazon VPC CNI for Kubernetes 네트워크 정책](cni-network-policy.md)을 지원합니다.

이 주제에서는 EKS Hybrid Nodes를 사용하여 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 네트워크 정책 및 사양을 지원합니다. AWS는 현재 `CiliumNetworkPolicy` 또는 `CiliumClusterwideNetworkPolicy`를 지원하지 않습니다.
+ `policyEnforcementMode` Helm 값을 사용하여 기본 Cilium 정책 시행 동작을 제어할 수 있습니다. 기본 동작은 모든 송신 및 수신 트래픽을 허용합니다. 네트워크 정책에서 엔드포인트를 선택하면 엔드포인트는 명시적으로 허용된 트래픽만 허용되는 default-deny 상태로 전환됩니다. [기본 정책 모드](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`를 사용하여 일치하는 레이블이 있는 네임스페이스 및 포드와의 트래픽을 허용하거나 거부합니다. `namespaceSelector` 및 `podSelector`를 `matchLabels` 또는 `matchExpressions`와 함께 사용하여 레이블을 기반으로 네임스페이스 및 포드를 선택할 수 있습니다.
+ `ingress.ports` 및 `egress.ports`를 사용하여 포트 및 프로토콜과의 트래픽을 허용하거나 거부합니다.
+ `ipBlock` 필드는 포드 IP 주소([\$19209](https://github.com/cilium/cilium/issues/9209))와의 트래픽을 선택적으로 허용하거나 거부하는 데 사용할 수 없습니다. 노드 IP에 `ipBlock` 선택기를 사용하는 것은 Cilium에서 베타 기능으로 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 애플리케이션은 다음과 같은 관계가 있는 4개의 개별 마이크로서비스로 구성됩니다.
+  **productpage**. productpage 마이크로서비스는 세부 정보를 호출하고 마이크로서비스를 검토하여 페이지를 채웁니다.
+  **details**. details 마이크로서비스에는 책 정보가 포함됩니다.
+  **reviews**. reviews 마이크로서비스에는 책 리뷰가 포함됩니다. 또한 ratings 마이크로서비스를 호출합니다.
+  **ratings**. ratings 마이크로서비스에는 책 리뷰와 함께 제공되는 책 순위 정보가 포함됩니다.

  1. 샘플 애플리케이션을 생성합니다.

     ```
     kubectl apply -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/bookinfo/platform/kube/bookinfo.yaml
     ```

  1. 애플리케이션이 성공적으로 실행되고 있는지 확인하고 productpage 마이크로서비스의 포드 IP 주소를 기록합니다. 이 포드 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. 전체적으로 네트워크 정책을 테스트하는 데 사용할 포드를 생성합니다. 포드는 레이블이 `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 포드(`10.86.2.193`)의 포드 IP 주소를 사용하여 마이크로서비스를 쿼리합니다. 이를 환경에 있는 productpage 포드의 포드 IP 주소로 바꿉니다.

     ```
     curl -s http://10.86.2.193:9080/productpage | grep -o "<title>.*</title>"
     ```

     ```
     <title>Simple Bookstore App</title>
     ```

  1. `exit`를 입력하여 테스트 curl 포드를 종료하고 다음 명령을 실행하여 포드에 다시 연결할 수 있습니다.

     ```
     kubectl attach curl-pod -c curl-pod -i -t
     ```

  1. 다음 단계에서 네트워크 정책의 효과를 보여주기 위해 먼저 BookInfo 마이크로서비스에 대한 모든 트래픽을 거부하는 네트워크 정책을 생성합니다. deny 네트워크 정책을 정의하는 `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. 클러스터에 deny 네트워크 정책을 적용합니다.

     ```
     kubectl apply -f network-policy-default-deny-bookinfo.yaml
     ```

  1. BookInfo 애플리케이션에 대한 액세스를 테스트합니다. 아래 예시에서는 productpage 포드(`10.86.2.193`)의 포드 IP 주소를 사용하여 마이크로서비스를 쿼리합니다. 이를 환경에 있는 productpage 포드의 포드 IP 주소로 바꿉니다.

     ```
     curl http://10.86.2.193:9080/productpage --max-time 10
     ```

     ```
     curl: (28) Connection timed out after 10001 milliseconds
     ```

  1. productpage 네트워크 정책을 정의하는 `network-policy-productpage.yaml` 파일을 생성합니다. 이 정책에는 다음 규칙이 있습니다.
     + 레이블 `access: true`가 있는 포드(이전 단계에서 생성된 curl 포드)의 수신 트래픽 허용
     + details, reviews 및 ratings 마이크로서비스의 경우 포트 `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 포드에 연결하고 Bookinfo 애플리케이션에 대한 액세스를 테스트합니다. 이제 productpage 마이크로서비스에 대한 액세스가 허용되지만 다른 마이크로서비스는 여전히 deny 네트워크 정책의 적용 대상이므로 여전히 거부됩니다. 아래 예시에서는 productpage 포드(`10.86.2.193`)의 포드 IP 주소를 사용하여 마이크로서비스를 쿼리합니다. 이를 환경에 있는 productpage 포드의 포드 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. details 네트워크 정책을 정의하는 `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. reviews 네트워크 정책을 정의하는 `network-policy-reviews.yaml` 파일을 생성합니다. 이 정책은 productpage 마이크로서비스의 수신 트래픽만 허용하고 ratings 마이크로서비스 및 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. ratings 네트워크 정책을 정의하는 `network-policy-ratings.yaml` 파일을 생성합니다. 이 정책은 productpage 및 reviews 마이크로서비스의 수신 트래픽만 허용합니다.

     ```
     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. details, reviews 및 ratings 네트워크 정책을 클러스터에 적용합니다.

     ```
     kubectl apply -f network-policy-details.yaml
     kubectl apply -f network-policy-reviews.yaml
     kubectl apply -f network-policy-ratings.yaml
     ```

  1. curl 포드에 연결하고 Bookinfo 애플리케이션에 대한 액세스를 테스트합니다. 아래 예시에서는 productpage 포드(`10.86.2.193`)의 포드 IP 주소를 사용하여 마이크로서비스를 쿼리합니다. 이를 환경에 있는 productpage 포드의 포드 IP 주소로 바꿉니다.

     ```
     kubectl attach curl-pod -c curl-pod -i -t
     ```

     details 마이크로서비스를 테스트합니다.

     ```
     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"}
     ```

     reviews 마이크로서비스를 테스트합니다.

     ```
     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."}]}
     ```

     ratings 마이크로서비스를 테스트합니다.

     ```
     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 Hybrid Nodes*를 사용하면 온프레미스 또는 엣지 환경에서 실행되는 물리적 또는 가상 머신을 AWS 클라우드에서 실행되는 Amazon EKS 클러스터에 조인할 수 있습니다. 이 접근 방식은 많은 이점을 제공하지만 단일 네트워크 환경에서 Kubernetes 클러스터를 실행하는 데 익숙한 사용자를 위한 새로운 네트워킹 개념과 아키텍처도 도입합니다.

다음 섹션에서는 EKS Hybrid Nodes의 Kubernetes 및 네트워킹 개념을 자세히 살펴보고 하이브리드 아키텍처를 통해 트래픽이 흐르는 방식을 자세히 설명합니다. 이 섹션에서는 포드, 노드, 서비스, Kubernetes 컨트롤 플레인, kubelet 및 kube-proxy의 개념과 같은 기본 Kubernetes 네트워킹 지식을 숙지해야 합니다.

[하이브리드 노드의 네트워킹 개념](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 Hybrid Nodes용 네트워크 토폴로지를 설계할 때 고려해야 하는 핵심 네트워킹 개념과 제약 조건을 자세히 설명합니다.

## EKS Hybrid Nodes의 네트워킹 개념
<a name="_networking_concepts_for_eks_hybrid_nodes"></a>

![\[개략적인 하이브리드 노드 네트워크 다이어그램\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/hybrid-nodes-highlevel-network.png)


 **네트워크 허브로서의 VPC** 

클라우드 경계를 통과하는 모든 트래픽은 VPC를 통해 라우팅됩니다. 여기에는 AWS에서 실행되는 EKS 컨트롤 플레인 또는 포드와 해당 포드에서 실행되는 하이브리드 노드 또는 포드 간의 트래픽이 포함됩니다. 클러스터의 VPC는 ​​하이브리드 노드와 나머지 클러스터 사이의 네트워크 허브라고 생각할 수 있습니다. 이 아키텍처를 사용하면 트래픽과 라우팅을 완벽하게 제어할 수 있지만 VPC에 대한 경로, 보안 그룹 및 방화벽을 올바르게 구성하는 것도 사용자의 책임입니다.

 **VPC에 대한 EKS 컨트롤 플레인** 

EKS 컨트롤 플레인은 VPC에 **탄력적 네트워크 인터페이스(ENI)**를 연결합니다. 이러한 ENI는 EKS API 서버와의 트래픽을 처리합니다. EKS는 클러스터 생성 시 전달한 서브넷에 ENI를 연결하므로 클러스터를 구성할 때 EKS 컨트롤 플레인 ENI의 배치를 제어할 수 있습니다.

EKS는 서브넷에 연결하는 ENI에 보안 그룹을 연결합니다. 이러한 보안 그룹은 ENI를 통해 EKS 컨트롤 플레인을 오가는 트래픽을 허용합니다. 이는 EKS Hybrid Nodes에 중요합니다. 하이브리드 노드와 해당 노드에서 실행되는 포드에서 EKS 컨트롤 플레인 ENI로의 트래픽을 허용해야 하기 때문입니다.

 **원격 노드 네트워크** 

원격 노드 네트워크, 특히 원격 노드 CIDR은 하이브리드 노드로 사용하는 머신에 할당된 IP의 범위입니다. 하이브리드 노드를 프로비저닝하면 해당 노드는 EKS 컨트롤 플레인 및 VPC와 다른 네트워크 도메인인 온프레미스 데이터 센터 또는 엣지 로케이션에 상주합니다. 각 하이브리드 노드에는 VPC의 서브넷과 구별되는 원격 노드 CIDR의 IP 주소 또는 주소가 있습니다.

EKS가 kubelet API에 대한 요청과 같이 클러스터 VPC를 통해 하이브리드 노드 IP로 향하는 모든 트래픽을 라우팅하는 것을 알도록 이러한 원격 노드 CIDR로 EKS 클러스터를 구성합니다. `kubelet` API에 대한 연결은 `kubectl attach`, `kubectl cp`, `kubectl exec`, `kubectl logs`, `kubectl port-forward` 명령에서 사용됩니다.

 **원격 포드 네트워크** 

원격 포드 네트워크는 하이브리드 노드에서 실행되는 포드에 할당된 IP의 범위입니다. 일반적으로 이러한 범위로 CNI를 구성하면 CNI의 IP Address Manager(IPAM) 기능이 이러한 범위의 조각을 각 하이브리드 노드에 할당합니다. 포드를 생성하면 CNI는 포드가 예약된 노드에 할당된 조각에서 포드에 IP를 할당합니다.

이러한 원격 포드 CIDR로 EKS 클러스터를 구성하면 EKS 컨트롤 플레인이 웹후크와의 통신과 같이 클러스터의 VPC를 통해 하이브리드 노드에서 실행되는 포드로 향하는 모든 트래픽을 라우팅하는 것을 압니다.

![\[원격 포드 네트워크\]](http://docs.aws.amazon.com/ko_kr/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에서 원격 노드 및 원격 포드 네트워크로 이동하는 모든 트래픽은 연결을 통해 온프레미스 네트워크(‘게이트웨이’라고 함)로 라우팅되어야 합니다. 일부 서브넷의 라우팅 테이블이 다른 경우 하이브리드 노드의 경로와 해당 노드에서 실행되는 포드로 각 라우팅 테이블을 구성해야 합니다. 이는 EKS 컨트롤 플레인 ENI가 연결된 서브넷과 하이브리드 노드와 통신해야 하는 EC2 노드 또는 포드가 포함된 서브넷에 해당합니다.

온프레미스 네트워크에서 EKS 클러스터의 VPC 및 하이브리드 노드에 필요한 기타 AWS 서비스와의 트래픽을 허용하도록 네트워크를 구성해야 합니다. EKS 클러스터의 트래픽은 게이트웨이를 양방향으로 통과합니다.

## 네트워킹 제약 조건
<a name="_networking_constraints"></a>

 **완전히 라우팅된 네트워크** 

주요 제약 조건은 EKS 컨트롤 플레인과 모든 노드, 클라우드 또는 하이브리드 노드가 **완전히 라우팅**된 네트워크를 구성해야 한다는 것입니다. 즉, 모든 노드가 IP 주소를 기준으로 계층 3에서 서로 연결할 수 있어야 합니다.

EKS 컨트롤 플레인과 클라우드 노드는 일반 네트워크(VPC)에 있기 때문에 이미 서로 연결할 수 있습니다. 그러나 하이브리드 노드는 다른 네트워크 도메인에 있습니다. 따라서 하이브리드 노드와 클러스터의 나머지 부분 간에 트래픽을 라우팅하려면 VPC 및 온프레미스 네트워크에서 추가 라우팅을 구성해야 합니다. 하이브리드 노드가 서로 및 VPC에서 연결 가능한 경우 하이브리드 노드는 단일 일반 네트워크 또는 여러 세그먼트 네트워크에 있을 수 있습니다.

 **라우팅 가능한 원격 포드 CIDR** 

EKS 컨트롤 플레인이 하이브리드 노드(예: 웹후크 또는 지표 서버)에서 실행되는 포드와 통신하거나 클라우드 노드에서 실행되는 포드가 하이브리드 노드에서 실행되는 포드와 통신하려면(워크로드 동서 통신) 원격 포드 CIDR이 VPC에서 라우팅 가능해야 합니다. 즉, VPC는 게이트웨이를 통해 온프레미스 네트워크로 포드 CIDR로 트래픽을 라우팅할 수 있어야 하며 온프레미스 네트워크는 포드의 트래픽을 올바른 노드로 라우팅할 수 있어야 합니다.

VPC의 포드 라우팅 요구 사항과 온프레미스의 포드 라우팅 요구 사항을 구분하는 것이 중요합니다. VPC는 원격 포드로 이동하는 모든 트래픽이 게이트웨이를 통과해야 한다는 것을 알기만 하면 됩니다. 원격 포드 CIDR이 하나만 있는 경우 경로가 하나만 필요합니다.

이 요구 사항은 온프레미스 네트워크의 모든 홉에서 하이브리드 노드와 동일한 서브넷의 로컬 라우터까지 적용됩니다. 이는 각 노드에 할당된 포드 CIDR 조각을 인식해야 하는 유일한 라우터로, 특정 포드에 대한 트래픽이 포드가 예약된 노드로 전달되도록 합니다.

로컬 온프레미스 라우터에서 VPC 라우팅 테이블로 온프레미스 포드 CIDR에 대한 이러한 경로를 전파하도록 선택할 수 있지만 반드시 그럴 필요는 없습니다. 온프레미스 포드 CIDR이 자주 변경되고 VPC 라우팅 테이블을 변경된 포드 CIDR을 반영하도록 업데이트해야 하는 경우 온프레미스 포드 CIDR을 VPC 라우팅 테이블로 전파하는 것이 좋지만 이는 흔하지 않습니다.

온프레미스 포드 CIDR을 라우팅 가능하게 만드는 제약 조건은 선택 사항입니다. 하이브리드 노드에서 웹후크를 실행할 필요가 없거나 클라우드 노드의 포드가 하이브리드 노드의 포드와 통신하는 경우 온프레미스 네트워크에서 포드 CIDR에 대한 라우팅을 구성할 필요가 없습니다.

 *온프레미스 포드 CIDR을 하이브리드 노드로 라우팅해야 하는 이유는 무엇인가요?*

클라우드 노드에 VPC CNI와 함께 EKS를 사용하는 경우 VPC CNI는 VPC에서 포드에 IP를 직접 할당합니다. 즉, 클라우드 포드와 EKS 컨트롤 플레인 모두 포드 IP에 직접 도달할 수 있으므로 특별한 라우팅이 필요하지 않습니다.

온프레미스 및 클라우드의 다른 CNI에서 실행하는 경우 포드는 일반적으로 격리된 오버레이 네트워크에서 실행되고 CNI는 포드 간 트래픽 전달을 처리합니다. 이는 일반적으로 캡슐화를 통해 수행됩니다. CNI는 포드 간 트래픽을 노드 간 트래픽으로 변환하여 양쪽 끝에서 캡슐화 및 캡슐화 해제를 처리합니다. 이렇게 하면 노드 및 라우터에서 추가 구성이 필요하지 않습니다.

하이브리드 노드를 사용한 네트워킹은 두 가지 토폴로지의 조합을 제공한다는 점에서 독특합니다. EKS 컨트롤 플레인과 클라우드 노드(VPC CNI 사용)는 노드와 포드를 포함한 플랫 네트워크를 기대하는 반면, 하이브리드 노드에서 실행되는 포드는 캡슐화를 위해 VXLAN을 사용하여 오버레이 네트워크에 있습니다(기본적으로 Cilium에서). 온프레미스 네트워크가 VPC로 라우팅될 수 있다고 가정하면 하이브리드 노드에서 실행되는 포드는 EKS 컨트롤 플레인과 클라우드 노드에서 실행되는 포드에 도달할 수 있습니다. 그러나 온프레미스 네트워크의 포드 CIDR에 대한 라우팅이 없으면 네트워크가 오버레이 네트워크에 도달하고 올바른 노드로 라우팅하는 방법을 모르는 경우 온프레미스 포드 IP로 다시 들어오는 모든 트래픽이 결국 삭제됩니다.

# 하이브리드 노드에 대한 Kubernetes 개념
<a name="hybrid-nodes-concepts-kubernetes"></a>

이 페이지에서는 EKS Hybrid Nodes 시스템 아키텍처의 기반이 되는 주요 Kubernetes 개념을 자세히 설명합니다.

## VPC의 EKS 컨트롤 플레인
<a name="hybrid-nodes-concepts-k8s-api"></a>

EKS 컨트롤 플레인 ENI의 IP는 `default` 네임스페이스의 `kubernetes` `Endpoints` 객체에 저장됩니다. EKS는 새 ENI를 생성하거나 이전 ENI를 제거할 때 IP 목록이 항상 최신 상태로 유지되도록 이 객체를 업데이트합니다.

이러한 엔드포인트는 `default` 네임스페이스에서도 `kubernetes` 서비스를 통해 사용할 수 있습니다. `ClusterIP` 유형의 이 서비스는 항상 클러스터 서비스 CIDR의 첫 번째 IP 주소를 할당받습니다. 예를 들어 서비스 CIDR `172.16.0.0/16`의 경우 서비스 IP는 `172.16.0.1`이 됩니다.

일반적으로 이 방식으로 포드(클라우드 또는 하이브리드 노드에서 실행되는지 여부에 관계 없음)가 EKS Kubernetes API 서버에 액세스합니다. 포드는 서비스 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 서버와 상호 작용할 수 있습니다.

이 인터페이스를 통해 `kubelet`은 로그 가져오기(`kubectl logs`), 컨테이너 내부에서 명령 실행(`kubectl exec`), 포트 포워딩 트래픽(`kubectl port-forward`) 등 다양한 요청을 처리합니다. 이러한 각 요청은 `kubelet`을 통해 기본 컨테이너 런타임과 상호 작용하여 클러스터 관리자와 개발자에게 원활하게 나타납니다.

이 API의 가장 일반적인 소비자는 Kubernetes API 서버입니다. 앞서 언급한 `kubectl` 명령 중 하나를 사용할 때 `kubectl`은 API 서버에 API 요청을 보낸 다음 포드가 실행되고 있는 노드의 `kubelet` API를 직접적으로 호출합니다. 이것이 EKS 컨트롤 플레인에서 노드 IP에 도달할 수 있어야 하는 주된 이유이며, 노드 경로가 잘못 구성되면 포드가 실행 중이더라도 로그나 `exec`에 접근할 수 없는 이유이기도 합니다.

 **노드 IP** 

EKS 컨트롤 플레인이 노드와 통신할 때 `Node` 객체 상태(`status.addresses`)에 보고된 주소 중 하나를 사용합니다.

EKS 클라우드 노드를 사용하면 노드 등록 중 kubelet이 EC2 인스턴스의 프라이빗 IP를 `InternalIP`로 보고하는 것이 일반적입니다. 이후 Cloud Controller Manager(CCM)가 이 IP를 검증하여 해당 IP가 EC2 인스턴스에 속하는지 확인합니다. 또한 CCM은 일반적으로 인스턴스의 퍼블릭 IP(`ExternalIP`)와 DNS 이름(`InternalDNS` 및 `ExternalDNS`)을 노드 상태에 추가합니다.

그러나 하이브리드 노드용 CCM은 없습니다. EKS Hybrid Nodes CLI(`nodeadm`)를 사용하여 하이브리드 노드를 등록하면 CCM 없이 노드 상태에서 머신의 IP를 직접 보고하도록 kubelet이 구성됩니다.

```
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 중 하나를 선택합니다. `spec.kubelet.flags`의 `nodeadm` 구성에서 전달할 수 있는 `--node-ip` 플래그를 사용하여 선택한 IP를 제어할 수 있습니다. `Node` 객체에 보고된 IP에만 VPC의 경로가 필요합니다. 머신에는 클라우드에서 연결할 수 없는 다른 IP가 있을 수 있습니다.

## `kube-proxy`
<a name="hybrid-nodes-concepts-k8s-kube-proxy"></a>

 `kube-proxy`는 각 노드의 네트워킹 계층에서 서비스 추상화 구현을 담당합니다. 또한 Kubernetes Services로 향하는 트래픽에 대한 네트워크 프록시 및 로드 밸런서 역할을 합니다. `kube-proxy`는 Kubernetes API 서버에서 서비스 및 엔드포인트와 관련된 변경 사항을 지속적으로 감시해서 기본 호스트의 네트워킹 규칙을 동적으로 업데이트하여 트래픽이 제대로 전달되도록 합니다.

`iptables` 모드에서 `kube-proxy`는 여러 개의 `netfilter` 체인을 프로그래밍하여 서비스 트래픽을 처리합니다. 규칙은 다음과 같은 계층 구조를 형성합니다.

1.  **KUBE-SERVICES 체인**: 모든 서비스 트래픽의 진입점입니다. 각 서비스의 `ClusterIP` 및 포트와 일치하는 규칙이 있습니다.

1.  **KUBE-SVC-XXX 체인**: 서비스별 체인에는 각 서비스에 대한 로드 밸런싱 규칙이 있습니다.

1.  **KUBE-SEP-XXX 체인**: 엔드포인트별 체인에는 실제 `DNAT` 규칙이 있습니다.

`default` 네임스페이스의 서비스 `test-server`에서 어떤 일이 발생하는지 살펴보겠습니다. \$1 서비스 클러스터 IP: `172.16.31.14` \$1 서비스 포트: `80` \$1 백업 포드: `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(Destination 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와 포트를 다시 작성하여 트래픽을 특정 포드로 전달합니다.
   + 각 규칙은 트래픽의 약 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`가 손상되면 해당 노드가 서비스 트래픽을 제대로 라우팅할 수 없어 클러스터 서비스에 의존하는 포드에 제한 시간 초과나 연결 실패가 발생합니다. 이는 노드가 처음 등록될 때 특히 방해가 될 수 있습니다. CNI는 포드 네트워킹을 구성하기 전에 노드의 포드 CIDR과 같은 정보를 얻기 위해 Kubernetes API 서버와 통신해야 합니다. 이를 위해 CNI는 `kubernetes` 서비스 IP를 사용합니다. 그러나 `kube-proxy`가 시작되지 못하거나 올바른 `iptables` 규칙을 설정하지 못한 경우 `kubernetes` 서비스 IP로 전송되는 요청은 EKS 컨트롤 플레인 ENI의 실제 IP로 변환되지 않습니다. 따라서 CNI는 충돌 루프에 들어가고 포드 중 어느 것도 제대로 실행되지 않습니다.

포드가 `kubernetes` 서비스 IP를 사용하여 Kubernetes API 서버와 통신한다는 것을 알고 있지만, 이를 작동시키려면 먼저 `kube-proxy`가 `iptables` 규칙을 설정해야 합니다.

`kube-proxy`는 API 서버와 어떻게 통신하나요?

`kube-proxy`는 Kubernetes API 서버의 실제 IP 또는 해당 IP로 확인되는 DNS 이름을 사용하도록 구성해야 합니다. EKS의 경우 EKS는 클러스터 생성 시 EKS가 생성하는 Route53 DNS 이름을 가리키도록 기본 `kube-proxy`를 구성합니다. 이 값은 `kube-system` 네임스페이스의 `kube-proxy` ConfigMap에서 확인할 수 있습니다. 이 ConfigMap의 내용은 `kube-proxy` 포드에 삽입되는 `kubeconfig`이므로 `clusters0.cluster.server` 필드를 확인하세요. 이 값은 EKS `DescribeCluster` API 직접 호출 시 EKS 클러스터의 `endpoint` 필드와 일치합니다.

```
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
```

## 라우팅 가능한 원격 포드 CIDR
<a name="hybrid-nodes-concepts-k8s-pod-cidrs"></a>

이 [하이브리드 노드의 네트워킹 개념](hybrid-nodes-concepts-networking.md) 페이지에서는 하이브리드 노드에서 웹후크를 실행하거나 클라우드 노드에서 실행되는 포드가 하이브리드 노드에서 실행되는 포드와 통신하도록 하는 요구 사항을 자세히 설명합니다. 핵심 요구 사항은 온프레미스 라우터가 특정 포드 IP를 담당하는 노드를 알아야 한다는 것입니다. Border Gateway Protocol(BGP), 정적 경로, 주소 확인 프로토콜(ARP) 프록시 등 이를 달성하는 방법에는 여러 가지가 있습니다. 이들은 다음 섹션에서 다룹니다.

 **Border Gateway Protocol(BGP)** 

CNI가 이를 지원하는 경우(예: Cilium 및 Calico), CNI의 BGP 모드를 사용하여 노드에서 로컬 라우터로 노드별 포드 CIDR에 대한 경로를 전파할 수 있습니다. CNI의 BGP 모드를 사용할 때 CNI는 가상 라우터 역할을 하므로 로컬 라우터는 포드 CIDR이 다른 서브넷에 속하고 노드가 해당 서브넷의 게이트웨이라고 간주합니다.

![\[하이브리드 노드 BGP 라우팅\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/hybrid-nodes-bgp.png)


 **정적 경로** 

또는 로컬 라우터에서 정적 경로를 구성할 수 있습니다. 이는 온프레미스 포드 CIDR을 VPC로 라우팅하는 가장 간단한 방법이지만 가장 오류가 발생하기 쉽고 유지 관리하기 어렵습니다. 기존 노드와 할당된 포드 CIDR을 사용하여 경로가 항상 최신 상태인지 확인해야 합니다. 노드 수가 적고 인프라가 정적이면 실행 가능한 옵션이며 라우터에서 BGP를 지원할 필요가 없습니다. 이 옵션을 선택하는 경우 IPAM이 결정하도록 하는 대신 각 노드에 할당하려는 포드 CIDR 조각으로 CNI를 구성하는 것이 좋습니다.

![\[하이브리드 노드 정적 라우팅\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/hybrid-nodes-static-routes.png)


 **주소 확인 프로토콜(ARP) 프록시** 

ARP 프록시는 온프레미스 포드 IP를 라우팅 가능하게 만드는 또 다른 접근 방식이며, 하이브리드 노드가 로컬 라우터와 동일한 계층 2 네트워크에 있을 때 특히 유용합니다. ARP 프록싱이 활성화되면 노드는 자신이 호스팅하는 포드 IP에 대한 ARP 요청에 응답하는데, 해당 IP가 다른 서브넷에 속하더라도 마찬가지입니다.

로컬 네트워크의 디바이스가 포드 IP에 도달하려고 할 때 먼저 '누가 이 IP를 가지고 있나요?'라는 ARP 요청을 전송합니다. 포드가 자체 MAC 주소로 응답하는 하이브리드 노드 호스팅으로, ‘해당 IP에 대한 트래픽을 처리할 수 있습니다.’라는 메시지가 표시됩니다. 이를 통해 라우터 구성 없이 로컬 네트워크의 디바이스와 포드 간에 직접 경로가 생성됩니다.

이렇게 하려면 CNI가 프록시 ARP 기능을 지원해야 합니다. Cilium에는 구성을 통해 활성화할 수 있는 프록시 ARP에 대한 지원이 내장되어 있습니다. 가장 중요한 고려 사항은 포드 CIDR이 환경 내의 다른 네트워크와 겹치지 않아야 한다는 것입니다. 겹치면 라우팅 충돌이 발생할 수 있습니다.

이 접근 방식에는 다음과 같은 몇 가지 이점이 있습니다. \$1 BGP로 라우터를 구성하거나 정적 경로를 유지할 필요가 없습니다. \$1 라우터 구성을 제어할 수 없는 환경에서 잘 작동합니다.

![\[하이브리드 노드 ARP 프록시\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/hybrid-nodes-arp-proxy.png)


## 포드 간 캡슐화
<a name="hybrid-nodes-concepts-k8s-pod-encapsulation"></a>

온프레미스 환경에서 CNI는 일반적으로 캡슐화 프로토콜을 사용하여 물리적 네트워크상에서 작동할 수 있는 오버레이 네트워크를 생성하므로 네트워크를 재구성할 필요가 없습니다. 이 섹션에서는 이러한 캡슐화가 어떻게 작동하는지 설명합니다. 일부 세부 정보는 사용하는 CNI에 따라 다를 수 있습니다.

캡슐화는 원래의 포드 네트워크 패킷을 기본 물리적 네트워크를 통해 라우팅될 수 있는 다른 네트워크 패킷으로 묶습니다. 이를 통해 포드는 물리적 네트워크가 해당 포드 CIDR을 라우팅하는 방법을 알 필요 없이 동일한 CNI를 실행하는 노드 간에 통신할 수 있습니다.

Kubernetes에서 가장 일반적으로 사용되는 캡슐화 프로토콜은 VXLAN(Virtual Extensible LAN)이지만 CNI에 따라 `Geneve` 등의 다른 프로토콜도 사용할 수 있습니다.

### VXLAN 캡슐화
<a name="_vxlan_encapsulation"></a>

VXLAN은 UDP 패킷 내에서 계층 2 이더넷 프레임을 캡슐화합니다. 포드가 다른 노드의 다른 포드로 트래픽을 전송하면 CNI는 다음을 수행합니다.

1. CNI가 포드 A에서 패킷을 가로챕니다.

1. CNI가 원래 패킷을 VXLAN 헤더로 래핑합니다.

1. 그러면 이 래핑된 패킷이 노드의 일반 네트워킹 스택을 통해 대상 노드로 전송됩니다.

1. 대상 노드의 CNI가 패킷을 언래핑하여 포드 B로 전송합니다.

VXLAN 캡슐화 중 패킷 구조에는 다음과 같은 일이 일어납니다.

원래 포드 간 패킷:

```
+-----------------+---------------+-------------+-----------------+
| 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)는 서로 다른 오버레이 네트워크를 구분합니다.

### 포드 통신 시나리오
<a name="_pod_communication_scenarios"></a>

 **동일한 하이브리드 노드의 포드** 

동일한 하이브리드 노드의 포드가 통신하는 경우 일반적으로 캡슐화가 필요하지 않습니다. CNI는 노드의 내부 가상 인터페이스를 통해 포드 간 트래픽을 보내는 로컬 경로를 설정합니다.

```
Pod A -> veth0 -> node's bridge/routing table -> veth1 -> Pod B
```

패킷은 절대 노드를 벗어나지 않으며 캡슐화가 불필요합니다.

 **다양한 하이브리드 노드의 포드** 

서로 다른 하이브리드 노드의 포드 간 통신에는 캡슐화가 필요합니다.

```
Pod A -> CNI -> [VXLAN encapsulation] -> Node A network -> router or gateway -> Node B network -> [VXLAN decapsulation] -> CNI -> Pod B
```

이렇게 하면 물리적 네트워크가 포드 IP 라우팅을 이해할 필요 없이 포드 트래픽이 물리적 네트워크 인프라를 통과할 수 있습니다.

# 하이브리드 노드의 네트워크 트래픽 흐름
<a name="hybrid-nodes-concepts-traffic-flows"></a>

이 페이지에서는 다양한 트래픽 유형에 대한 엔드 투 엔드 네트워크 경로를 보여주는 다이어그램과 함께 EKS Hybrid Nodes의 네트워크 트래픽 흐름을 자세히 설명합니다.

다음 트래픽 흐름이 포함됩니다.
+  [하이브리드 노드 `kubelet`에서 EKS 컨트롤 플레인으로](#hybrid-nodes-concepts-traffic-flows-kubelet-to-cp) 
+  [EKS 컨트롤 플레인에서 하이브리드 노드로(`kubelet` 서버)](#hybrid-nodes-concepts-traffic-flows-cp-to-kubelet) 
+  [하이브리드 노드에서 실행되는 포드에서 EKS 컨트롤 플레인으로](#hybrid-nodes-concepts-traffic-flows-pods-to-cp) 
+  [하이브리드 노드에서 실행되는 포드에 대한 EKS 컨트롤 플레인(웹후크)](#hybrid-nodes-concepts-traffic-flows-cp-to-pod) 
+  [하이브리드 노드에서 실행되는 포드 간](#hybrid-nodes-concepts-traffic-flows-pod-to-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/ko_kr/eks/latest/userguide/images/hybrid-nodes-kubelet-to-cp-public.png)


### 요청
<a name="_request"></a>

 **1. `kubelet` 요청 시작** 

하이브리드 노드의 `kubelet`이 EKS 컨트롤 플레인과 통신해야 하는 경우(예: 노드 상태 보고 또는 포드 사양 가져오기), 노드 등록 중 제공된 `kubeconfig` 파일을 사용합니다. 이 `kubeconfig`에는 직접 IP 주소가 아닌 API 서버 엔드포인트 URL(Route53 DNS 이름)이 있습니다.

`kubelet`은 엔드포인트(예: `https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.gr7.us-west-2.eks.amazonaws.com`)에 대한 DNS 조회를 수행합니다. 퍼블릭 액세스 클러스터에서는 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`(포드가 아님)에서 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/ko_kr/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`)를 검색합니다. 그런 다음 대상 IP가 구성된 원격 노드 CIDR(`10.80.0.0/16`)에 속하므로 VPC의 ENI를 통해 이 요청을 라우팅합니다. 초기 패킷은 다음과 같습니다.

```
+-----------------+---------------------+-----------------+
| 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-온프레미스 게이트웨이로 전달됩니다.

 **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`)가 AWS로 연결되는 게이트웨이를 가리키는 경로를 가진 `10.0.0.0/16`에 속한다고 판단합니다.

 **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에 도달하여 왕복을 완료합니다.

## 하이브리드 노드에서 실행되는 포드에서 EKS 컨트롤 플레인으로
<a name="hybrid-nodes-concepts-traffic-flows-pods-to-cp"></a>

![\[하이브리드 노드에서 실행되는 포드에서 EKS 컨트롤 플레인으로\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/hybrid-nodes-pod-to-cp.png)


### CNI NAT 사용 안 함
<a name="_without_cni_nat"></a>

### 요청
<a name="_request_3"></a>

포드는 일반적으로 `kubernetes` 서비스를 통해 Kubernetes API 서버와 통신합니다. 서비스 IP는 클러스터 서비스 CIDR의 첫 번째 IP입니다. 이 규칙을 사용하면 CoreDNS를 사용할 수 있기 전에 실행해야 하는 포드(예: CNI)가 API 서버에 도달할 수 있습니다. 요청은 서비스 IP를 대상으로 하여 포드를 떠납니다. 예를 들어 서비스 CIDR이 `172.16.0.0/16`인 경우 서비스 IP는 `172.16.0.1`이 됩니다.

 **1: 포드에서 요청 시작** 

포드는 임의의 소스 포트에서 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가 관리하는 어떤 포드 CIDR에도 속하지 않음을 감지합니다. **발신 NAT가 비활성화**되어 있으므로 CNI는 패킷을 수정하지 않고 호스트 네트워크 스택으로 전달합니다.

 **3. 노드 네트워크 처리** 

패킷은 `netfilter` 후크가 kube-proxy에서 설정한 `iptables` 규칙을 트리거하는 노드의 네트워크 스택으로 들어갑니다. 다음과 같은 순서로 여러 규칙이 적용됩니다.

1. 패킷은 먼저 `KUBE-SERVICES` 체인에 도달합니다. 여기에는 각 서비스의 ClusterIP 및 포트와 일치하는 규칙이 포함됩니다.

1. 일치하는 규칙은 `kubernetes` 서비스(`172.16.0.1:443`으로 전송되는 패킷)에 대한 `KUBE-SVC-XXX` 체인으로 이동합니다.

1. 로드 밸런싱 규칙은 컨트롤 플레인 ENI IP(`10.0.0.132` 또는 `10.0.1.23`)에 대해 `KUBE-SEP-XXX` 체인 중 하나를 무작위로 선택합니다.

1. 선택한 `KUBE-SEP-XXX` 체인에는 대상 IP를 서비스 IP에서 선택한 IP로 변경하는 실제 규칙이 있습니다. 이를 DNAT(Destination Network Address Translation)이라고 합니다.

이러한 규칙이 적용된 후 선택한 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 컨트롤 플레인이 요청을 처리한 후 포드에 응답을 다시 전송합니다.

 **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는 구성된 원격 포드 CIDR(`10.85.0.0/16`)에 속하므로 서브넷의 라우터를 다음 홉으로 사용하여 VPC의 ENI를 통해 전송합니다.

 **6. VPC 라우팅** 

VPC 라우팅 테이블에는 원격 포드 CIDR(`10.85.0.0/16`)에 대한 항목이 포함되어 이 트래픽을 VPC-온프레미스 게이트웨이로 전달합니다.

 **5. 교차 경계 전송** 

게이트웨이는 설정된 연결(예: Direct Connect 또는 VPN)을 통해 클라우드 경계를 넘어 온프레미스 네트워크로 패킷을 전송합니다.

 **4. 온프레미스 네트워크 수신** 

패킷이 로컬 온프레미스 라우터에 도착합니다.

 **3. 노드로 전송** 

라우터 테이블에는 `10.85.1.0/24`에 대한 항목이 있고, 다음 홉은 `10.80.0.2`로 패킷을 노드에 전달합니다.

 **2. 노드 네트워크 처리** 

패킷이 노드의 네트워크 스택에서 처리되면 `conntrack`(`netfilter`의 일부)은 패킷을 포드가 처음 설정한 연결과 일치시킵니다. 원래 DNAT가 적용되었으므로 `conntrack`은 EKS 컨트롤 플레인 ENI의 IP에서 `kubernetes` 서비스 IP로 소스 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가 네트워크의 포드에 속함을 식별하고 패킷을 올바른 포드 네트워크 네임스페이스로 전송합니다.

이 흐름은 원격 포드 CIDR이 VPC에서 각 포드를 호스팅하는 특정 노드까지 제대로 라우팅되어야 하는 이유를 보여줍니다. 전체 반환 경로는 클라우드 및 온프레미스 네트워크 모두에서 포드 IP의 적절한 라우팅에 따라 달라집니다.

### CNI NAT 사용
<a name="_with_cni_nat"></a>

이 흐름은 *CNI NAT가 없는* 흐름과 매우 유사하지만 한 가지 주요 차이점이 있습니다. CNI는 패킷을 노드의 네트워크 스택으로 전송하기 전에 패킷에 소스 NAT(SNAT)를 적용한다는 점입니다. 이렇게 하면 패킷의 소스 IP가 노드의 IP로 변경되므로 추가 라우팅 구성 없이 패킷을 노드로 다시 라우팅할 수 있습니다.

### 요청
<a name="_request_4"></a>

 **1: 포드에서 요청 시작** 

포드는 임의의 소스 포트에서 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가 관리하는 어떤 포드 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 컨트롤 플레인이 요청을 처리한 후 포드에 응답을 다시 전송합니다.

 **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-온프레미스 게이트웨이로 전달합니다.

 **5. 교차 경계 전송** 

게이트웨이는 설정된 연결(예: Direct Connect 또는 VPN)을 통해 클라우드 경계를 넘어 온프레미스 네트워크로 패킷을 전송합니다.

 **4. 온프레미스 네트워크 수신** 

패킷이 로컬 온프레미스 라우터에 도착합니다.

 **3. 노드로 전송** 

로컬 라우터는 대상 IP(`10.80.0.2`) 주소가 직접 연결된 네트워크에 속하는 것을 식별하고 패킷을 대상 하이브리드 노드로 직접 전달합니다.

 **2. 노드 네트워크 처리** 

패킷이 노드의 네트워크 스택에서 처리될 때 `conntrack`(`netfilter`의 일부)은 패킷을 포드가 처음에 설정한 연결과 일치시키고 DNAT가 원래 적용되었기 때문에 EKS 컨트롤 플레인 ENI의 IP에서 `kubernetes` 서비스 IP로 소스 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를 포드의 IP로 다시 변경합니다.

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 172.16.0.1 | Src: 443            |                 |
| Dst: 10.85.1.56 | Dst: 67493          |                 |
+-----------------+---------------------+-----------------+
```

CNI는 대상 IP가 네트워크의 포드에 속함을 감지하고 패킷을 올바른 포드 네트워크 네임스페이스로 전송합니다.

이 흐름은 CNI NAT-ing이 Pod CIDR에 대한 추가 라우팅을 요구하지 않고도 패킷을 노드로 다시 라우팅할 수 있도록 하여 구성을 간소화하는 방법을 보여줍니다.

## 하이브리드 노드에서 실행되는 포드에 대한 EKS 컨트롤 플레인(웹후크)
<a name="hybrid-nodes-concepts-traffic-flows-cp-to-pod"></a>

![\[하이브리드 노드에서 실행되는 포드에 대한 EKS 컨트롤 플레인\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/hybrid-nodes-cp-to-pod.png)


이 트래픽 패턴은 EKS 컨트롤 플레인이 하이브리드 노드의 포드에서 실행되는 웹후크 서버에 대한 연결을 직접 시작해야 하는 웹후크에서 가장 일반적으로 볼 수 있습니다. 리소스 검증 또는 변형 프로세스 중 API 서버에서 직접적으로 호출하는 승인 웹후크의 검증 및 변형을 예로 들 수 있습니다.

### 요청
<a name="_request_5"></a>

 **1: EKS Kubernetes API 서버가 요청 시작** 

클러스터에 웹후크가 구성되고 관련 API 작업이 이를 트리거하면 EKS Kubernetes API 서버는 웹후크 서버 포드에 직접 연결해야 합니다. API 서버는 먼저 웹후크와 연결된 서비스 또는 엔드포인트 리소스에서 포드의 IP 주소를 조회합니다.

IP가 `10.85.1.23`인 하이브리드 노드에서 웹후크 포드가 실행 중이라는 가정하에 EKS Kubernetes API 서버는 웹후크 엔드포인트에 HTTPS 요청을 생성합니다. 대상 IP `10.85.1.23`이 구성된 원격 포드 CIDR(`10.85.0.0/16`)에 속하기 때문에 초기 패킷은 VPC의 EKS 컨트롤 플레인 ENI를 통해 전송됩니다. 패킷은 다음과 같습니다.

```
+-----------------+---------------------+-----------------+
| 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 라우팅 테이블에는 원격 포드 CIDR에 대한 특정 경로(`10.85.0.0/16`)가 포함되어 있습니다. 이 라우팅 규칙은 패킷을 VPC-온프레미스 게이트웨이(예: 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 주소에 도달하는 방법을 결정합니다. 이를 위해서는 온프레미스 네트워크에 트래픽을 적절한 하이브리드 노드로 전달하는 포드 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`)로 전달합니다. 패킷이 노드에 도착하면 대상 IP가 여전히 포드의 IP인 것을 제외하면 EKS Kubernetes API 서버가 패킷을 전송했을 때와 동일하게 보입니다.

 **7. CNI 처리** 

노드의 네트워크 스택은 패킷을 수신하고 대상 IP가 노드의 자체 IP가 아님을 확인한 후 처리를 위해 CNI에 전달합니다. CNI는 대상 IP가 이 노드에서 로컬로 실행되는 포드에 속함을 식별하고 적절한 가상 인터페이스를 통해 패킷을 올바른 포드로 전달합니다.

```
Original packet -> node routing -> CNI -> Pod's network namespace
```

포드의 웹후크 서버는 요청을 수신하고 처리합니다.

### 응답
<a name="_response_5"></a>

웹후크 포드가 이 요청을 처리한 후, 동일한 경로를 역으로 응답을 다시 전송합니다.

 **7. 포드에서 응답 전송** 

웹후크 포드는 자체 IP를 소스로, 원래 요청자(EKS 컨트롤 플레인 ENI)를 대상으로 응답 패킷을 생성합니다.

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 10.85.1.23 | Src: 8443           |                 |
| Dst: 10.0.0.132 | Dst: 41892          |                 |
+-----------------+---------------------+-----------------+
```

CNI는 이 패킷이 로컬 포드가 아닌 외부 네트워크로 이동함을 식별하고 원본 소스 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 서버는 웹후크 응답을 수신하고 이 응답을 기반으로 원래 API 요청을 계속 처리합니다.

이 트래픽 흐름은 원격 포드 CIDR을 올바르게 구성하고 라우팅해야 하는 이유를 보여줍니다.
+ VPC에는 온프레미스 게이트웨이를 가리키는 원격 포드 CIDR에 대한 경로가 있어야 합니다.
+ 온프레미스 네트워크에는 해당 포드를 호스팅하는 특정 노드로 트래픽을 전달하는 포드 CIDR에 대한 경로가 있어야 합니다.
+ 이 라우팅 구성이 없으면 EKS 컨트롤 플레인이 하이브리드 노드의 포드에서 실행되는 웹후크와 기타 유사 서비스에 연결할 수 없습니다.

## 하이브리드 노드에서 실행되는 포드 간
<a name="hybrid-nodes-concepts-traffic-flows-pod-to-pod"></a>

![\[하이브리드 노드에서 실행되는 포드 간\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/hybrid-nodes-pod-to-pod.png)


이 섹션에서는 서로 다른 하이브리드 노드에서 실행되는 포드가 서로 통신하는 방법을 설명합니다. 이 예에서는 CNI가 캡슐화를 위해 VXLAN을 사용한다고 가정하며, 이는 Cilium 또는 Calico와 같은 CNI에 일반적입니다. 전체 프로세스는 Geneve 또는 IP-in-IP 등의 다른 캡슐화 프로토콜과 유사합니다.

### 요청
<a name="_request_6"></a>

 **1: 포드 A에서 통신 시작** 

노드 1의 포드 A(`10.85.1.56`)가 노드 2의 포드 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에서 패킷을 가로채고 처리** 

포드 A의 패킷이 네트워크 네임스페이스를 벗어나면 CNI가 이를 가로챕니다. CNI는 라우팅 테이블을 참조하여 다음을 확인합니다. - 대상 IP(`10.85.2.67`)는 포드 CIDR에 속합니다. - 이 IP는 로컬 노드에 없지만 노드 2(`10.80.0.3`)에 속합니다. - 패킷은 VXLAN으로 캡슐화되어야 합니다.

캡슐화 결정은 기본 물리적 네트워크가 포드 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)는 이 패킷이 속하는 오버레이 네트워크를 식별합니다. - 전체 원본 패킷(포드 A의 IP를 소스로, 포드 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가 로컬 포드에 속함을 식별합니다.

1. 적절한 가상 인터페이스를 통해 패킷을 라우팅합니다.

1. 포드 B의 네트워크 네임스페이스로 패킷을 전송합니다.

### 응답
<a name="_response_6"></a>

포드 B가 포드 A에 응답하면 전체 프로세스가 반대로 수행됩니다.

1. 포드 B가 포드 A(`10.85.1.56`)로 패킷을 전송합니다.

1. 노드 2의 CNI는 노드 1(`10.80.0.2`)로 대상을 설정하여 VXLAN으로 캡슐화합니다.

1. 캡슐화된 패킷이 노드 1로 전달됩니다.

1. 노드 1의 CNI는 이를 캡슐화 해제하고 포드 A에 원래 응답을 전달합니다.

## 클라우드 노드의 포드에서 하이브리드 노드의 포드로(동서 트래픽)
<a name="hybrid-nodes-concepts-traffic-flows-east-west"></a>

![\[클라우드 노드의 포드에서 하이브리드 노드의 포드로\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/hybrid-nodes-east-west.png)


### 요청
<a name="_request_7"></a>

 **1: 포드 A에서 통신 시작** 

EC2 노드의 포드 A(`10.0.0.56`)가 하이브리드 노드의 포드 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를 사용하면 포드 A는 VPC CIDR의 IP를 가지며 EC2 인스턴스의 ENI에 직접 연결됩니다. 포드의 네트워크 네임스페이스는 VPC 네트워크에 연결되므로 패킷은 VPC 라우팅 인프라에 직접 들어갑니다.

 **2. VPC 라우팅** 

VPC 라우팅 테이블에는 원격 포드 CIDR(`10.85.0.0/16`)에 대한 특정 경로가 포함되어 있으며, 이 트래픽을 VPC-온프레미스 게이트웨이로 전달합니다.

```
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 주소에 도달하기 위한 다음 홉을 결정합니다. 온프레미스 라우터에 트래픽을 적절한 하이브리드 노드로 전달하는 포드 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`)로 전달합니다. 패킷이 노드에 도착해도 여전히 포드 A의 IP가 소스이고 포드 B의 IP가 대상입니다.

 **6. CNI 처리** 

노드의 네트워크 스택은 패킷을 수신하고 대상 IP가 자체가 아님을 확인한 후 처리를 위해 CNI에 전달합니다. CNI는 대상 IP가 이 노드에서 로컬로 실행되는 포드에 속함을 식별하고 적절한 가상 인터페이스를 통해 패킷을 올바른 포드로 전달합니다.

```
Original packet -> node routing -> CNI -> Pod B's network namespace
```

포드 B는 패킷을 수신하고 필요에 따라 처리합니다.

### 응답
<a name="_response_7"></a>

 **6. 포드 B에서 응답 전송** 

포드 B는 자체 IP를 소스로, 포드 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 네트워크를 통해 포드 A를 호스팅하는 EC2 인스턴스로 라우팅됩니다.

 **1: 포드 A에서 응답 수신** 

패킷은 EC2 인스턴스에 도착하고 연결된 ENI를 통해 포드 A로 직접 전달됩니다. VPC CNI는 VPC의 포드에 오버레이 네트워킹을 사용하지 않으므로 추가 캡슐화 해제가 필요하지 않습니다. 패킷은 원래 헤더가 그대로 유지된 상태로 도착합니다.

이 동서 트래픽 흐름은 원격 포드 CIDR을 올바르게 구성하고 양방향으로 라우팅해야 하는 이유를 보여줍니다.
+ VPC에는 온프레미스 게이트웨이를 가리키는 원격 포드 CIDR에 대한 경로가 있어야 합니다.
+ 온프레미스 네트워크에는 해당 포드를 호스팅하는 특정 노드로 트래픽을 전달하는 포드 CIDR에 대한 경로가 있어야 합니다.

# 하이브리드 노드 `nodeadm` 참조
<a name="hybrid-nodes-nodeadm"></a>

Amazon EKS Hybrid Nodes 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** 


| 이름 | 필수 | 설명 | 
| --- | --- | --- | 
|   `-p`,  `--credential-provider`   |  TRUE  |  설치할 자격 증명 공급자입니다. 지원되는 값은 `iam-ra` 및 `ssm`입니다. 자세한 정보는 [하이브리드 노드에 대한 자격 증명 준비](hybrid-nodes-creds.md)을 참조하세요.  | 
|   `-s`,  `--containerd-source`   |  FALSE  |  `containerd` 소스입니다. `nodeadm`은 OS distro, Docker 패키지에서 `containerd` 설치 또는 `containerd` 설치 건너뛰기를 지원합니다.  **값**   `distro` - 기본값입니다. `nodeadm`은 노드 OS(EKS Kubernetes 버전과 호환됨)에서 배포한 `containerd` 패키지를 설치합니다. `distro`는 Red Hat Enterprise Linux(RHEL) 운영 체제에서 지원되지 않는 값입니다.  `docker` - `nodeadm`은 Docker에서 빌드 및 배포한 최신 `containerd` 패키지를 설치합니다. `docker`는 Amazon Linux 2023에서 지원되지 않는 값입니다.  `none`-`nodeadm`은 `containerd` 패키지를 설치하지 않습니다. `nodeadm init`를 실행하기 전에 `containerd`를 수동으로 설치해야 합니다.  | 
|   `-r`,  `--region`   |  FALSE  |  SSM 에이전트와 같은 아티팩트를 다운로드할 AWS 리전을 지정합니다. 기본값은 `us-west-2`입니다.  | 
|   `-t`,  `--timeout`   |  FALSE  |  최대 설치 명령 기간입니다. 입력은 기간 형식을 따릅니다. 예: `1h23m`. 설치 명령의 기본 다운로드 제한 시간은 20분으로 설정됩니다.  | 
|   `-h`, `--help`   |  FALSE  |  사용 가능한 플래그, 하위 명령, 위치 값 파라미터가 포함된 도움말 메시지가 표시됩니다.  | 

 **예제** 

AWS Systems Manager(SSM)를 자격 증명 공급자로 사용하여 Kubernetes 버전 `1.32` 설치

```
nodeadm install 1.32 --credential-provider ssm
```

AWS Systems Manager(SSM)를 자격 증명 공급자로, Docker를 Containered 소스로 사용하여 Kubernetes 버전 `1.32`을 설치하고 다운로드 제한 시간은 20분입니다.

```
nodeadm install 1.32 --credential-provider ssm --containerd-source docker --timeout 20m
```

AWS IAM Roles Anywhere를 자격 증명 공급자로 사용하여 Kubernetes 버전 `1.32` 설치

```
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** 


| 이름 | 필수 | 설명 | 
| --- | --- | --- | 
|   `-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** 


| 이름 | 필수 | 설명 | 
| --- | --- | --- | 
|   `-c`,  `--config-source`   |  TRUE  |  `nodeadm` 구성 소스입니다. 하이브리드 노드의 경우 입력은 파일 체계의 URI를 따라야 합니다.  | 
|   `-s`,  `--skip`   |  FALSE  |  건너뛸 `init`의 단계입니다. 문제 해결에 도움이 되지 않는 한 단계를 건너뛰는 것은 권장되지 않습니다.  **값**   `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** 


| 이름 | 필수 | 설명 | 
| --- | --- | --- | 
|   `-c`,  `--config-source`   |  TRUE  |  `nodeadm` 구성 소스입니다. 하이브리드 노드의 경우 입력은 파일 체계의 URI를 따라야 합니다.  | 
|   `-t`,  `--timeout`   |  FALSE  |  아티팩트 다운로드 제한 시간입니다. 입력은 기간 형식을 따릅니다. 예를 들면 1h23m입니다. 업그레이드 명령의 기본 다운로드 제한 시간은 10분으로 설정됩니다.  | 
|   `-s`,  `--skip`   |  FALSE  |  건너뛸 업그레이드 단계입니다. 문제 해결에 도움이 되지 않는 한 단계를 건너뛰는 것은 권장되지 않습니다.  **값**   `pod-validation`은 대몬 세트 및 정적 포드를 제외하고 노드에서 모든 포드가 실행 중인지 확인하는 단계를 건너뜁니다.  `node-validation`은 노드가 차단되었는지 확인하는 단계를 건너뜁니다.  `init-validation`은 업그레이드를 실행하기 전에 노드가 성공적으로 초기화되었는지 확인하는 단계를 건너뜁니다.  `containerd-major-version-upgrade`는 노드 업그레이드 중에 Containered 메이저 버전 업그레이드를 방지합니다.  | 
|   `-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` 명령은 kubelet 및 Containered를 포함하여 `nodeadm install` 중에 아티팩트 `nodeadm` 설치를 중지하고 제거합니다. 제거 명령은 클러스터에서 하이브리드 노드를 드레이닝하거나 삭제하지 않습니다. 드레이닝 및 삭제 작업을 별도로 실행해야 합니다. 자세한 내용은 [하이브리드 노드 제거](hybrid-nodes-remove.md) 섹션을 참조하세요. 노드에 포드가 남아 있는 경우 기본적으로 `nodeadm uninstall`이 진행되지 않습니다. 마찬가지로 `nodeadm uninstall`은 CNI 종속성 또는 클러스터에서 실행하는 다른 Kubernetes 추가 기능의 종속성을 제거하지 않습니다. 호스트에서 CNI 설치를 완전히 제거하려면 [하이브리드 노드에 대한 CNI 구성](hybrid-nodes-cni.md)의 지침을 참조하세요. 온프레미스 자격 증명 공급자로 AWS SSM 하이브리드 활성화를 사용하는 경우 `nodeadm uninstall` 명령은 호스트를 AWS SSM 관리형 인스턴스로 등록 취소합니다.

 **사용량** 

```
nodeadm uninstall [flags]
```

 **Flags** 


| 이름 | 필수 | 설명 | 
| --- | --- | --- | 
|   `-s`,  `--skip`   |  FALSE  |  건너뛸 제거 단계입니다. 문제 해결에 도움이 되지 않는 한 단계를 건너뛰는 것은 권장되지 않습니다.  **값**   `pod-validation`은 대몬 세트 및 정적 포드를 제외하고 노드에서 모든 포드가 실행 중인지 확인하는 단계를 건너뜁니다.  `node-validation`은 노드가 차단되었는지 확인하는 단계를 건너뜁니다.  `init-validation`은 제거를 실행하기 전에 노드가 성공적으로 초기화되었는지 확인하는 단계를 건너뜁니다.  | 
|   `-h`,  `--help`   |  FALSE  |  사용 가능한 플래그, 하위 명령, 위치 값 파라미터가 포함된 도움말 메시지가 표시됩니다.  | 
|   `-f`,  `--force`   |  FALSE  |  Kubernetes 및 CNI 구성 요소의 나머지 파일이 포함될 수 있는 추가 디렉터리를 강제로 삭제합니다.  **경고**  그러면 기본 Kubernetes 및 CNI 디렉터리(`/var/lib/cni`, `/etc/cni/net.d` 등)의 모든 콘텐츠가 삭제됩니다. 이러한 위치에 자체 데이터를 저장하는 경우 이 플래그를 사용하지 마세요. nodeadm `v1.0.9`부터 `./nodeadm uninstall --skip node-validation,pod-validation --force` 명령으로 더 이상 `/var/lib/kubelet` 디렉터리가 삭제되지 않습니다. 탑재된 노드 파일 시스템을 포함하는 포드 볼륨 및 볼륨 하위 경로 디렉터리가 포함될 수 있기 때문입니다.  **안전한 처리 관련 팁**  - 탑재된 경로를 삭제하면 실제 탑재된 노드 파일 시스템이 실수로 삭제될 수 있습니다. `/var/lib/kubelet` 디렉터리를 수동으로 삭제하기 전에 모든 활성 탑재를 주의하여 검사하고 볼륨 탑재를 안전하게 해제하여 데이터 손실을 방지합니다.  | 

 **예제** 

```
nodeadm uninstall
```

```
nodeadm uninstall --skip node-validation,pod-validation
```

## `nodeadm debug`
<a name="_nodeadm_debug"></a>

`nodeadm debug` 명령을 사용하여 비정상이거나 잘못 구성된 하이브리드 노드 문제를 해결할 수 있습니다. 다음 요구 사항이 있는지 확인합니다.
+ 노드는 자격 증명을 얻는 데 필요한 AWS API에 대한 네트워크 액세스 권한이 있습니다.
+ 노드는 구성된 하이브리드 노드 IAM 역할에 대한 AWS 자격 증명을 가져올 수 있습니다.
+ 노드에는 EKS Kubernetes API 엔드포인트에 대한 네트워크 액세스 권한과 EKS Kubernetes API 엔드포인트 인증서의 유효성이 있습니다.
+ 노드는 EKS 클러스터로 인증할 수 있고, 클러스터의 자격 증명이 유효하며, 노드가 EKS 클러스터에 대해 구성된 VPC를 통해 EKS 클러스터에 액세스할 수 있는지 확인할 수 있습니다.

오류가 발견되면 명령의 출력에서 문제 해결 단계를 제안합니다. 특정 검증 단계는 하위 프로세스를 보여줍니다. 이러한 오류가 발생하면 출력이 검증 오류 아래의 stderr 섹션에 표시됩니다.

 **사용량** 

```
nodeadm debug [flags]
```

 **Flags** 


| 이름 | 필수 | 설명 | 
| --- | --- | --- | 
|   `-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 install
<a name="_nodeadm_install_2"></a>

`nodeadm install`을 실행할 때 다음 파일과 파일 위치가 구성됩니다.


| 아티팩트 | 경로 | 
| --- | --- | 
|  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 설정 CLI  |  /opt/ssm/ssm-setup-cli  | 
|  SSM 에이전트  |  Ubuntu - /snap/amazon-ssm-agent/current/amazon-ssm-agent RHEL 및 AL2023 - /usr/bin/amazon-ssm-agent  | 
|  Containered  |  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`를 실행할 때 다음 파일과 파일 위치가 구성됩니다.


| 이름 | 경로 | 
| --- | --- | 
|  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  | 
|  Containered 구성  |  /etc/containerd/config.toml  | 
|  Containered 커널 모듈 구성  |  /etc/modules-load.d/contianerd.conf  | 
|   AWS Config 파일  |  /etc/aws/hybrid/config  | 
|   AWS 자격 증명 파일(자격 증명 파일을 활성화하는 경우)  |  /eks-hybrid/.aws/credentials  | 
|   AWS signing helper 시스템 단위  |  /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>

다음은 하이브리드 노드 자격 증명을 위한 AWS IAM Roles Anywhere의 샘플 `nodeConfig.yaml`입니다.

AWS IAM Roles Anywhere를 온프레미스 자격 증명 공급자로 사용하는 경우 `nodeadm` 구성에서 사용하는 `nodeName`은 하이브리드 노드 IAM 역할에 대해 범위가 지정된 권한과 일치해야 합니다. 예를 들어 하이브리드 노드 IAM 역할에 대한 권한이 역할 세션 이름이 호스트 인증서의 CN과 같을 때만 AWS IAM Roles Anywhere가 역할을 수임하도록 허용하는 경우 `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 구성 및 플래그를 전달할 수 있습니다. `shutdownGracePeriod`를 30초로 설정하기 위해 노드 레이블 `abc.amazonaws.com/test-label` 및 구성을 추가하는 방법은 아래 예제를 참조하세요.

```
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
```

## Containered 사용자 지정을 위한 노드 구성(선택 사항)
<a name="_node_config_for_customizing_containerd_optional"></a>

`nodeadm` 구성에서 사용자 지정 Containered 구성을 전달할 수 있습니다. `nodeadm`에 대한 Containered 구성은 인라인 TOML을 허용합니다. Containered 콘텐츠 스토어에서 압축되지 않은 이미지 계층의 삭제를 비활성화하도록 Containered를 구성하는 방법은 아래 예제를 참조하세요.

```
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
```

**참고**  
Containered 버전 1.x 및 2.x는 여러 구성 형식을 사용합니다. Containerd 1.x는 구성 버전 2를 사용하는 반면, Containered 2.x는 구성 버전 3을 사용합니다. Containered 2.x는 구성 버전 2와 이전 버전과의 호환성을 유지하지만 최적의 성능을 위해 구성 버전 3이 권장됩니다. `containerd --version`을 사용하여 Containered 버전을 확인하거나 `nodeadm` 설치 로그를 검토합니다. 구성 버전 관리에 대한 자세한 내용은 https://containerd.io/releases/를 참조하세요.

Containered 구성을 사용하여 SELinux 지원을 활성화할 수도 있습니다. Containered에서 SELinux를 활성화한 경우 노드에 예약된 포드에 적절한 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가 호스트에서 허용 모드로 설정된 경우 Containered에서 활성화하면 요청이 차단되지 않고 호스트의 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 Hybrid Nodes를 사용하는 동안 발생할 수 있는 몇 가지 일반적 오류와 이를 해결하는 방법을 다룹니다. 기타 문제 해결 정보는 [Amazon EKS 클러스터 및 노드 관련 문제 해결](troubleshooting.md) 및 *AWS re:Post*의 [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 Management Console, AWS CLI, AWS SDK에서 모든 인사이트 검사의 결과를 볼 수 있습니다. 클러스터 인사이트에 대한 자세한 내용은 [클러스터 인사이트를 사용한 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`, `kubelet`, `kubectl`, 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"
```

 **`eks:DescribeCluster` 작업에 대한 하이브리드 노드 IAM 역할 권한 누락** 

`nodeadm init`를 실행할 때 `nodeadm`은 EKS `DescribeCluster` 작업을 직접 호출하여 EKS 클러스터에 대한 정보를 수집하려고 시도합니다. 하이브리드 노드 IAM 역할에 `eks:DescribeCluster` 작업에 대한 권한이 없으면 `nodeadm init`를 실행할 때 `nodeadm`에 전달하는 노드 구성에서 Kubernetes API 엔드포인트, 클러스터 CA 번들, 서비스 IPv4 CIDR을 전달해야 합니다. 하이브리드 노드 IAM 역할에 필요한 권한에 대한 자세한 내용은 [하이브리드 노드에 대한 자격 증명 준비](hybrid-nodes-creds.md) 섹션을 참조하세요.

```
"msg":"Command failed","error":"operation error EKS: DescribeCluster, https response error StatusCode: 403 ... AccessDeniedException"
```

 **`eks:ListAccessEntries` 작업에 대한 하이브리드 노드 IAM 역할 권한 누락** 

`nodeadm init`를 실행할 때 `nodeadm`은 EKS `ListAccessEntries` 작업을 직접 호출하여 하이브리드 노드 IAM 역할에 연결된 `HYBRID_LINUX` 유형의 액세스 항목이 EKS 클러스터에 있는지 검증하려고 시도합니다. 하이브리드 노드 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]
```

이 예는 원격 네트워크 CIDR가 10.0.0.0/16 및 192.168.0.0/16인 클러스터에 조인하려고 시도하는 IP 주소가 10.18.0.1인 노드를 보여줍니다. 10.18.0.1이 두 범위 중 하나에 속하지 않기 때문에 오류가 발생합니다.

모든 노드 IP 주소를 포함하도록 `RemoteNodeNetworks`를 올바르게 구성했는지 확인합니다. 네트워킹 구성에 대한 자세한 내용은 [하이브리드 노드용 네트워킹 준비](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 주소가 클러스터에 등록하려는 주소와 일치하는지 확인하여 올바른 노드에 있는지 확인합니다.
  + 이 노드가 올바른 온프레미스 네트워크(클러스터 설정 중에 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 컨트롤 플레인 간의 네트워크 연결에 문제가 있거나, 필요한 보안 그룹 권한이 구성되지 않았거나, Kubernetes 역할 기반 액세스 제어(RBAC)에 필요한 하이브리드 노드 IAM 역할을 매핑하지 않았을 수 있습니다. 다음 명령으로 `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에 온프레미스 노드 및 선택적으로 포드 CIDR에 대한 전송 게이트웨이(TGW) 또는 가상 프라이빗 게이트웨이(VGW)에 대한 경로가 있는지 확인합니다.
+ EKS 클러스터에 대한 추가 보안 그룹에 온프레미스 노드 CIDR 및 선택적으로 포드 CIDR에 대한 인바운드 규칙이 있는지 확인합니다.
+ 온프레미스 라우터가 EKS 컨트롤 플레인으로의 트래픽과 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)의 하이브리드 노드 요구 사항 세부 정보를 충족하는지 확인합니다.
+ 하이브리드 노드의 ID가 예상 하이브리드 노드 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을 생성하고, CSR에 다음과 같은 주제 대체 이름(SAN)이 포함된 경우 자동으로 승인 및 발급됩니다. 노드 이름과 동일한 DNS SAN이 1개 이상이며 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`를 실행한 후 `no such host`가 있어 `kubelet` 로그에 EKS Kubernetes API 서버에 연결하지 못하는 오류가 표시되는 경우 온프레미스 네트워크 또는 호스트 수준에서 EKS Kubernetes API 엔드포인트의 DNS 항목을 변경해야 할 수 있습니다. *AWS Route53 설명서*의 [Forwarding inbound DNS queries to your 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 권한이 있어야 합니다. 자세한 내용은 [AWS Management Console에서 Kubernetes 리소스 보기](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
```

 **포드 상태 가져오기** 

```
kubectl get pods -A -o wide
```

 **포드 조건 및 이벤트 확인** 

```
kubectl describe pod POD_NAME
```

 **포드 로그 확인** 

```
kubectl logs POD_NAME
```

 **`kubectl` 로그 확인** 

```
systemctl status kubelet
```

```
journalctl -u kubelet -f
```

 **포드 활성 프로브가 실패하거나 웹후크가 작동하지 않음** 

하이브리드 노드에서 실행되는 애플리케이션, 추가 기능 또는 웹후크가 제대로 시작되지 않는 경우 포드에 대한 통신을 차단하는 네트워킹 문제가 있을 수 있습니다. EKS 컨트롤 플레인이 하이브리드 노드에서 실행되는 웹후크와 접촉하려면 원격 포드 네트워크로 EKS 클러스터를 구성하고 전송 게이트웨이(TGW), 가상 프라이빗 게이트웨이(VPW) 또는 VPC를 온프레미스 네트워크와 연결하는 데 사용하는 기타 게이트웨이를 대상으로 하는 VPC 라우팅 테이블의 온프레미스 포드 CIDR에 대한 경로가 있어야 합니다. 하이브리드 노드의 네트워킹 요구 사항에 대한 자세한 내용은 [하이브리드 노드용 네트워킹 준비](hybrid-nodes-networking.md) 섹션을 참조하세요. 또한 온프레미스 방화벽에서 이 트래픽을 허용하고 라우터가 포드로 올바르게 라우팅될 수 있도록 해야 합니다. 하이브리드 노드에서의 웹후크 실행 요구 사항에 대한 자세한 내용은 [하이브리드 노드용 웹후크 구성](hybrid-nodes-webhooks.md) 섹션을 참조하세요.

이 시나리오에 대한 일반적인 포드 로그 메시지는 아래에 나와 있습니다. 여기서 ip-address는 Kubernetes 서비스의 클러스터 IP입니다.

```
dial tcp <ip-address>:443: connect: no route to host
```

 **`kubectl logs` 또는 `kubectl exec` 명령이 작동하지 않음(`kubelet` API 명령)** 

다른 `kubectl` 명령은 성공하지만 `kubectl attach`, `kubectl cp`, `kubectl exec`, `kubectl logs` 또는 `kubectl port-forward` 명령이 제한 시간을 초과하면 원격 네트워크 구성과 관련된 문제일 수 있습니다. 이러한 명령은 클러스터를 통해 노드의 `kubelet` 엔드포인트에 연결됩니다. 자세한 내용은 [`kubelet` 엔드포인트](hybrid-nodes-concepts-kubernetes.md#hybrid-nodes-concepts-k8s-kubelet-api)을 참조하세요.

노드 IP 및 포드 IP가 클러스터에 대해 구성된 원격 노드 네트워크 및 원격 포드 네트워크 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 포드와 EKS 컨트롤 플레인 간의 네트워킹 문제로 인해 가장 자주 발생합니다. 환경이 하이브리드 노드용 네트워킹 준비의 요구 사항을 충족하는지 확인합니다. 문제를 세분화하면 도움이 됩니다.

EKS 클러스터 구성  
RemoteNodeNetwork 및 RemotePodNetwork 구성이 정확합니까?

VPC 구성  
전송 게이트웨이 또는 가상 프라이빗 게이트웨이가 대상인 VPC 라우팅 테이블에 RemoteNodeNetwork 및 RemotePodNetwork에 대한 경로가 있습니까?

보안 그룹 구성  
RemoteNodeNetwork 및 RemotePodNetwork에 대한 인바운드 및 아웃바운드 규칙이 있습니까?

온프레미스 네트워크  
EKS 컨트롤 플레인과 하이브리드 노드 및 하이브리드 노드에서 실행되는 포드 간에 경로 및 액세스 권한이 있습니까?

CNI 구성  
오버레이 네트워크를 사용하는 경우 웹후크를 사용할 때 CNI의 IP 풀 구성이 EKS 클러스터에 대해 구성된 RemotePodNetwork와 일치합니까?

 **하이브리드 노드에 CNI가 설치되지 않고 `Ready` 상태임** 

하이브리드 노드에 `Ready` 상태가 표시되지만 클러스터에 CNI를 설치하지 않은 경우 하이브리드 노드에 이전 CNI 아티팩트가 있을 수 있습니다. 기본적으로 Helm과 같은 도구를 사용하여 Cilium 및 Calico를 제거하면 물리적 머신이나 가상 머신에서 온디스크 리소스가 제거되지 않습니다. 또한 이러한 CNI에 대한 사용자 지정 리소스 정의(CRD)가 이전 설치에서 클러스터에 계속 존재할 수 있습니다. 자세한 내용은 [하이브리드 노드에 대한 CNI 구성](hybrid-nodes-cni.md)의 Cilium 삭제 및 Calico 삭제 섹션을 참조하세요.

 **Cilium 문제 해결** 

하이브리드 노드에서 Cilium을 실행하는 데 문제가 있는 경우 Cilium 설명서의 [the troubleshooting steps](https://docs.cilium.io/en/stable/operations/troubleshooting/)를 참조하세요. 아래 섹션에서는 하이브리드 노드에 Cilium을 배포하는 작업과 관련된 문제를 다룹니다.

 **Cilium이 시작되지 않음** 

각 하이브리드 노드에서 실행되는 Cilium 에이전트가 시작되지 않는 경우 Cilium 에이전트 포드의 로그에 오류가 있는지 확인합니다. Cilium 에이전트를 시작하려면 EKS Kubernetes API 엔드포인트에 연결해야 합니다. 이 연결이 올바르게 구성되지 않으면 Cilium 에이전트 시작이 실패합니다. 이 경우 Cilium 에이전트 포드 로그에 다음과 유사한 로그 메시지가 표시됩니다.

```
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 에이전트는 호스트 네트워크에서 실행됩니다. Cilium 연결을 위해 EKS 클러스터를 `RemoteNodeNetwork`로 구성해야 합니다. `RemoteNodeNetwork`에 대한 인바운드 규칙을 적용한 EKS 클러스터에 대한 추가 보안 그룹이 있고, `RemoteNodeNetwork`에 대한 VPC에 경로가 있으며 온프레미스 네트워크가 EKS 컨트롤 플레인에 연결할 수 있도록 올바르게 구성되어 있는지 확인합니다.

Cilium 연산자가 실행 중이고 전부가 아닌 일부 Cilium 에이전트가 실행 중인 경우 클러스터의 모든 노드에 할당할 수 있는 포드 IP가 있는지 확인합니다. Cilium 구성에서 `clusterPoolIPv4PodCIDRList`와 함께 클러스터 풀 IPAM을 사용할 때 할당 가능한 포드 CIDR의 크기를 구성합니다. 노드별 CIDR 크기는 Cilium 구성의 `clusterPoolIPv4MaskSize` 설정으로 구성됩니다. 자세한 내용은 Cilium 설명서의 [클러스터 풀 확장](https://docs.cilium.io/en/stable/network/concepts/ipam/cluster-pool/#expanding-the-cluster-pool)을 참조하세요.

 **Cilium BGP가 작동하지 않음** 

Cilium BGP 컨트롤 플레인을 사용하여 포드 또는 서비스 주소를 온프레미스 네트워크에 알리는 경우 다음 Cilium CLI 명령을 사용하여 BGP가 리소스에 경로를 알리는지 확인할 수 있습니다. Cilium CLI를 설치하는 단계는Cilium 설명서의 [Install the 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를 알리는 경우 Cilium 에이전트를 다시 시작하는 동안 BGP 경로가 중단될 수 있습니다. 자세한 내용은 Cilium 설명서의 [Failure Scenarios](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 설명서의 [the troubleshooting steps](https://docs.tigera.io/calico/latest/operations/troubleshoot/)를 참조하세요. 아래 섹션에서는 하이브리드 노드에 Calico를 배포하는 작업과 관련된 문제를 다룹니다.

아래 표에는 Calico 구성 요소와 기본적으로 노드 또는 포드 네트워크에서 실행되는지 여부가 요약되어 있습니다. 발신 포드 트래픽에 NAT를 사용하도록 Calico를 구성한 경우 온프레미스 네트워크를 구성하여 온프레미스 노드 CIDR로 트래픽을 라우팅하고 VPC 라우팅 테이블을 전송 게이트웨이(TGW) 또는 가상 프라이빗 게이트웨이(VGW)를 대상으로 하는 온프레미스 노드 CIDR의 경로로 구성해야 합니다. 발신 포드 트래픽에 NAT를 사용하도록 Calico를 구성하지 않은 경우 온프레미스 네트워크를 구성하여 온프레미스 포드 CIDR로 트래픽을 라우팅하고 VPC 라우팅 테이블을 전송 게이트웨이(TGW) 또는 가상 프라이빗 게이트웨이(VGW)를 대상으로 하는 온프레미스 포드 CIDR의 경로로 구성해야 합니다.


| 구성 요소 | Network | 
| --- | --- | 
|  Calico API 서버  |  노드  | 
|  Kubernetes용 Calico 컨트롤러  |  포드  | 
|  Calico 노드 에이전트  |  노드  | 
|  Calico `typha`   |  노드  | 
|  Calico CSI 노드 드라이버  |  포드  | 
|  Calico 연산자  |  노드  | 

 **Calico 리소스가 차단된 노드에서 예약 또는 실행됨** 

DaemonSet로 실행되지 않는 Calico 리소스에는 기본적으로 유연한 허용 오차가 있어 포드를 예약하거나 실행할 준비가 되지 않은 차단된 노드에서 예약할 수 있습니다. 다음을 포함하도록 연산자 설치를 변경하여 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 하이브리드 활성화를 사용하는 경우 `nodeadm`이 하이브리드 노드에 설치하는 다음 SSM 디렉터리 및 아티팩트에 유의합니다. SSM 에이전트에 대한 자세한 내용은 *AWS Systems Manager 사용 설명서*의 [Working with the SSM agent](https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-agent.html)을 참조하세요.


| 설명 | 위치 | 
| --- | --- | 
|  SSM 에이전트  |  Ubuntu-`/snap/amazon-ssm-agent/current/amazon-ssm-agent` RHEL & AL2023-`/usr/bin/amazon-ssm-agent`   | 
|  SSM Agent 로그  |   `/var/log/amazon/ssm`   | 
|   AWS 보안 인증  |   `/root/.aws/credentials`   | 
|  SSM 설정 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 endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/ssm.html)을 참조하세요. 아래 명령에서 `us-west-2`를 AWS SSM 하이브리드 활성화를 위한 AWS 리전으로 바꿉니다.

```
ping ssm.us-west-2.amazonaws.com
```

 **등록된 SSM 인스턴스의 연결 상태 보기** 

다음 AWS CLI 명령을 사용하여 SSM 하이브리드 활성화에 등록된 인스턴스의 연결 상태를 확인할 수 있습니다. 시스템 ID를 인스턴스의 시스템 ID로 바꿉니다.

```
aws ssm get-connection-status --target mi-012345678abcdefgh
```

 **SSM 설정 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에 등록하는 동안 오류가 발생하면 `nodeConfig.yaml`의 `region`, `activationCode`, `activationId`가 올바른지 확인합니다. 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"
```

 **시스템 등록 명령을 실행하는 중 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
```

 ** AWSIAM Roles Anywhere 문제 해결** 

하이브리드 노드 자격 증명에 AWS IAM Roles Anywhere를 사용하는 경우 `nodeadm`에서 하이브리드 노드에 설치하는 다음 디렉터리 및 아티팩트에 유의합니다. IAM Roles Anywhere 문제 해결에 대한 자세한 내용은 *AWS IAM Roles Anywhere 사용 설명서*의 [Troubleshooting AWS IAM Roles Anywhere identity and access](https://docs.aws.amazon.com/rolesanywhere/latest/userguide/security_iam_troubleshoot.html)을 참조하세요.


| 설명 | 위치 | 
| --- | --- | 
|  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 호스트에 전체 루트 쉘을 가져올 수 있습니다.

```
sheltie
```

각 명령에 `sudo chroot /.bottlerocket/rootfs`로 접두사를 지정하여 관리자 컨테이너 쉘에서 다음 섹션의 명령을 실행할 수도 있습니다.

```
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
```

호스트 `containerd` 인스턴스에 대한 `host-containerd` 서비스 상태를 확인하고 로그를 검색하기 위해 다음을 실행할 수 있습니다.

```
systemctl status host-containerd
journalctl -u host-containerd -f
```

부트스트랩 컨테이너 및 호스트 컨테이너에 대한 로그를 검색하기 위해 다음을 실행할 수 있습니다.

```
journalctl _COMM=host-ctr -f
```