

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

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

# VPC CNI 모드 및 구성에 대해 알아보기
<a name="pod-networking-use-cases"></a>

Kubernetes용 Amazon VPC CNI 플러그인은 포드에 대한 네트워킹을 제공합니다. 다음 테이블을 사용하여 사용 가능한 네트워킹 기능을 자세히 알아봅니다.


| 네트워킹 기능 | 자세히 알아보기 | 
| --- | --- | 
|  클러스터, 포드 및 서비스에 IPv6 주소를 할당하도록 클러스터를 구성합니다.  |   [클러스터, 포드 및 서비스에 대한 IPv6 주소에 대해 알아보기](cni-ipv6.md)   | 
|  포드에 IPv4 소스 네트워크 주소 변환 사용  |   [포드에 대한 아웃바운드 인터넷 액세스 활성화](external-snat.md)   | 
|  포드에서 송수신하는 네트워크 트래픽 제한  |   [Kubernetes 네트워크 정책으로 포드 네트워크 트래픽 제한](cni-network-policy-configure.md)   | 
|  노드의 보조 네트워크 인터페이스 사용자 지정  |   [사용자 지정 네트워킹을 통해 대체 서브넷에 포드 배포](cni-custom-network.md)   | 
|  노드의 IP 주소 증가  |   [접두사를 사용하여 Amazon EKS 노드에 추가 IP 주소 할당](cni-increase-ip-addresses.md)   | 
|  포드 네트워크 트래픽에 대해 보안 그룹 사용  |   [개별 포드에 보안 그룹 할당](security-groups-for-pods.md)   | 
|  포드에 여러 네트워크 인터페이스 사용  |   [포드에 여러 네트워크 인터페이스 연결](pod-multiple-network-interfaces.md)   | 

# 클러스터, 포드 및 서비스에 대한 IPv6 주소에 대해 알아보기
<a name="cni-ipv6"></a>

 **적용 대상**: Amazon EC2 인스턴스가 있는 포드와 Fargate 포드

기본적으로 Kubernetes는 포드와 서비스에 `IPv4` 주소를 할당합니다. 포드와 서비스에 `IPv4` 주소를 할당하는 대신 `IPv6` 주소를 할당하도록 클러스터를 구성할 수 있습니다. Kubernetes는 듀얼 스택 포드 또는 서비스를 지원하지만, Amazon EKS는 듀얼 스택 포드 또는 서비스를 지원하지 않습니다. 결과적으로 포드와 서비스에 `IPv4` 및 `IPv6` 주소를 모두 할당할 수 없습니다.

클러스터를 생성할 때 클러스터에 사용할 IP 패밀리를 선택합니다. 클러스터를 생성한 후에는 패밀리를 변경할 수 없습니다.

Amazon EKS `IPv6` 클러스터를 배포하기 위한 자습서는 [Amazon EKS `IPv6` 클러스터 및 관리형 Amazon Linux 노드 배포](deploy-ipv6-cluster.md)을 참조하세요.

다음은 기능 사용 시 고려 사항입니다.

## `IPv6` 기능 지원
<a name="_ipv6_feature_support"></a>
+  **Windows 지원 없음**: Windows 포드와 서비스는 지원되지 않습니다.
+  **Nitro 기반 EC2 노드 필요**: `IPv6`는 AWS Nitro 기반 Amazon EC2 또는 Fargate 노드에서만 사용할 수 있습니다.
+  **지원되는 EC2 및 Fargate 노드**: Amazon EC2 노드 및 Fargate 노드에서 [개별 포드에 보안 그룹 할당](security-groups-for-pods.md)와 함께 `IPv6`를 사용할 수 있습니다.
+  **Outposts가 지원되지 않음**: [AWS Outposts를 사용한 Amazon EKS 온프레미스 배포](eks-outposts.md)와 `IPv6`는 함께 사용할 수 없습니다.
+  **Lustre용 FSx는 지원되지 않음**:. [Amazon FSx for Lustre와 함께 고성능 앱 스토리지 사용](fsx-csi.md)는 지원되지 않습니다.
+  **사용자 지정 네트워킹이 지원되지 않음**: 이전에 [사용자 지정 네트워킹을 통해 대체 서브넷에 포드 배포](cni-custom-network.md)를 사용하여 IP 주소 고갈을 완화한 경우, 대신 `IPv6`를 사용할 수 있습니다. `IPv6`에서는 사용자 지정 네트워킹을 사용할 수 없습니다. 네트워크 격리를 위해 사용자 정의 네트워킹을 사용하는 경우 클러스터에 사용자 정의 네트워킹 및 `IPv4` 패밀리를 계속 사용해야 할 수 있습니다.

## IP 주소 할당
<a name="_ip_address_assignments"></a>
+  **Kubernetes 서비스**: Kubernetes 서비스에는 `IPv6` 주소만 할당됩니다. IPv4 주소는 할당되지 않습니다.
+  **포드**: 포드에는 IPv6 주소와 호스트-로컬 IPv4 주소가 할당됩니다. 호스트-로컬 IPv4 주소는 VPC CNI와 연결된 호스트-로컬 CNI 플러그인을 사용하여 할당되며 주소는 Kubernetes 컨트롤 플레인에 보고되지 않습니다. 포드가 다른 Amazon VPC 또는 인터넷의 외부 IPv4 리소스와 통신해야 하는 경우에만 사용됩니다. 호스트-로컬 IPv4 주소는 VPC CNI를 통해 워커 노드 기본 ENI의 기본 IPv4 주소에 SNAT 처리됩니다.
+  **포드 및 서비스**: 포드와 서비스는 `IPv4` 주소가 아닌 `IPv6` 주소만 수신합니다. 포드가 외부 `IPv4` 엔드포인트와 통신해야 하는 경우 노드 자체에서 NAT를 사용합니다. 이 내장 NAT 기능으로 [DNS64와 NAT64](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html#nat-gateway-nat64-dns64)가 필요하지 않습니다. 퍼블릭 인터넷 액세스가 필요한 트래픽의 경우 포드의 트래픽은 퍼블릭 IP 주소로 변환된 소스 네트워크 주소입니다.
+  **라우팅 주소**: 포드가 VPC 외부에서 통신하면 원래 `IPv6` 주소가 보존되고, 노드의 `IPv6` 주소로 변환되지 않습니다. 이 트래픽은 인터넷 게이트웨이나 송신 전용 인터넷 게이트웨이를 통해 직접 라우팅됩니다.
+  **노드**: 모든 노드에 `IPv4` 및 `IPv6` 주소가 할당됩니다.
+  **Fargate 포드**: 각 Fargate 포드는 배포된 서브넷에 대해 지정된 CIDR에서 `IPv6` 주소를 수신합니다. Fargate 포드를 실행하는 기본 하드웨어 장치는 하드웨어 장치가 배포된 서브넷에 할당된 CIDR에서 고유한 `IPv4` 및 `IPv6` 주소를 가져옵니다.

## EKS에서 `IPv6`를 사용하는 방법
<a name="_how_to_use_ipv6_with_eks"></a>
+  **새 클러스트 생성**: 새 클러스터를 생성하고 해당 클러스터에 `IPv6` 패밀리를 사용하도록 지정해야 합니다. 이전 버전에서 업데이트한 클러스터에 `IPv6` 패밀리를 사용 설정할 수 없습니다. 새 클러스터를 생성하는 방법에 대한 지침은 Considerations을 참조하세요.
+  **최신 VPC CNI 사용**: Amazon VPC CNI 버전 `1.10.1` 이상을 배포합니다. 이 버전 이상은 기본적으로 배포됩니다. 추가 기능을 배포하면 클러스터의 모든 노드 그룹에 있는 모든 노드를 제거하지 않으면 `1.10.1` 이전 버전에 Amazon VPC CNI 추가 기능을 다운로드할 수 없습니다.
+  **`IPv6`용 VPC CNI 구성**: Amazon EC2 노드를 사용하는 경우 IP 접두사 위임 및 `IPv6`를 사용하여 Amazon VPC CNI 추가 기능을 구성해야 합니다. 클러스터를 생성할 때 `IPv6` 패밀리를 선택하면 `1.10.1` 버전의 추가 기능이 이 구성으로 기본 설정됩니다. 이는 자체 관리형 또는 Amazon EKS 추가 기능 모두에 해당됩니다. IP 접두사 위임에 대한 자세한 내용은 [접두사를 사용하여 Amazon EKS 노드에 추가 IP 주소 할당](cni-increase-ip-addresses.md) 섹션을 참조하세요.
+  **`IPv4` 및 `IPv6` 주소를 구성**:클러스터를 생성할 때 지정한 VPC 및 서브넷에는 지정한 VPC 및 서브넷에 할당된 `IPv6` CIDR 블록이 있어야 합니다. 또한 할당된 `IPv4` CIDR 블록도 있어야 합니다. `IPv6`만 사용하려는 경우에도 VPC가 작동하려면 `IPv4` CIDR 블록이 필요하기 때문입니다. 자세한 내용은 Amazon VPC 사용 설명서의 [IPv6 CIDR 블록을 VPC와 연결](https://docs.aws.amazon.com/vpc/latest/userguide/working-with-vpcs.html#vpc-associate-ipv6-cidr)을 참조하세요.
+  **노드에 IPv6 주소 자동 할당**: 노드를 생성할 때 `IPv6` 주소를 자동 할당하도록 구성된 서브넷을 지정해야 합니다. 그렇지 않으면 노드를 배포할 수 없습니다. 기본적으로 이 구성은 사용 중지되어 있습니다. 자세한 내용은 Amazon VPC 사용 설명서의 [서브넷의 IPv6 주소 지정 속성 수정](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-ip-addressing.html#subnet-ipv6)을 참조하세요.
+  **`IPv6`를 사용할 라우트 테이블 설정**:서브넷에 할당된 라우팅 테이블에는 `IPv6` 주소에 대한 경로가 있어야 합니다. 자세한 내용은 Amazon VPC 사용 설명서의 [IPv6로 마이그레이션](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6.html)을 참조하세요.
+  **`IPv6`에 대한 보안 그룹 설정**: 보안 그룹은 `IPv6` 주소를 허용해야 합니다. 자세한 내용은 Amazon VPC 사용 설명서의 [IPv6로 마이그레이션](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6.html)을 참조하세요.
+  **로드 밸런서 설정**: AWS Load Balancer Controller 버전 `2.3.1` 이상에서 [Application Load Balancer를 사용하여 애플리케이션 및 HTTP 트래픽 라우팅](alb-ingress.md)을 사용하여 HTTP 애플리케이션의 로드 밸런싱을 수행하거나 [Network Load Balancer를 사용하여 TCP 및 UDP 트래픽 라우팅](network-load-balancing.md)을 사용하여 네트워크 트래픽을 인스턴스 모드가 아닌 IP 모드의 로드 밸런서가 있는 `IPv6` 포드로 로드 밸런싱합니다. 자세한 내용은 [AWS 로드 밸런서 컨트롤러를 통해 인터넷 트래픽 라우팅](aws-load-balancer-controller.md) 섹션을 참조하세요.
+  **`IPv6` IAM 정책을 추가**: `IPv6` IAM 정책을 노드 IAM 또는 CNI IAM 역할에 연결해야 합니다. 두 가지 중 CNI IAM 역할에 연결하는 것이 좋습니다. 자세한 내용은 [`IPv6` 패밀리를 사용하는 클러스터에 대한 IAM 정책 생성](cni-iam-role.md#cni-iam-role-create-ipv6-policy) 및 [1단계: Kubernetes용 Amazon VPC CNI 플러그인 IAM 역할 생성](cni-iam-role.md#cni-iam-role-create-role) 섹션을 참조하세요.
+  **모든 구성 요소 평가**: AWS 클러스터를 배포하기 전에 통합하는 애플리케이션, Amazon EKS 애드온 및 `IPv6` 서비스에 대한 철저한 평가를 수행하세요. 이는 `IPv6`에서 모든 것이 예상대로 작동하는지 확인하기 위한 것입니다.

# Amazon EKS `IPv6` 클러스터 및 관리형 Amazon Linux 노드 배포
<a name="deploy-ipv6-cluster"></a>

이 튜토리얼에서는 `IPv6` Amazon VPC, `IPv6` 패밀리가 있는 Amazon EKS 클러스터 및 Amazon EC2 Amazon Linux 노드가 있는 관리형 노드 그룹을 배포합니다. `IPv6` 클러스터에는 Amazon EC2 Windows 노드를 배포할 수 없습니다. Fargate 노드를 클러스터에 배포할 수도 있지만 이 항목에서는 단순화를 위해 해당 지침을 제공하지 않습니다.

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

자습서를 시작하기 전에 다음을 완료합니다.

Amazon EKS 클러스터를 생성하고 관리할 때 필요한 다음 도구 및 리소스를 설치하고 구성합니다.
+ 모든 설정을 숙지하고 요구 사항을 충족하는 설정으로 클러스터를 배포하는 것이 좋습니다. 자세한 내용은 [Amazon EKS 클러스터 생성](create-cluster.md), [관리형 노드 그룹을 사용한 노드 수명 주기 간소화](managed-node-groups.md) 그리고 이 주제에 대한 [고려 사항](cni-ipv6.md)을 참조하세요. 클러스터를 생성할 때 일부 설정만 사용 설정할 수 있습니다.
+ `kubectl` 명령줄 도구는 장치 또는 AWS CloudShell에 설치됩니다. 버전은 클러스터의 Kubernetes 버전과 동일하거나 최대 하나 이전 또는 이후의 마이너 버전일 수 있습니다. 예를 들어, 클러스터 버전이 `1.29`인 경우 `kubectl` 버전 `1.28`, `1.29` 또는 `1.30`를 함께 사용할 수 있습니다. `kubectl`을 설치하거나 업그레이드하려면 [`kubectl` 및 `eksctl` 설정](install-kubectl.md) 부분을 참조하세요.
+ 사용하는 IAM 보안 주체에 Amazon EKS IAM 역할, 서비스 연결 역할, AWS CloudFormation, VPC 및 관련 리소스를 사용할 수 있는 권한이 있어야 합니다. 자세한 내용은 IAM 사용 설명서의 [서비스 연결 역할](https://docs.aws.amazon.com/IAM/latest/UserGuide/using-service-linked-roles.html) [사용](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonelastickubernetesservice.html)을 참조하세요.
+ eksctl을 사용하는 경우 컴퓨터에 버전 `0.215.0` 이상을 설치합니다. 설치하거나 업데이트하려면 `eksctl` 설명서에서 [설치](https://eksctl.io/installation)를 참조하세요.
+ 장치에 설치 및 구성된 AWS 명령줄 인터페이스(AWS CLI)의 버전 `2.12.3` 이상 또는 버전 `1.27.160` 이상 또는 AWS CloudShell. 현재 버전을 확인하려면 `aws --version | cut -d / -f2 | cut -d ' ' -f1`을 사용합니다. `yum`, `apt-get` 또는 macOS용 Homebrew와 같은 패키지 관리자는 최신 버전의 AWS CLI 이전에 나온 버전이 몇 가지 있을 때도 있습니다. 최신 버전을 설치하려면 * AWS 명령줄 인터페이스 사용 설명서*에서 [설치](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) 및 [aws config를 사용하여 빠른 구성](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config)을 참조하세요. AWS CloudShell에 설치된 AWS CLI 버전도 최신 버전보다 여러 버전 이전일 수도 있습니다. 업데이트하려면 * AWS CloudShell 사용 설명서*의 [홈 디렉터리에 AWS CLI 설치하기](https://docs.aws.amazon.com/cloudshell/latest/userguide/vm-specs.html#install-cli-software)를 참조하세요. AWS CloudShell을 사용하는 경우 AWS CloudShell에 설치된 기본 AWS CLI 버전이 이전 버전일 수 있으므로 [AWS CLI 버전 2.12.3 이상 또는 1.27.160 이상을 설치](https://docs.aws.amazon.com/cloudshell/latest/userguide/vm-specs.html#install-cli-software)해야 할 수 있습니다.

eksctl 또는 CLI를 사용하여 `IPv6` 클러스터를 배포할 수 있습니다.

## eksctl을 사용하여 IPv6 클러스터 배포
<a name="_deploy_an_ipv6_cluster_with_eksctl"></a>

1. `ipv6-cluster.yaml` 파일을 생성합니다. 다음 명령을 디바이스에 복사합니다. 필요에 따라 명령을 다음과 같이 수정한 다음에 수정한 명령을 실행합니다.
   + *my-cluster*를 클러스터의 이름으로 바꿉니다. 이름에는 영숫자(대소문자 구분)와 하이픈만 사용할 수 있습니다. 영숫자로 시작해야 하며 100자 이하여야 합니다. 이름은 클러스터를 생성하는 AWS 리전과 AWS 계정 내에서 고유해야 합니다.
   + *region-code*를 Amazon EKS에서 지원하는 AWS 리전으로 바꿉니다. AWS 리전 목록은 AWS General Reference 가이드의 [Amazon EKS endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/eks.html)를 참조하세요.
   + 클러스터의 버전이 포함된 `version`의 값입니다. 자세한 내용은 [Amazon EKS 지원 버전](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)을 참조하세요.
   + *my-nodegroup*을 노드 그룹의 이름으로 바꿉니다. 노드 그룹 이름은 63자를 초과할 수 없습니다. 문자나 숫자로 시작하되, 나머지 문자의 경우 하이픈과 밑줄을 포함할 수 있습니다.
   + *t3.medium*을 [AWS Nitro 시스템 인스턴스 유형](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html#ec2-nitro-instances)으로 바꿉니다.

     ```
     cat >ipv6-cluster.yaml <<EOF
     ---
     apiVersion: eksctl.io/v1alpha5
     kind: ClusterConfig
     
     metadata:
       name: my-cluster
       region: region-code
       version: "X.XX"
     
     kubernetesNetworkConfig:
       ipFamily: IPv6
     
     addons:
       - name: vpc-cni
         version: latest
       - name: coredns
         version: latest
       - name: kube-proxy
         version: latest
     
     iam:
       withOIDC: true
     
     managedNodeGroups:
       - name: my-nodegroup
         instanceType: t3.medium
     EOF
     ```

1. 클러스터를 생성합니다.

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

   클러스터 생성에 몇 분 정도 걸립니다. 다음 출력과 유사한 출력의 마지막 줄이 나타날 때까지 진행하지 마세요.

   ```
   [...]
   [✓]  EKS cluster "my-cluster" in "region-code" region is ready
   ```

1. 기본 포드에 `IPv6` 주소가 할당되었는지 확인합니다.

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

   예제 출력은 다음과 같습니다.

   ```
   NAME                       READY   STATUS    RESTARTS   AGE     IP                                       NODE                                            NOMINATED NODE   READINESS GATES
   aws-node-rslts             1/1     Running   1          5m36s   2600:1f13:b66:8200:11a5:ade0:c590:6ac8   ip-192-168-34-75.region-code.compute.internal   <none>           <none>
   aws-node-t74jh             1/1     Running   0          5m32s   2600:1f13:b66:8203:4516:2080:8ced:1ca9   ip-192-168-253-70.region-code.compute.internal  <none>           <none>
   coredns-85d5b4454c-cw7w2   1/1     Running   0          56m     2600:1f13:b66:8203:34e5::                ip-192-168-253-70.region-code.compute.internal  <none>           <none>
   coredns-85d5b4454c-tx6n8   1/1     Running   0          56m     2600:1f13:b66:8203:34e5::1               ip-192-168-253-70.region-code.compute.internal  <none>           <none>
   kube-proxy-btpbk           1/1     Running   0          5m36s   2600:1f13:b66:8200:11a5:ade0:c590:6ac8   ip-192-168-34-75.region-code.compute.internal   <none>           <none>
   kube-proxy-jjk2g           1/1     Running   0          5m33s   2600:1f13:b66:8203:4516:2080:8ced:1ca9   ip-192-168-253-70.region-code.compute.internal  <none>           <none>
   ```

1. 기본 서비스에 `IPv6` 주소가 할당되었는지 확인합니다.

   ```
   kubectl get services -n kube-system -o wide
   ```

   예제 출력은 다음과 같습니다.

   ```
   NAME       TYPE        CLUSTER-IP          EXTERNAL-IP   PORT(S)         AGE   SELECTOR
   kube-dns   ClusterIP   fd30:3087:b6c2::a   <none>        53/UDP,53/TCP   57m   k8s-app=kube-dns
   ```

1. (선택 사항) [샘플 애플리케이션을 배포](sample-deployment.md)하거나 [AWS 로드 밸런서 컨트롤러](aws-load-balancer-controller.md)와 샘플 애플리케이션을 배포하여 [Application Load Balancer를 사용하여 애플리케이션 및 HTTP 트래픽 라우팅](alb-ingress.md)를 사용하는 HTTP 애플리케이션 또는 [Network Load Balancer를 사용하여 TCP 및 UDP 트래픽 라우팅](network-load-balancing.md)을 사용하는 네트워크 트래픽을 `IPv6` 포드로 로드 밸런싱하세요.

1. 이 튜토리얼용으로 생성한 클러스터 및 노드 사용을 마친 후 다음 명령을 사용하여 생성한 리소스를 정리해야 합니다.

   ```
   eksctl delete cluster my-cluster
   ```

## AWS CLI을 사용하여 IPv6 클러스터 배포
<a name="deploy_an_ipv6_cluster_with_shared_aws_cli"></a>

**중요**  
이 절차의 모든 단계를 동일한 사용자로 완료해야 합니다. 현재 사용자를 확인하려면 다음 명령을 실행합니다.  

  ```
  aws sts get-caller-identity
  ```
이 절차의 모든 단계를 동일한 셸로 완료해야 합니다. 여러 단계에서는 이전 단계에서 설정한 변수를 사용합니다. 변수 값이 다른 셸에서 설정되면 변수를 사용하는 단계가 제대로 작동하지 않습니다. [AWS CloudShell](https://docs.aws.amazon.com/cloudshell/latest/userguide/welcome.html)을 사용하여 다음 절차를 완료하는 경우 약 20\$130분 동안 키보드나 포인터를 사용하여 상호 작용하지 않으면 셸 세션이 종료된다는 점을 기억하세요. 실행 중인 프로세스는 상호 작용으로 계산되지 않습니다.
지침은 Bash 셸용으로 작성되었으며 다른 셸에서 조정해야 할 수도 있습니다.

이 절차 단계의 모든 예제 값을 고유한 값으로 바꿉니다.

1. 다음 명령을 실행하여 이후 단계에서 사용되는 일부 변수를 설정합니다. *region-code*를 리소스를 배포할 AWS 리전으로 바꿉니다. 값은 Amazon EKS에서 지원하는 모든 AWS 리전일 수 있습니다. AWS 리전 목록은 AWS General Reference 가이드의 [Amazon EKS endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/eks.html)를 참조하세요. *my-cluster*를 클러스터의 이름으로 바꿉니다. 이름에는 영숫자(대소문자 구분)와 하이픈만 사용할 수 있습니다. 영숫자로 시작해야 하며 100자 이하여야 합니다. 이름은 클러스터를 생성하는 AWS 리전과 AWS 계정 내에서 고유해야 합니다. *my-nodegroup*을 노드 그룹의 이름으로 바꿉니다. 노드 그룹 이름은 63자를 초과할 수 없습니다. 문자나 숫자로 시작하되, 나머지 문자의 경우 하이픈과 밑줄을 포함할 수 있습니다. *111122223333*을 계정 ID로 바꿉니다.

   ```
   export region_code=region-code
   export cluster_name=my-cluster
   export nodegroup_name=my-nodegroup
   export account_id=111122223333
   ```

1. Amazon EKS 및 `IPv6` 요구 사항을 충족하는 퍼블릭 및 프라이빗 서브넷이 있는 Amazon VPC를 생성합니다.

   1. 다음 명령을 실행하여 AWS CloudFormation 스택 이름에 대한 변수를 설정합니다. 선택하는 이름으로 *my-eks-ipv6-vpc*를 바꿀 수 있습니다.

      ```
      export vpc_stack_name=my-eks-ipv6-vpc
      ```

   1. AWS CloudFormation 템플릿을 사용하여 `IPv6` VPC를 만듭니다.

      ```
      aws cloudformation create-stack --region $region_code --stack-name $vpc_stack_name \
        --template-url https://s3.us-west-2.amazonaws.com/amazon-eks/cloudformation/2020-10-29/amazon-eks-ipv6-vpc-public-private-subnets.yaml
      ```

      스택을 만드는 데 몇 분 정도 걸립니다. 다음 명령을 실행합니다. 명령의 출력이 `CREATE_COMPLETE`가 될 때까지 다음 단계를 계속하지 마세요.

      ```
      aws cloudformation describe-stacks --region $region_code --stack-name $vpc_stack_name --query Stacks[].StackStatus --output text
      ```

   1. 생성된 퍼블릭 서브넷의 ID를 검색합니다.

      ```
      aws cloudformation describe-stacks --region $region_code --stack-name $vpc_stack_name \
          --query='Stacks[].Outputs[?OutputKey==`SubnetsPublic`].OutputValue' --output text
      ```

      예제 출력은 다음과 같습니다.

      ```
      subnet-0a1a56c486EXAMPLE,subnet-099e6ca77aEXAMPLE
      ```

   1. 생성된 퍼블릭 서브넷에 대해 `IPv6` 주소 자동 할당 옵션을 사용 설정합니다.

      ```
      aws ec2 modify-subnet-attribute --region $region_code --subnet-id subnet-0a1a56c486EXAMPLE --assign-ipv6-address-on-creation
      aws ec2 modify-subnet-attribute --region $region_code --subnet-id subnet-099e6ca77aEXAMPLE --assign-ipv6-address-on-creation
      ```

   1. 배포된 AWS CloudFormation 스택에서 템플릿으로 생성된 서브넷 및 보안 그룹의 이름을 검색하고 이후 단계에서 사용할 수 있도록 변수에 저장합니다.

      ```
      security_groups=$(aws cloudformation describe-stacks --region $region_code --stack-name $vpc_stack_name \
          --query='Stacks[].Outputs[?OutputKey==`SecurityGroups`].OutputValue' --output text)
      
      public_subnets=$(aws cloudformation describe-stacks --region $region_code --stack-name $vpc_stack_name \
          --query='Stacks[].Outputs[?OutputKey==`SubnetsPublic`].OutputValue' --output text)
      
      private_subnets=$(aws cloudformation describe-stacks --region $region_code --stack-name $vpc_stack_name \
          --query='Stacks[].Outputs[?OutputKey==`SubnetsPrivate`].OutputValue' --output text)
      
      subnets=${public_subnets},${private_subnets}
      ```

1. 클러스터 IAM 역할을 생성하고 필요한 Amazon EKS IAM 관리형 정책을 연결합니다. Amazon EKS에서 관리하는 Kubernetes 클러스터는 사용자 대신 다른 AWS 서비스를 직접 호출하여 서비스에 사용하는 리소스를 관리합니다.

   1. 다음 명령을 실행해 `eks-cluster-role-trust-policy.json` 파일을 생성합니다.

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

   1. 다음 명령을 실행하여 역할 이름에 대한 변수를 설정합니다. *myAmazonEKSClusterRole*을 선택한 이름으로 바꿀 수 있습니다.

      ```
      export cluster_role_name=myAmazonEKSClusterRole
      ```

   1. 역할을 생성합니다.

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

   1. IAM 역할의 ARN을 검색하고 이후 단계를 위해 변수에 저장합니다.

      ```
      CLUSTER_IAM_ROLE=$(aws iam get-role --role-name $cluster_role_name --query="Role.Arn" --output text)
      ```

   1. 필요한 Amazon EKS 관리형 IAM 정책을 역할에 연결합니다.

      ```
      aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy --role-name $cluster_role_name
      ```

1. 클러스터를 생성합니다.

   ```
   aws eks create-cluster --region $region_code --name $cluster_name --kubernetes-version 1.XX \
      --role-arn $CLUSTER_IAM_ROLE --resources-vpc-config subnetIds=$subnets,securityGroupIds=$security_groups \
      --kubernetes-network-config ipFamily=ipv6
   ```

   1. 참고: 요청의 가용 영역 중 하나에 Amazon EKS 클러스터를 생성하는 데 충분한 용량이 없다는 오류가 표시될 수 있습니다. 이 경우 오류 출력에는 새 클러스터를 지원할 수 있는 가용 영역이 포함됩니다. 사용자 계정의 지원 가용 영역에 있는 2개 이상의 서브넷을 사용하여 클러스터를 다시 생성합니다. 자세한 내용은 [용량 부족](troubleshooting.md#ice) 섹션을 참조하세요.

      클러스터를 생성하는 데 몇 분 정도 걸립니다. 다음 명령을 실행합니다. 명령의 출력이 `ACTIVE`가 될 때까지 다음 단계를 계속하지 마세요.

      ```
      aws eks describe-cluster --region $region_code --name $cluster_name --query cluster.status
      ```

1. 클러스터와 통신할 수 있도록 클러스터에 대한 `kubeconfig` 파일을 생성하거나 업데이트합니다.

   ```
   aws eks update-kubeconfig --region $region_code --name $cluster_name
   ```

   기본적으로 `config` 파일이 `~/.kube`에 생성되거나 새 클러스터의 구성이 `~/.kube`의 기존 `config` 파일에 추가됩니다.

1. 노드 IAM 역할을 생성합니다.

   1. 다음 명령을 실행해 `vpc-cni-ipv6-policy.json` 파일을 생성합니다.

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "ec2:AssignIpv6Addresses",
                      "ec2:DescribeInstances",
                      "ec2:DescribeTags",
                      "ec2:DescribeNetworkInterfaces",
                      "ec2:DescribeInstanceTypes"
                  ],
                  "Resource": "*"
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "ec2:CreateTags"
                  ],
                  "Resource": [
                      "arn:aws:ec2:*:*:network-interface/*"
                  ]
              }
          ]
      }
      ```

   1. IAM 정책을 생성합니다.

      ```
      aws iam create-policy --policy-name AmazonEKS_CNI_IPv6_Policy --policy-document file://vpc-cni-ipv6-policy.json
      ```

   1. 다음 명령을 실행해 `node-role-trust-relationship.json` 파일을 생성합니다.

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

   1. 다음 명령을 실행하여 역할 이름에 대한 변수를 설정합니다. *AmazonEKSNodeRole*을 선택한 이름으로 바꿀 수 있습니다.

      ```
      export node_role_name=AmazonEKSNodeRole
      ```

   1. IAM 역할을 생성합니다.

      ```
      aws iam create-role --role-name $node_role_name --assume-role-policy-document file://"node-role-trust-relationship.json"
      ```

   1. IAM 정책을 IAM 역할에 연결합니다.

      ```
      aws iam attach-role-policy --policy-arn arn:aws:iam::$account_id:policy/AmazonEKS_CNI_IPv6_Policy \
          --role-name $node_role_name
      ```
**중요**  
이 자습서에서는 단순화를 위해 이 IAM 역할에 정책이 연결되어 있습니다. 그러나 프로덕션 클러스터에서는 정책을 별도의 IAM 역할에 연결하는 것이 좋습니다. 자세한 내용은 [IRSA를 사용하도록 Amazon VPC CNI 플러그인 구성](cni-iam-role.md) 섹션을 참조하세요.

   1. 필요한 2개의 관리형 IAM 정책을 IAM 역할에 연결합니다.

      ```
      aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy \
        --role-name $node_role_name
      aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly \
        --role-name $node_role_name
      ```

   1. IAM 역할의 ARN을 검색하고 이후 단계를 위해 변수에 저장합니다.

      ```
      node_iam_role=$(aws iam get-role --role-name $node_role_name --query="Role.Arn" --output text)
      ```

1. 관리형 노드 그룹을 생성합니다.

   1. 이전 단계에서 생성한 서브넷의 ID를 확인합니다.

      ```
      echo $subnets
      ```

      예제 출력은 다음과 같습니다.

      ```
      subnet-0a1a56c486EXAMPLE,subnet-099e6ca77aEXAMPLE,subnet-0377963d69EXAMPLE,subnet-0c05f819d5EXAMPLE
      ```

   1. 노드 그룹을 생성합니다. *0a1a56c486EXAMPLE*, *099e6ca77aEXAMPLE*, *0377963d69EXAMPLE*, *0c05f819d5EXAMPLE*을 이전 단계의 출력에서 반환된 값으로 바꾸세요. 다음 명령의 이전 출력에서 서브넷 ID 사이의 쉼표를 제거해야 합니다. *t3.medium*을 [AWS Nitro 시스템 인스턴스 유형](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html#ec2-nitro-instances)으로 바꿀 수 있습니다.

      ```
      aws eks create-nodegroup --region $region_code --cluster-name $cluster_name --nodegroup-name $nodegroup_name \
          --subnets subnet-0a1a56c486EXAMPLE subnet-099e6ca77aEXAMPLE subnet-0377963d69EXAMPLE subnet-0c05f819d5EXAMPLE \
          --instance-types t3.medium --node-role $node_iam_role
      ```

      노드 그룹을 만드는 데 몇 분 정도 걸립니다. 다음 명령을 실행합니다. 반환되는 출력이 `ACTIVE`가 되면 다음 단계로 진행하세요.

      ```
      aws eks describe-nodegroup --region $region_code --cluster-name $cluster_name --nodegroup-name $nodegroup_name \
          --query nodegroup.status --output text
      ```

1. `IP` 열에서 기본 포드에 `IPv6` 주소가 할당되었는지 확인합니다.

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

   예제 출력은 다음과 같습니다.

   ```
   NAME                       READY   STATUS    RESTARTS   AGE     IP                                       NODE                                            NOMINATED NODE   READINESS GATES
   aws-node-rslts             1/1     Running   1          5m36s   2600:1f13:b66:8200:11a5:ade0:c590:6ac8   ip-192-168-34-75.region-code.compute.internal   <none>           <none>
   aws-node-t74jh             1/1     Running   0          5m32s   2600:1f13:b66:8203:4516:2080:8ced:1ca9   ip-192-168-253-70.region-code.compute.internal  <none>           <none>
   coredns-85d5b4454c-cw7w2   1/1     Running   0          56m     2600:1f13:b66:8203:34e5::                ip-192-168-253-70.region-code.compute.internal  <none>           <none>
   coredns-85d5b4454c-tx6n8   1/1     Running   0          56m     2600:1f13:b66:8203:34e5::1               ip-192-168-253-70.region-code.compute.internal  <none>           <none>
   kube-proxy-btpbk           1/1     Running   0          5m36s   2600:1f13:b66:8200:11a5:ade0:c590:6ac8   ip-192-168-34-75.region-code.compute.internal   <none>           <none>
   kube-proxy-jjk2g           1/1     Running   0          5m33s   2600:1f13:b66:8203:4516:2080:8ced:1ca9   ip-192-168-253-70.region-code.compute.internal  <none>           <none>
   ```

1. `IP` 열에서 기본 서비스에 `IPv6` 주소가 할당되었는지 확인합니다.

   ```
   kubectl get services -n kube-system -o wide
   ```

   예제 출력은 다음과 같습니다.

   ```
   NAME       TYPE        CLUSTER-IP          EXTERNAL-IP   PORT(S)         AGE   SELECTOR
   kube-dns   ClusterIP   fd30:3087:b6c2::a   <none>        53/UDP,53/TCP   57m   k8s-app=kube-dns
   ```

1. (선택 사항) [샘플 애플리케이션을 배포](sample-deployment.md)하거나 [AWS Load Balancer Controller](aws-load-balancer-controller.md)와 샘플 애플리케이션을 배포하여 [Application Load Balancer를 사용하여 애플리케이션 및 HTTP 트래픽 라우팅](alb-ingress.md)를 사용하는 HTTP 애플리케이션 또는 [Network Load Balancer를 사용하여 TCP 및 UDP 트래픽 라우팅](network-load-balancing.md)을 사용하는 네트워크 트래픽을 `IPv6` 포드로 로드 밸런싱합니다.

1. 이 튜토리얼로 생성한 클러스터 및 노드 사용을 마친 후 다음 명령을 사용하여 생성한 리소스를 정리해야 합니다. 리소스를 삭제하기 전에 이 튜토리얼 외부의 리소스를 사용하고 있지 않은지 확인합니다.

   1. 이전 단계를 완료한 것과 다른 셸에서 이 단계를 완료하는 경우 이전 단계에서 사용한 모든 변수의 값을 설정하고 예제 값을 이전 단계를 완료했을 때 지정한 값으로 바꿉니다. 이전 단계를 완료한 동일한 셸에서 이 단계를 완료하는 경우 다음 단계로 건너뜁니다.

      ```
      export region_code=region-code
      export vpc_stack_name=my-eks-ipv6-vpc
      export cluster_name=my-cluster
      export nodegroup_name=my-nodegroup
      export account_id=111122223333
      export node_role_name=AmazonEKSNodeRole
      export cluster_role_name=myAmazonEKSClusterRole
      ```

   1. 노드 그룹을 삭제합니다.

      ```
      aws eks delete-nodegroup --region $region_code --cluster-name $cluster_name --nodegroup-name $nodegroup_name
      ```

      삭제하는 데 몇 분 정도 걸립니다. 다음 명령을 실행합니다. 출력이 반환되는 경우 다음 단계로 진행하지 마세요.

      ```
      aws eks list-nodegroups --region $region_code --cluster-name $cluster_name --query nodegroups --output text
      ```

   1. 클러스터를 삭제합니다.

      ```
      aws eks delete-cluster --region $region_code --name $cluster_name
      ```

      클러스터를 삭제하는 데 몇 분 정도 걸립니다. 계속하기 전에 다음 명령으로 클러스터가 삭제되었는지 확인합니다.

      ```
      aws eks describe-cluster --region $region_code --name $cluster_name
      ```

      출력이 다음 출력과 유사할 때까지 다음 단계로 진행하지 마세요.

      ```
      An error occurred (ResourceNotFoundException) when calling the DescribeCluster operation: No cluster found for name: my-cluster.
      ```

   1. 생성한 IAM 리소스를 삭제합니다. 이전 단계에서 사용한 이름과 다른 이름을 선택한 경우 *AmazonEKS\$1CNI\$1IPv6\$1Policy*를 선택한 이름으로 바꿉니다.

      ```
      aws iam detach-role-policy --role-name $cluster_role_name --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
      aws iam detach-role-policy --role-name $node_role_name --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
      aws iam detach-role-policy --role-name $node_role_name --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
      aws iam detach-role-policy --role-name $node_role_name --policy-arn arn:aws:iam::$account_id:policy/AmazonEKS_CNI_IPv6_Policy
      aws iam delete-policy --policy-arn arn:aws:iam::$account_id:policy/AmazonEKS_CNI_IPv6_Policy
      aws iam delete-role --role-name $cluster_role_name
      aws iam delete-role --role-name $node_role_name
      ```

   1. 생성한 VPC AWS CloudFormation 스택을 삭제합니다.

      ```
      aws cloudformation delete-stack --region $region_code --stack-name $vpc_stack_name
      ```

# 포드에 대한 아웃바운드 인터넷 액세스 활성화
<a name="external-snat"></a>

 **적용 대상**: Linux `IPv4` Fargate 노드, Amazon EC2 인스턴스가 있는 Linux 노드

`IPv6` 패밀리를 사용하여 클러스터를 배포한 경우 `IPv6` 주소는 네트워크로 변환되지 않기 때문에 이 주제의 정보는 클러스터에 적용되지 않습니다. 클러스터에서 `IPv6` 사용에 대한 자세한 내용을 알아보려면 [클러스터, 포드 및 서비스에 대한 IPv6 주소에 대해 알아보기](cni-ipv6.md) 섹션을 참조하세요.

기본적으로 클러스터의 각 포드에는 포드가 배포된 VPC와 연결된 CIDR(Classless Inter-Domain Routing) 블록의 [프라이빗](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html#concepts-private-addresses) `IPv4` 주소가 할당됩니다. 동일한 VPC의 포드는 이러한 프라이빗 IP 주소를 엔드포인트로 사용하여 서로 통신합니다. 포드가 VPC에 연결된 CIDR 블록 내에 있지 않은 `IPv4` 주소와 통신하는 경우 Amazon VPC CNI 플러그인([Linux](https://github.com/aws/amazon-vpc-cni-k8s#amazon-vpc-cni-k8s) 또는 [Windows](https://github.com/aws/amazon-vpc-cni-plugins/tree/master/plugins/vpc-bridge)용)은 기본적으로 [\$1](#snat-exception)를 통해 포드의 `IPv4` 주소를 포드가 실행 중인 노드의 기본 [탄력적 네트워크 인터페이스](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#eni-basics)의 기본 프라이빗 `IPv4` 주소로 변환합니다.

**참고**  
Windows 노드의 경우 고려해야 할 추가 세부 정보가 있습니다. 기본적으로 [Windows용 VPC CNI 플러그인](https://github.com/aws/amazon-vpc-cni-plugins/tree/master/plugins/vpc-bridge)은 동일한 VPC 내의 대상에 대한 트래픽이 SNAT에서 제외되는 네트워킹 구성으로 정의됩니다. 이는 내부 VPC 통신에 SNAT가 비활성화되어 있고 포드에 할당된 IP 주소를 VPC 내에서 라우팅할 수 있음을 의미합니다. 그러나 VPC 외부의 대상에 대한 트래픽은 소스 포드 IP SNAT가 인스턴스 ENI의 기본 IP 주소에 연결되어 있습니다. Windows에 대한 이 기본 구성은 포드가 호스트 인스턴스와 동일한 방식으로 VPC 외부의 네트워크에 액세스할 수 있도록 합니다.

이 동작으로 인해 다음이 발생합니다.
+ 실행 중인 노드가 [퍼블릭](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html#concepts-public-addresses) 또는 [탄력적](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-eips.html) IP 주소를 할당받고 [퍼블릭 서브넷](https://docs.aws.amazon.com/vpc/latest/userguide/configure-subnets.html#subnet-basics)에 있는 경우에만 포드가 인터넷 리소스와 통신할 수 있습니다. 퍼블릭 서브넷은 인터넷 게이트웨이로 이어지는 라우팅이 있는 [라우팅 테이블](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Route_Tables.html)과 연결된 서브넷입니다. 가능하면 프라이빗 서브넷에 노드를 배포하는 것이 좋습니다.
+ `1.8.0` 이전 플러그인 버전의 경우 [VPC 피어링](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html), [전송 VPC](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/transit-vpc-option.html) 또는 [AWS Direct Connect](https://docs.aws.amazon.com/directconnect/latest/UserGuide/Welcome.html)를 사용하여 클러스터 VPC에 연결된 네트워크 또는 VPC에 있는 리소스는 보조 탄력적 네트워크 인터페이스 뒤에 있는 포드와의 통신을 시작할 수 없습니다. 그럼에도 포드는 이러한 리소스와 통신을 시작하고 응답을 수신할 수 있습니다.

사용자 환경에서 다음 설명 중 하나에 해당하는 경우 다음 명령을 사용하여 기본 구성을 변경하십시오.
+ 네트워크 또는 [VPC 피어링](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html), [전송 VPC](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/transit-vpc-option.html) 또는 [AWS Direct Connect](https://docs.aws.amazon.com/directconnect/latest/UserGuide/Welcome.html)를 사용하여 클러스터 VPC에 연결된 리소스가 `IPv4` 주소를 사용하여 포드와 통신을 시작해야 하며 플러그인 버전이 `1.8.0`보다 이전 버전인 네트워크 또는 VPC에 있습니다.
+ 포드는 [프라이빗 서브넷](https://docs.aws.amazon.com/vpc/latest/userguide/configure-subnets.html#subnet-basics)에 있으며 인터넷과 아웃바운드로 통신해야 합니다. 서브넷은 [NAT 게이트웨이로](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html) 가는 경로를 가지고 있습니다.

```
kubectl set env daemonset -n kube-system aws-node AWS_VPC_K8S_CNI_EXTERNALSNAT=true
```

**참고**  
`AWS_VPC_K8S_CNI_EXTERNALSNAT` 및 `AWS_VPC_K8S_CNI_EXCLUDE_SNAT_CIDRS` CNI 구성 변수는 Windows 노드에 적용할 수 없습니다. Windows에서는 SNAT를 비활성화할 수 없습니다. SNAT에서 `IPv4` CIDR 목록을 제외하는 경우 Windows 부트스트랩 스크립트에서 `ExcludedSnatCIDRs` 파라미터를 지정하여 이를 정의할 수 있습니다. 이 파라미터 사용에 대한 자세한 내용은 [부트스트랩 스크립트 구성 파라미터](eks-optimized-windows-ami.md#bootstrap-script-configuration-parameters) 섹션을 참조하세요.

## 호스트 네트워킹
<a name="snat-exception"></a>

\$1 포드의 사양에 `hostNetwork=true`(기본값은 `false`)가 포함된 경우 해당 IP 주소가 다른 주소로 변환되지 않습니다. 이 경우는 기본적으로 클러스터에서 실행되는 `kube-proxy` 및 Kubernetes용 Amazon VPC CNI 플러그인 포드의 경우입니다. 이러한 포드의 경우 IP 주소는 노드의 기본 IP 주소와 동일하므로 포드의 IP 주소는 변환되지 않습니다. 포드의 `hostNetwork` 설정에 대한 자세한 내용은 Kubernetes API Reference의 [PodSpec v1 core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#podspec-v1-core)를 참조하세요.

# Kubernetes 네트워크 정책을 통해 pod 트래픽 제한
<a name="cni-network-policy"></a>

## 개요
<a name="_overview"></a>

기본적으로 클러스터의 포드 또는 다른 네트워크의 포드와 리소스 사이에 IP 주소, 포트 또는 연결에 대해 Kubernetes에는 제한이 없습니다. Kubernetes *네트워크 정책*을 사용하여 포드에서 송수신되는 네트워크 트래픽을 제한할 수 있습니다. 자세한 내용은 쿠버네티스 문서의 [네트워크 정책](https://kubernetes.io/docs/concepts/services-networking/network-policies/)을 참조하세요.

## 표준 네트워크 정책
<a name="_standard_network_policy"></a>

표준 `NetworkPolicy`를 사용하여 클러스터에서 포드 간 트래픽을 분할할 수 있습니다. 이러한 네트워크 정책은 OSI 네트워크 모델의 계층 3 및 4에서 작동하므로 Amazon EKS 클러스터 내 IP 주소 또는 포트 수준에서 트래픽 흐름을 제어할 수 있습니다. 표준 네트워크 정책은 네임스페이스 수준으로 범위가 지정됩니다.

### 사용 사례
<a name="_use_cases"></a>
+ 워크로드 간에 네트워크 트래픽을 분할하여 관련 애플리케이션만 서로 통신할 수 있도록 보장합니다.
+ 정책을 통해 네임스페이스 수준에서 테넌트를 격리하여 네트워크 분리를 적용합니다.

### 예제
<a name="_example"></a>

아래 정책에서는 *sun* 네임스페이스의 *webapp* 포드에서 송신 트래픽이 제한됩니다.

```
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: webapp-egress-policy
  namespace: sun
spec:
  podSelector:
    matchLabels:
      role: webapp
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: moon
      podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 8080
  - to:
    - namespaceSelector:
        matchLabels:
          name: stars
      podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 8080
```

이 정책은 `sun` 네임스페이스에 `role: webapp` 레이블이 있는 포드에 적용됩니다.
+ 허용된 트래픽: TCP 포트 `8080`에서 `moon` 네임스페이스의 `role: frontend` 레이블이 있는 포드 
+ 허용된 트래픽: TCP 포트 `8080`에서 `stars` 네임스페이스의 role: frontend 레이블이 있는 포드 
+ 차단된 트래픽: `webapp` 포드에서의 다른 모든 아웃바운드 트래픽은 암시적으로 거부됨

## 관리자(또는 클러스터) 네트워크 정책
<a name="_admin_or_cluster_network_policy"></a>

![\[EKS에서 네트워크 정책의 평가 순서에 대한 그림\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/evaluation-order.png)


`ClusterNetworkPolicy`를 사용하여 전체 클러스터에 적용되는 네트워크 보안 표준을 적용할 수 있습니다. 각 네임스페이스에 대해 고유한 정책을 반복적으로 정의하고 유지하는 대신 단일 정책을 사용하여 네임스페이스에 관계없이 클러스터의 여러 워크로드에 대한 네트워크 액세스 제어를 중앙에서 관리할 수 있습니다.

### 사용 사례
<a name="_use_cases_2"></a>
+ EKS 클러스터의 모든 워크로드와 워크로드의 하위 집합에 대한 네트워크 액세스 제어를 중앙에서 관리합니다.
+ 전체 클러스터에서 기본 네트워크 보안 태세를 정의합니다.
+ 보다 운영 효율적인 방식으로 조직 보안 표준을 클러스터 범위로 확장합니다.

### 예제
<a name="_example_2"></a>

아래 정책에서 다른 네임스페이스의 클러스터 트래픽을 명시적으로 차단하여 민감한 워크로드 네임스페이스에 대한 네트워크 액세스를 방지할 수 있습니다.

```
apiVersion: networking.k8s.aws/v1alpha1
kind: ClusterNetworkPolicy
metadata:
  name: protect-sensitive-workload
spec:
  tier: Admin
  priority: 10
  subject:
    namespaces:
      matchLabels:
        kubernetes.io/metadata.name: earth
  ingress:
    - action: Deny
      from:
      - namespaces:
          matchLabels: {} # Match all namespaces.
      name: select-all-deny-all
```

## 중요 정보
<a name="_important_notes"></a>

Kubernetes에 대한 Amazon VPC CNI 플러그인의 네트워크 정책은 아래 낭려된 구성에서 지원됩니다.
+ 표준 및 관리자 네트워크 정책 모두에 대한 Amazon VPC CNI 플러그인 버전 1.21.0 이상.
+ `IPv4` 또는 `IPv6` 주소에 대해 구성된 클러스터.
+ [포드에 대한 보안 그룹](security-groups-for-pods.md)과 함께 네트워크 정책을 사용할 수 있습니다. 네트워크 정책을 사용하면 클러스터 내 모든 통신을 제어할 수 있습니다. 포드용 보안 그룹을 통해 포드 내의 애플리케이션에서 AWS 서비스에 대한 액세스를 제어할 수 있습니다.
+ 사용자 지정 네트워킹** 및 접두사 위임**에 네트워크 정책을 사용할 수 있습니다.

## 고려 사항
<a name="cni-network-policy-considerations"></a>

 **아키텍처** 
+ Kubernetes용 Amazon VPC CNI 플러그인 사용을 통해 클러스터에 Kubernetes 네트워크 정책을 적용할 때 Amazon EC2 Linux 노드에만 정책을 적용할 수 있습니다. Fargate 또는 Windows 노드에는 정책을 적용할 수 없습니다.
+ 네트워크 정책은 `IPv4` 또는 `IPv6` 주소만 적용하지만 둘 다 적용되지는 않습니다. `IPv4` 클러스터에서 VPC CNI는 포드에 `IPv4` 주소를 할당하고 `IPv4` 정책을 적용합니다. `IPv6` 클러스터에서 VPC CNI는 포드에 `IPv6` 주소를 할당하고 `IPv6` 정책을 적용합니다. `IPv6` 클러스터에 적용된 모든 `IPv4` 네트워크 정책 규칙은 무시됩니다. `IPv4` 클러스터에 적용된 모든 `IPv6` 네트워크 정책 규칙은 무시됩니다.

 **네트워크 정책** 
+ 네트워크 정책은 배포의 일부인 포드에만 적용됩니다. `metadata.ownerReferences` 세트가 없는 독립 실행형 포드에는 네트워크 정책이 적용될 수 없습니다.
+ 여러 네트워크 정책을 동일한 포드에 적용할 수 있습니다. 동일한 포드를 선택한 둘 이상의 정책이 구성된 경우 모든 정책이 포드에 적용됩니다.
+ 단일 IP 주소 범위(CIDR)에 대한 포트 및 프로토콜의 최대 조합 수는 모든 네트워크 정책에서 24개입니다. `namespaceSelector`와 같은 선택기는 하나 이상의 CIDR로 확인됩니다. 여러 개의 선택기가 단일 CIDR로 확인되거나 동일하거나 다른 네트워크 정책에서 동일한 직접 CIDR을 여러 번 지정하는 경우 모두 이 제한에 포함됩니다.
+ Kubernetes 서비스의 경우 서비스 포트는 컨테이너 포트와 동일해야 합니다. 이름이 지정된 포트를 사용하는 경우 서비스 사양에도 같은 이름을 사용합니다.

 **관리자 네트워크 정책** 

1.  **관리자 티어 정책(먼저 평가됨)**: 모든 관리자 티어 ClusterNetworkPolicies는 다른 정책보다 먼저 평가됩니다. 관리자 티어 내에서 정책은 우선순위에 따라 처리됩니다(가장 낮은 우선순위 번호 먼저 처리됨). 작업 유형에 따라 다음 상황이 결정됩니다.
   +  **거부 작업(가장 높은 우선순위)**: 거부 작업이 있는 관리자 정책이 트래픽과 일치하면 다른 정책에 관계없이 해당 트래픽이 즉시 차단됩니다. 추가 ClusterNetworkPolicy 또는 NetworkPolicy 규칙은 더 이상 처리되지 않습니다. 이를 통해 조직 전체의 보안 제어가 네임스페이스 수준 정책에 의해 재정의되지 않습니다.
   +  **허용 작업**: 거부 규칙을 평가한 후 허용 작업이 있는 관리자 정책은 우선순위에 따라 처리됩니다(가장 낮은 우선순위 번호 먼저 처리됨). 허용 작업이 일치하면 트래픽이 수락되고 추가 정책 평가가 수행되지 않습니다. 이러한 정책은 레이블 선택기를 기반으로 여러 네임스페이스에 액세스 권한을 부여하여 특정 리소스에 액세스할 수 있는 워크로드를 중앙에서 제어할 수 있습니다.
   +  **통과 작업**: 관리자 티어 정책에서 통과 작업은 의사 결정이 하위 티어로 위임합니다. 트래픽이 통과 규칙과 일치하면 평가는 해당 트래픽에 대한 나머지 모든 관리자 티어 규칙을 건너뛰고 NetworkPolicy 티어로 바로 진행합니다. 이를 통해 관리자는 특정 트래픽 패턴에 대한 제어를 애플리케이션 팀에 명시적으로 위임할 수 있습니다. 예를 들어 통과 규칙을 사용하여 외부 액세스에 대한 엄격한 제어를 유지하면서 네임스페이스 내 트래픽 관리를 네임스페이스 관리자에게 위임할 수 있습니다.

1.  **네트워크 정책 티어**: 거부 또는 허용과 일치하는 관리자 티어 정책이 없거나 통과 작업이 일치하는 경우 네임스페이스 범위의 NetworkPolicy 리소스가 다음에 평가됩니다. 이러한 정책은 개별 네임스페이스 내에서 세분화된 제어를 제공하며 애플리케이션 팀이 관리합니다. 네임스페이스 범위의 정책은 관리자 정책보다 더 제한적일 수 있습니다. 관리자 정책의 거부 결정을 재정의할 수는 없지만 관리자 정책에서 허용하거나 전달하는 트래픽을 추가로 제한할 수 있습니다.

1.  **기준 티어 관리자 정책**: 트래픽과 일치하는 관리자 또는 네임스페이스 범위의 정책이 없는 경우 기준 티어 ClusterNetworkPolicies가 평가됩니다. 이는 네임스페이스 범위의 정책으로 재정의할 수 있는 기본 보안 태세를 제공하므로 관리자는 조직 전체의 기본값을 설정하는 동시에 필요에 따라 팀에 사용자 지정할 수 있는 유연성을 제공할 수 있습니다. 기준 정책은 우선순위에 따라(가장 낮은 우선순위 번호 먼저) 평가됩니다.

1.  **기본 거부(정책이 일치하지 않는 경우)**:이러한 기본적으로 거부 동작은 명시적으로 허용된 연결만 허용되도록 보장하여 강력한 보안 태세를 유지 관리합니다.

 **마이그레이션** 
+ 클러스터에서 현재 타사 솔루션을 사용하여 Kubernetes 네트워크 정책을 관리하는 경우 Kubernetes용 Amazon VPC CNI 플러그인에 동일한 정책을 사용할 수 있습니다. 하지만 동일한 정책을 관리하지 않도록 기존 솔루션을 제거해야 합니다.

**주의**  
네트워크 정책 솔루션을 제거한 후 네트워크 정책 솔루션이 적용된 모든 노드를 교체하는 것이 좋습니다. 트래픽 규칙이 갑자기 종료될 경우 솔루션의 포드에 의해 지연될 수 있기 때문입니다.

 **설치**.
+ 네트워크 정책 기능에서 `policyendpoints.networking.k8s.aws`라는 `PolicyEndpoint` 사용자 지정 리소스 정의(CRD)가 생성되고 이를 사용해야 합니다.사용자 지정 참조의 `PolicyEndpoint` 개체는 Amazon EKS에서 관리합니다. 이러한 리소스를 수정하거나 삭제해서는 안 됩니다.
+ 인스턴스 역할 IAM 보안 인증 정보를 사용하는 포드를 실행하거나 EC2 IMDS에 연결하는 경우 EC2 IMDS에 대한 액세스를 차단하는 네트워크 정책을 주의하여 확인하세요. EC2 IMDS에 대한 액세스를 허용하려면 네트워크 정책을 추가해야 할 수도 있습니다. 자세한 내용은 Amazon EC2 사용 설명서의 [인스턴스 메타데이터 및 사용자 데이터](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)를 참조하세요.

  *서비스 계정에 대한 IAM 역할*을 사용하는 포드 또는 *EKS Pod Identity*를 사용하는 포드는 EC2 IMDS에 액세스하지 않습니다.
+ Kubernetes용 Amazon VPC CNI 플러그인은 각 포드의 추가 네트워크 인터페이스에 네트워크 정책을 적용하지 않고 각 포드의 기본 인터페이스(`eth0`)에만 적용합니다. 이는 다음 아키텍처에 영향을 미칩니다.
  +  `ENABLE_V4_EGRESS` 변수가 `true`로 설정된 `IPv6` 포드. 이 변수를 사용하면 `IPv4` 송신 기능을 통해 IPv6 포드를 클러스터 외부의 항목과 같이 `IPv4` 엔드포인트에 연결할 수 있습니다. `IPv4` 송신 기능은 로컬 루프백 IPv4 주소를 사용하여 추가 네트워크 인터페이스를 생성하여 작동합니다.
  + Multus와 같은 체인 네트워크 플러그인을 사용하는 경우. 이러한 플러그인은 각 포드에 네트워크 인터페이스를 추가하므로 네트워크 정책은 체인 네트워크 플러그인에 적용되지 않습니다.

# Kubernetes 네트워크 정책으로 포드 네트워크 트래픽 제한
<a name="cni-network-policy-configure"></a>

Kubernetes 네트워크 정책을 사용하여 포드에서 송수신되는 네트워크 트래픽을 제한할 수 있습니다. 자세한 내용은 쿠버네티스 문서의 [네트워크 정책](https://kubernetes.io/docs/concepts/services-networking/network-policies/)을 참조하세요.

이 기능을 사용하려면 다음을 구성해야 합니다.

1. 포드 시작 시 정책 적용을 설정합니다. VPC CNI `DaemonSet`의 `aws-node` 컨테이너에서 이 작업을 수행합니다.

1. 추가 기능의 네트워크 정책 파라미터를 활성화합니다.

1. Kubernetes 네트워크 정책을 사용하도록 클러스터 구성

시작하기 전에 고려 사항을 검토하세요. 자세한 내용은 [고려 사항](cni-network-policy.md#cni-network-policy-considerations) 섹션을 참조하세요.

## 사전 조건
<a name="cni-network-policy-prereqs"></a>

다음은 기능의 사전 조건입니다.

### 최소 클러스터 버전
<a name="cni-network-policy-minimum"></a>

기존 Amazon EKS 클러스터. 배포하려면 [Amazon EKS 시작하기](getting-started.md) 섹션을 참조하세요. 클러스터는 다음 표에 나열된 Kubernetes 버전 및 플랫폼 버전 중 하나를 실행해야 합니다. 나열된 것보다 이후의 모든 Kubernetes 및 플랫폼 버전도 지원됩니다. 다음 명령에서 *my-cluster*를 본인의 클러스터 이름으로 바꾼 다음 수정된 명령을 실행하여 현재 Kubernetes 버전을 확인할 수 있습니다.

```
aws eks describe-cluster --name my-cluster --query cluster.version --output text
```


| Kubernetes 버전 | 플랫폼 버전 | 
| --- | --- | 
|   `1.27.4`   |   `eks.5`   | 
|   `1.26.7`   |   `eks.6`   | 

### 최소 VPC CNI 버전
<a name="cni-network-policy-minimum-vpc"></a>

표준 Kubernetes 네트워크 정책과 관리자 네트워크 정책을 모두 생성하려면 VPC CNI 플러그인의 `1.21` 버전을 실행해야 합니다. 다음 명령을 사용하여 현재 버전을 확인할 수 있습니다.

```
kubectl describe daemonset aws-node --namespace kube-system | grep amazon-k8s-cni: | cut -d : -f 3
```

버전이 `1.21` 이하인 경우 [Amazon VPC CNI 업데이트(Amazon EKS 추가 기능)](vpc-add-on-update.md)의 내용을 참조하여 버전을 `1.21` 이상으로 업그레이드합니다.

### 최소 Linux 커널 버전
<a name="cni-network-policy-minimum-linux"></a>

노드의 Linux 커널 버전이 `5.10` 이상이어야 합니다. `uname -r`을 사용하여 커널 버전을 확인할 수 있습니다. Amazon EKS 최적화 Amazon Linux, Amazon EKS 최적화 가속 Amazon Linux AMI, Bottlerocket AMI의 최신 버전을 사용하는 경우 이미 필수 커널 버전이 설치되어 있습니다.

Amazon EKS 최적화 가속 Amazon Linux AMI 버전 `v20231116` 이상에는 커널 버전 `5.10`이 있습니다.

## 1단계: 포드 시작 시 정책 적용 설정
<a name="cni-network-policy-configure-policy"></a>

Kubernetes용 Amazon VPC CNI 플러그인은 포드 프로비저닝과 병행하여 포드에 대한 네트워크 정책을 구성합니다. 새 포드에 대해 모든 정책이 구성될 때까지 새 포드의 컨테이너는 **기본 허용 정책으로 시작됩니다. 이를 **표준 모드라고 합니다. 기본 허용 정책은 새 포드를 오가는 모든 수신 및 송신 트래픽이 허용됨을 의미합니다. 예를 들어, 새 포드가 활성 정책으로 업데이트될 때까지 포드에는 방화벽 규칙이 적용되지 않습니다(모든 트래픽이 허용됨).

`NETWORK_POLICY_ENFORCING_MODE` 변수가 `strict`로 설정되면 VPC CNI를 사용하는 포드는 **기본 거부 정책으로 시작하고, 정책이 구성됩니다. **이를 엄격 모드라고 합니다. 엄격 모드에서는 클러스터에서 포드가 액세스해야 하는 모든 엔드포인트에 대한 네트워크 정책이 있어야 합니다. 이 요구 사항은 CoreDNS 포드에 적용됩니다. 호스트 네트워킹을 사용하는 포드에는 기본 거부 정책이 구성되어 있지 않습니다.

VPC CNI `DaemonSet`의 `aws-node` 컨테이너에서 환경 변수 `NETWORK_POLICY_ENFORCING_MODE`를 `strict`로 설정하여 기본 네트워크 정책을 변경할 수 있습니다.

```
env:
  - name: NETWORK_POLICY_ENFORCING_MODE
    value: "strict"
```

## 2단계: 추가 기능의 네트워크 정책 파라미터 활성화
<a name="enable-network-policy-parameter"></a>

네트워크 정책 기능은 기본적으로 노드의 포트 `8162`를 지표에 사용합니다. 또한 이 기능은 상태 프로브에 포트 `8163`을 사용합니다. 이러한 포트를 사용해야 하는 노드 또는 포드 내부에서 다른 애플리케이션을 실행하면 앱이 실행되지 않습니다. VPC CNI 버전 `v1.14.1` 이상에서 이러한 포트를 변경할 수 있습니다.

다음 절차를 사용하여 추가 기능에 대한 네트워크 정책 파라미터를 활성화합니다.

### AWS Management Console
<a name="cni-network-policy-console"></a>

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

1. 왼쪽 탐색 창에서 **클러스터**를 선택한 다음 Amazon VPC CNI 추가 기능을 구성할 클러스터의 이름을 선택합니다.

1. **추가 기능** 탭을 선택합니다.

1. 추가 기능 상자의 오른쪽 상단에 있는 상자를 선택한 다음에 **편집**을 선택합니다.

1. **`Amazon VPC CNI` 구성** 페이지에서

   1. **버전** 목록에서 `v1.14.0-eksbuild.3` 이상 버전을 선택합니다.

   1. **선택적 구성 설정**을 확장합니다.

   1. **구성 값**에 JSON 키 `"enableNetworkPolicy":` 및 값 `"true"`를 입력합니다. 결과 텍스트는 유효한 JSON 객체여야 합니다. 이 키와 값이 텍스트 상자의 유일한 데이터인 경우, 키와 값을 중괄호(`{ }`)로 둘러쌉니다.

      다음 예제에서는 네트워크 정책 기능이 활성화되어 있고 지표 및 상태 프로브가 기본 포트 번호로 설정되어 있습니다.

      ```
      {
          "enableNetworkPolicy": "true",
          "nodeAgent": {
              "healthProbeBindAddr": "8163",
              "metricsBindAddr": "8162"
          }
      }
      ```

### Helm
<a name="cni-network-helm"></a>

`helm`을 통해 Kubernetes용 Amazon VPC CNI 플러그인을 설치한 경우 구성을 업데이트하여 포트를 변경할 수 있습니다.

1. 다음 명령을 실행하여 포트를 변경합니다. 키 `nodeAgent.metricsBindAddr` 또는 키 `nodeAgent.healthProbeBindAddr`의 값에 각각 포트 번호를 설정합니다.

   ```
   helm upgrade --set nodeAgent.metricsBindAddr=8162 --set nodeAgent.healthProbeBindAddr=8163 aws-vpc-cni --namespace kube-system eks/aws-vpc-cni
   ```

### kubectl
<a name="cni-network-policy-kubectl"></a>

1. 편집기에서 `aws-node` `DaemonSet`를 엽니다.

   ```
   kubectl edit daemonset -n kube-system aws-node
   ```

1. VPC CNI `aws-node` 대몬 세트 매니페스트의 `aws-network-policy-agent` 컨테이너에 있는 `args:`의 다음 명령 인수에서 포트 번호를 바꿉니다.

   ```
       - args:
               - --metrics-bind-addr=:8162
               - --health-probe-bind-addr=:8163
   ```

## 3단계: Kubernetes 네트워크 정책을 사용하도록 클러스터 구성
<a name="cni-network-policy-setup"></a>

Amazon EKS 추가 기능 또는 자체 관리형 추가 기능에 대해 이를 설정할 수 있습니다.

### Amazon EKS 추가 기능
<a name="cni-network-policy-setup-procedure-add-on"></a>

AWS CLI로 다음 명령을 실행하여 Kubernetes 네트워크 정책을 사용하도록 클러스터를 구성할 수 있습니다. `my-cluster`를 본인의 클러스터 이름으로 바꾸고 IAM 역할 ARN을 사용 중인 역할로 바꿉니다.

```
aws eks update-addon --cluster-name my-cluster --addon-name vpc-cni --addon-version v1.14.0-eksbuild.3 \
    --service-account-role-arn arn:aws:iam::123456789012:role/AmazonEKSVPCCNIRole \
    --resolve-conflicts PRESERVE --configuration-values '{"enableNetworkPolicy": "true"}'
```

AWS Management Console을 사용하여 이를 구성하려면 다음 단계를 따르세요.

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

1. 왼쪽 탐색 창에서 **클러스터**를 선택한 다음 Amazon VPC CNI 추가 기능을 구성할 클러스터의 이름을 선택합니다.

1. **추가 기능** 탭을 선택합니다.

1. 추가 기능 상자의 오른쪽 상단에 있는 상자를 선택한 다음에 **편집**을 선택합니다.

1. **`Amazon VPC CNI` 구성** 페이지에서

   1. **버전** 목록에서 `v1.14.0-eksbuild.3` 이상 버전을 선택합니다.

   1. **선택적 구성 설정**을 확장합니다.

   1. **구성 값**에 JSON 키 `"enableNetworkPolicy":` 및 값 `"true"`를 입력합니다. 결과 텍스트는 유효한 JSON 객체여야 합니다. 이 키와 값이 텍스트 상자의 유일한 데이터인 경우, 키와 값을 중괄호(`{ }`)로 둘러쌉니다. 다음 예시는 네트워크 정책이 활성화된 것을 보여줍니다.

      ```
      { "enableNetworkPolicy": "true" }
      ```

      다음 스크린샷은 이 시나리오의 예를 보여줍니다.  
![\[선택적 구성에 네트워크 정책이 포함된 VPC CNI 애드온을 보여주는 <shared id=“consolelong”/>입니다.\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/console-cni-config-network-policy.png)

### 자체 관리형 추가 기능
<a name="cni-network-policy-setup-procedure-self-managed-add-on"></a>

`helm`을 통해 Kubernetes용 Amazon VPC CNI 플러그인을 설치한 경우 구성을 업데이트하여 네트워크 정책을 활성화할 수 있습니다.

1. 다음 명령을 실행하여 네트워크 정책을 활성화합니다.

   ```
   helm upgrade --set enableNetworkPolicy=true aws-vpc-cni --namespace kube-system eks/aws-vpc-cni
   ```

1. 편집기에서 `amazon-vpc-cni` `ConfigMap`을 엽니다.

   ```
   kubectl edit configmap -n kube-system amazon-vpc-cni -o yaml
   ```

1. 다음 줄을 `ConfigMap`의 `data`에 추가합니다.

   ```
   enable-network-policy-controller: "true"
   ```

   줄을 추가한 후에는 `ConfigMap`이 다음 예와 같을 것입니다.

   ```
   apiVersion: v1
    kind: ConfigMap
    metadata:
     name: amazon-vpc-cni
     namespace: kube-system
    data:
     enable-network-policy-controller: "true"
   ```

1. 편집기에서 `aws-node` `DaemonSet`를 엽니다.

   ```
   kubectl edit daemonset -n kube-system aws-node
   ```

   1. VPC CNI `aws-node` 대몬 세트 매니페스트의 `aws-network-policy-agent` 컨테이너에 있는 `args:`의 명령 인수 `--enable-network-policy=false`에서 `false`를 `true`로 바꿉니다.

      ```
           - args:
              - --enable-network-policy=true
      ```

## 4단계. 다음 단계
<a name="cni-network-policy-setup-procedure-confirm"></a>

구성을 완료한 후 `aws-node` 포드가 클러스터에서 실행 중인지 확인합니다.

```
kubectl get pods -n kube-system | grep 'aws-node\|amazon'
```

예제 출력은 다음과 같습니다.

```
aws-node-gmqp7                                          2/2     Running   1 (24h ago)   24h
aws-node-prnsh                                          2/2     Running   1 (24h ago)   24h
```

버전 `1.14` 이상에서는 `aws-node` 포드에 2개의 컨테이너가 있습니다. 이전 버전에서 네트워크 정책이 비활성화된 경우 `aws-node` 포드에 하나의 컨테이너만 있습니다.

이제 클러스터에 Kubernetes 네트워크 정책을 배포할 수 있습니다.

Kubernetes 네트워크 정책을 구현하기 위해 Kubernetes `NetworkPolicy` 또는 `ClusterNetworkPolicy` 객체를 생성하여 클러스터에 배포할 수 있습니다. `NetworkPolicy` 객체는 네임스페이스로 범위가 지정되는 반면, `ClusterNetworkPolicy` 객체는 전체 클러스터 또는 여러 네임스페이스로 범위가 지정될 수 있습니다. 정책을 구현하여 레이블 선택기, 네임스페이스 및 IP 주소 범위를 기반으로 포드 사이의 트래픽을 허용 또는 거부합니다. `NetworkPolicy` 객체 생성에 대한 자세한 내용은 쿠버네티스 문서의 [네트워크 정책](https://kubernetes.io/docs/concepts/services-networking/network-policies/#networkpolicy-resource)을 참조하세요.

Kubernetes `NetworkPolicy` 객체의 적용은 확장 Berkeley 패킷 필터(eBPF)를 사용하여 구현됩니다. `iptables` 기반 구현에 따라 지연 시간을 낮추고 CPU 활용률 감소 및 순차 조회 방지를 포함한 성능 특성을 제공합니다. 추가로 eBPF 프로브는 복잡한 커널 수준 문제를 디버깅하고 관찰성을 개선하는 데 도움이 되도록 컨텍스트가 풍부한 데이터에 대한 액세스를 제공합니다. Amazon EKS는 프로브를 활용하여 각 노드에 정책 결과를 기록하고 외부 로그 수집기로 데이터를 내보내 디버깅을 지원하는 eBPF 기반 내보내기를 지원합니다. 자세한 내용은 [eBDF 설명](https://ebpf.io/what-is-ebpf/#what-is-ebpf)를 참조하세요.

# Amazon EKS 포드 네트워크 트래픽에 대한 Kubernetes 네트워크 정책 비활성화
<a name="network-policy-disable"></a>

Kubernetes 네트워크 정책을 비활성화하여 Amazon EKS 포드 네트워크 트래픽 제한 중지

1. 모든 Kubernetes 네트워크 정책을 나열합니다.

   ```
   kubectl get netpol -A
   ```

1. 각 Kubernetes 네트워크 정책을 삭제합니다. 네트워크 정책을 비활성화하기 전에 모든 네트워크 정책을 삭제해야 합니다.

   ```
   kubectl delete netpol <policy-name>
   ```

1. 편집기에서 aws-node DaemonSet를 엽니다.

   ```
   kubectl edit daemonset -n kube-system aws-node
   ```

1. VPC CNI `aws-node` 데몬 세트 매니페스트의 `aws-network-policy-agent` 컨테이너에 있는 `args:`의 명령 인수 `--enable-network-policy=true`에서 `true`를 `false`로 바꿉니다.

   ```
        - args:
           - --enable-network-policy=true
   ```

# Amazon EKS에 대한 Kubernetes 네트워크 정책 문제 해결
<a name="network-policies-troubleshooting"></a>

Amazon VPC CNI의 네트워크 정책 기능에 대한 문제 해결 가이드입니다.

이 가이드에서는 다음을 다룹니다.
+ 설치 정보, CRD 및 RBAC 권한 [새 `policyendpoints` CRD 및 권한](#network-policies-troubleshooting-permissions) 
+ 네트워크 정책 문제 [네트워크 정책 로그](#network-policies-troubleshooting-flowlogs) 진단 시 검사할 로그 
+ 문제 해결을 위한 eBPF SDK 도구 모음 실행
+ 알려진 문제 및 해결 방법 [알려진 문제 및 해결 방법](#network-policies-troubleshooting-known-issues) 

**참고**  
네트워크 정책은 Kubernetes *배포*에서 만든 포드에만 적용됩니다. VPC CNI의 네트워크 정책에 대한 추가 제한 사항은 [고려 사항](cni-network-policy.md#cni-network-policy-considerations) 섹션을 참조하세요.

네트워크 정책을 사용하는 네트워크 연결의 문제를 해결하고 조사하려면 [네트워크 정책 로그](#network-policies-troubleshooting-flowlogs)를 읽고 [eBPF SDK](#network-policies-ebpf-sdk)의 도구를 실행하여 문제를 해결할 수 있습니다.

## 새 `policyendpoints` CRD 및 권한
<a name="network-policies-troubleshooting-permissions"></a>
+ CRD: `policyendpoints.networking.k8s.aws` 
+ Kubernetes API: `v1.networking.k8s.io`라는 `apiservice` 
+ Kubernetes 리소스: `Kind: NetworkPolicy` 
+ RBAC: `aws-node`(VPC CNI)라는 `ClusterRole`, `eks:network-policy-controller`(EKS 클러스터 컨트롤 플레인의 네트워크 정책 컨트롤러)라는 `ClusterRole`

네트워크 정책의 경우 VPC CNI는 `policyendpoints.networking.k8s.aws`라는 새 `CustomResourceDefinition`(CRD)을 생성합니다. VPC CNI에 CRD를 생성하고 VPC CNI(`eniconfigs.crd.k8s.amazonaws.com`)가 설치한 이 CRD와 다른 CRD의 CustomResources(CR)를 생성할 수 있는 권한이 있어야 합니다. 두 CRD 모두 GitHub의 [`crds.yaml` 파일](https://github.com/aws/amazon-vpc-cni-k8s/blob/master/charts/aws-vpc-cni/crds/customresourcedefinition.yaml)에서 사용할 수 있습니다. 구체적으로, VPC CNI에 `policyendpoints`에 대한 ‘get’, ‘list’ 및 ‘watch’ 동사 권한이 있어야 합니다.

Kubernetes *네트워크 정책*은 `v1.networking.k8s.io`라는 `apiservice`의 일부이며, 정책 YAML 파일에서는 `apiversion: networking.k8s.io/v1`입니다. VPC CNI `DaemonSet`에 Kubernetes API의 이 부분을 사용할 수 있는 권한이 있어야 합니다.

VPC CNI 권한은 `aws-node`라는 `ClusterRole`에 있습니다. `ClusterRole` 객체는 네임스페이스에 그룹화되지 않습니다. 다음은 클러스터의 `aws-node`를 보여줍니다.

```
kubectl get clusterrole aws-node -o yaml
```

```
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    app.kubernetes.io/instance: aws-vpc-cni
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: aws-node
    app.kubernetes.io/version: v1.19.4
    helm.sh/chart: aws-vpc-cni-1.19.4
    k8s-app: aws-node
  name: aws-node
rules:
- apiGroups:
  - crd.k8s.amazonaws.com
  resources:
  - eniconfigs
  verbs:
  - list
  - watch
  - get
- apiGroups:
  - ""
  resources:
  - namespaces
  verbs:
  - list
  - watch
  - get
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - list
  - watch
  - get
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - list
  - watch
  - get
- apiGroups:
  - ""
  - events.k8s.io
  resources:
  - events
  verbs:
  - create
  - patch
  - list
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints/status
  verbs:
  - get
- apiGroups:
  - vpcresources.k8s.aws
  resources:
  - cninodes
  verbs:
  - get
  - list
  - watch
  - patch
```

또한 새 컨트롤러는 각 EKS 클러스터의 컨트롤 플레인에서 실행됩니다. 컨트롤러는 `eks:network-policy-controller`라는 `ClusterRole`의 권한을 사용합니다. 다음은 클러스터의 `eks:network-policy-controller`를 보여줍니다.

```
kubectl get clusterrole eks:network-policy-controller -o yaml
```

```
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    app.kubernetes.io/name: amazon-network-policy-controller-k8s
  name: eks:network-policy-controller
rules:
- apiGroups:
  - ""
  resources:
  - namespaces
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - services
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints
  verbs:
  - create
  - delete
  - get
  - list
  - patch
  - update
  - watch
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints/finalizers
  verbs:
  - update
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints/status
  verbs:
  - get
  - patch
  - update
- apiGroups:
  - networking.k8s.io
  resources:
  - networkpolicies
  verbs:
  - get
  - list
  - patch
  - update
  - watch
```

## 네트워크 정책 로그
<a name="network-policies-troubleshooting-flowlogs"></a>

VPC CNI가 네트워크 정책에 따라 연결을 허용할지 거부할지에 대한 각각의 결정은 *흐름 로그*에 기록됩니다. 각 노드의 네트워크 정책 로그에는 네트워크 정책이 있는 모든 포드의 흐름 로그가 포함됩니다. 네트워크 정책 로그는 `/var/log/aws-routed-eni/network-policy-agent.log`에 저장됩니다. 다음은 `network-policy-agent.log` 파일의 예입니다.

```
{"level":"info","timestamp":"2023-05-30T16:05:32.573Z","logger":"ebpf-client","msg":"Flow Info: ","Src
IP":"192.168.87.155","Src Port":38971,"Dest IP":"64.6.160","Dest
Port":53,"Proto":"UDP","Verdict":"ACCEPT"}
```

네트워크 정책 로그는 기본적으로 비활성화되어 있습니다. 네트워크 정책 로그를 활성화하려면 다음 단계를 수행합니다.

**참고**  
네트워크 정책 로그에는 VPC CNI `aws-node` `DaemonSet` 매니페스트의 `aws-network-policy-agent` 컨테이너용 vCPU 1개가 추가로 필요합니다.

### Amazon EKS 추가 기능
<a name="cni-network-policy-flowlogs-addon"></a>

 ** AWS Management Console **   

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

1. 왼쪽 탐색 창에서 **클러스터**를 선택한 다음 Amazon VPC CNI 추가 기능을 구성할 클러스터의 이름을 선택합니다.

1. **추가 기능** 탭을 선택합니다.

1. 추가 기능 상자의 오른쪽 상단에 있는 상자를 선택한 다음에 **편집**을 선택합니다.

1. ***Amazon VPC CNI* 구성** 페이지에서

   1. **버전** 드롭다운 목록에서 `v1.14.0-eksbuild.3` 이상 버전을 선택합니다.

   1. **선택적 구성 설정**을 확장합니다.

   1. 최상위 JSON 키 `"nodeAgent":`를 입력하고 값은 키 `"enablePolicyEventLogs":`와 **구성 값**의 `"true"` 값이 포함된 객체입니다. 결과 텍스트는 유효한 JSON 객체여야 합니다. 다음 예시는 네트워크 정책과 네트워크 정책 로그가 활성화되어 있으며 CloudWatch Logs로 전송된 것을 보여줍니다.

      ```
      {
          "enableNetworkPolicy": "true",
          "nodeAgent": {
              "enablePolicyEventLogs": "true"
          }
      }
      ```

다음 스크린샷은 이 시나리오의 예를 보여줍니다.

![\[선택적 구성에서 네트워크 정책 및 CloudWatch 로그가 포함된 VPC CNI 애드온을 보여주는 <shared id=“consolelong”/>입니다.\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/console-cni-config-network-policy-logs.png)


 AWS CLI  

1. 다음 AWS CLI 명령을 실행합니다. `my-cluster`를 본인의 클러스터 이름으로 바꾸고 IAM 역할 ARN을 사용 중인 역할로 바꿉니다.

   ```
   aws eks update-addon --cluster-name my-cluster --addon-name vpc-cni --addon-version v1.14.0-eksbuild.3 \
       --service-account-role-arn arn:aws:iam::123456789012:role/AmazonEKSVPCCNIRole \
       --resolve-conflicts PRESERVE --configuration-values '{"nodeAgent": {"enablePolicyEventLogs": "true"}}'
   ```

### 자체 관리형 추가 기능
<a name="cni-network-policy-flowlogs-selfmanaged"></a>

Helm  
`helm`을 통해 Kubernetes용 Amazon VPC CNI 플러그인을 설치한 경우 구성을 업데이트하여 네트워크 정책을 쓸 수 있습니다.  

1. 다음 명령을 실행하여 네트워크 정책을 활성화합니다.

   ```
   helm upgrade --set nodeAgent.enablePolicyEventLogs=true aws-vpc-cni --namespace kube-system eks/aws-vpc-cni
   ```

kubectl  
`kubectl`을 통해 Kubernetes용 Amazon VPC CNI 플러그인을 설치한 경우 구성을 업데이트하여 네트워크 정책을 쓸 수 있습니다.  

1. 편집기에서 `aws-node` `DaemonSet`를 엽니다.

   ```
   kubectl edit daemonset -n kube-system aws-node
   ```

1. VPC CNI `aws-node` `DaemonSet` 매니페스트의 `aws-network-policy-agent` 컨테이너에 있는 `args:`의 명령 인수 `--enable-policy-event-logs=false`에서 `false`를 `true`로 바꿉니다.

   ```
        - args:
           - --enable-policy-event-logs=true
   ```

### 네트워크 정책 로그를 Amazon CloudWatch Logs로 전송
<a name="network-policies-cloudwatchlogs"></a>

Amazon CloudWatch Logs와 같은 서비스를 사용하여 네트워크 정책 로그를 모니터링할 수 있습니다. 다음 방법을 사용하여 네트워크 정책 로그를 CloudWatch Logs로 보낼 수 있습니다.

EKS 클러스터의 경우 정책 로그는 `/aws/eks/cluster-name/cluster/` 아래에 있고 자체 관리형 K8S 클러스터의 경우 로그는 `/aws/k8s-cluster/cluster/` 아래에 있습니다.

#### Kubernetes용 Amazon VPC CNI 플러그인을 사용하여 네트워크 정책 로그 전송
<a name="network-policies-cwl-agent"></a>

네트워크 정책을 활성화하면 두 번째 컨테이너가 노드 에이전트**용 `aws-node` 포드에 추가됩니다. 이 노드 에이전트는 네트워크 정책 로그를 CloudWatch Logs로 보낼 수 있습니다.

**참고**  
네트워크 정책 로그는 노드 에이전트에 의해서만 전송됩니다. VPC CNI에서 생성한 다른 로그는 포함되지 않습니다.

##### 사전 조건
<a name="cni-network-policy-cwl-agent-prereqs"></a>
+ VPC CNI에 사용하는 IAM 역할에 다음 권한을 스탠자 또는 별도의 정책으로 추가합니다.

  ```
  {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
          {
              "Sid": "VisualEditor0",
              "Effect": "Allow",
              "Action": [
                  "logs:DescribeLogGroups",
                  "logs:CreateLogGroup",
                  "logs:CreateLogStream",
                  "logs:PutLogEvents"
              ],
              "Resource": "*"
          }
      ]
  }
  ```

##### Amazon EKS 추가 기능
<a name="cni-network-policy-cwl-agent-addon"></a>

 ** AWS Management Console **   

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

1. 왼쪽 탐색 창에서 **클러스터**를 선택한 다음 Amazon VPC CNI 추가 기능을 구성할 클러스터의 이름을 선택합니다.

1. **추가 기능** 탭을 선택합니다.

1. 추가 기능 상자의 오른쪽 상단에 있는 상자를 선택한 다음에 **편집**을 선택합니다.

1. ***Amazon VPC CNI* 구성** 페이지에서

   1. **버전** 드롭다운 목록에서 `v1.14.0-eksbuild.3` 이상 버전을 선택합니다.

   1. **선택적 구성 설정**을 확장합니다.

   1. 최상위 JSON 키 `"nodeAgent":`를 입력하고 값은 키 `"enableCloudWatchLogs":`와 **구성 값**의 `"true"` 값이 포함된 객체입니다. 결과 텍스트는 유효한 JSON 객체여야 합니다. 다음 예시는 네트워크 정책과 네트워크 정책 로그가 활성화되어 있으며 로그가 CloudWatch Logs로 전송된 것을 보여줍니다.

      ```
      {
          "enableNetworkPolicy": "true",
          "nodeAgent": {
              "enablePolicyEventLogs": "true",
              "enableCloudWatchLogs": "true",
          }
      }
      ```
다음 스크린샷은 이 시나리오의 예를 보여줍니다.

![\[선택적 구성에서 네트워크 정책 및 CloudWatch 로그가 포함된 VPC CNI 애드온을 보여주는 <shared id=“consolelong”/>입니다.\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/console-cni-config-network-policy-logs-cwl.png)


 ** AWSCLI**   

1. 다음 AWS CLI 명령을 실행합니다. `my-cluster`를 본인의 클러스터 이름으로 바꾸고 IAM 역할 ARN을 사용 중인 역할로 바꿉니다.

   ```
   aws eks update-addon --cluster-name my-cluster --addon-name vpc-cni --addon-version v1.14.0-eksbuild.3 \
       --service-account-role-arn arn:aws:iam::123456789012:role/AmazonEKSVPCCNIRole \
       --resolve-conflicts PRESERVE --configuration-values '{"nodeAgent": {"enablePolicyEventLogs": "true", "enableCloudWatchLogs": "true"}}'
   ```

##### 자체 관리형 추가 기능
<a name="cni-network-policy-cwl-agent-selfmanaged"></a>

 **Helm**   
`helm`을 통해 Kubernetes용 Amazon VPC CNI 플러그인을 설치한 경우 구성을 업데이트하여 네트워크 정책 로그를 CloudWatch Logs로 전송할 수 있습니다.  

1. 다음 명령을 실행하여 네트워크 정책 로그를 활성화하고 CloudWatch Logs로 전송합니다.

   ```
   helm upgrade --set nodeAgent.enablePolicyEventLogs=true --set nodeAgent.enableCloudWatchLogs=true aws-vpc-cni --namespace kube-system eks/aws-vpc-cni
   ```

 **kubectl**   

1. 편집기에서 `aws-node` `DaemonSet`를 엽니다.

   ```
   kubectl edit daemonset -n kube-system aws-node
   ```

1. VPC CNI `aws-node` `DaemonSet` 매니페스트의 `aws-network-policy-agent` 컨테이너에 있는 `args:`에서 두 명령 인수 `--enable-policy-event-logs=false` 및 `--enable-cloudwatch-logs=false`에서 `false`를 `true`로 바꿉니다.

   ```
        - args:
           - --enable-policy-event-logs=true
           - --enable-cloudwatch-logs=true
   ```

#### Fluent Bit `DaemonSet`로 네트워크 정책 로그 전송
<a name="network-policies-cwl-fluentbit"></a>

`DaemonSet`에서 Fluent Bit를 사용하여 노드에서 로그를 전송하는 경우 네트워크 정책에서 네트워크 정책 로그를 포함하도록 구성을 추가할 수 있습니다. 다음 예제 구성을 사용할 수 있습니다.

```
    [INPUT]
        Name              tail
        Tag               eksnp.*
        Path              /var/log/aws-routed-eni/network-policy-agent*.log
        Parser            json
        DB                /var/log/aws-routed-eni/flb_npagent.db
        Mem_Buf_Limit     5MB
        Skip_Long_Lines   On
        Refresh_Interval  10
```

## eBPF SDK 포함
<a name="network-policies-ebpf-sdk"></a>

Kubernetes용 Amazon VPC CNI 플러그인은 노드에 eBPF SDK 도구 모음을 설치합니다. eBPF SDK 도구를 사용하여 네트워크 정책 관련 문제를 식별할 수 있습니다. 예를 들어, 다음 명령은 노드에서 실행 중인 프로그램을 나열합니다.

```
sudo /opt/cni/bin/aws-eks-na-cli ebpf progs
```

이 명령을 실행하려면 임의의 방법을 사용하여 노드에 연결할 수 있습니다.

## 알려진 문제 및 해결 방법
<a name="network-policies-troubleshooting-known-issues"></a>

다음 섹션에서는 Amazon VPC CNI 네트워크 정책 기능과 관련된 알려진 문제와 해결 방법을 설명합니다.

### enable-policy-event-logs가 false로 설정되어 있음에도 불구하고 네트워크 정책 로그가 생성됨
<a name="network-policies-troubleshooting-policy-event-logs"></a>

 **문제**: `enable-policy-event-logs` 설정이 `false`로 설정된 경우에도 EKS VPC CNI가 네트워크 정책 로그를 생성합니다.

 **해결 방법**: `enable-policy-event-logs` 설정은 정책 ‘결정’ 로그만 비활성화하고, 모든 네트워크 정책 에이전트 로깅은 비활성화하지 않습니다. 이 동작은 GitHub의 [aws-network-policy-agent README](https://github.com/aws/aws-network-policy-agent/)에 설명되어 있습니다. 로깅을 완전히 비활성화하려면 다른 로깅 구성을 조정해야 할 수 있습니다.

### 네트워크 정책 맵 정리 문제
<a name="network-policies-troubleshooting-map-cleanup"></a>

 **문제**: 네트워크 `policyendpoint` 문제가 여전히 존재하며 포드가 삭제된 후에도 정리되지 않습니다.

 **해결 방법**: 이 문제는 VPC CNI 추가 기능 버전 1.19.3-eksbuild.1의 문제로 인해 발생했습니다. 이 문제를 해결하려면 최신 버전의 VPC CNI 추가 기능으로 업데이트하세요.

### 네트워크 정책이 적용되지 않음
<a name="network-policies-troubleshooting-policyendpoint"></a>

 **문제**: Amazon VPC CNI 플러그인에서 네트워크 정책 기능이 활성화되었지만 네트워크 정책이 제대로 적용되지 않습니다.

네트워크 정책 `kind: NetworkPolicy`를 만들었지만 포드에 영향을 주지 않는 경우 정책 엔드포인트 객체가 포드와 동일한 네임스페이스에 생성되었는지 확인합니다. 네임스페이스에 `policyendpoint` 객체가 없는 경우 네트워크 정책 컨트롤러(EKS 클러스터의 일부)가 적용할 네트워크 정책 에이전트(VPC CNI의 일부)에 대한 네트워크 정책 규칙을 생성할 수 없습니다.

 **해결 방법**: 해결 방법은 VPC CNI(`ClusterRole` : `aws-node`)와 네트워크 정책 컨트롤러(`ClusterRole` : `eks:network-policy-controller`)의 권한을 수정하고 Kyverno와 같은 정책 시행 도구에서 이러한 작업을 허용하는 것입니다. Kyverno 정책이 `policyendpoint` 객체 생성을 차단하지 않는지 확인하세요. [새 `policyendpoints` CRD 및 권한](#network-policies-troubleshooting-permissions)에서 필요한 권한은 이전 섹션을 참조하세요.

### 엄격한 모드에서 정책 삭제 후 포드가 기본 거부 상태로 돌아가지 않음
<a name="network-policies-troubleshooting-strict-mode-fallback"></a>

 **문제**: 네트워크 정책이 엄격한 모드에서 활성화되면 포드가 기본 거부 정책으로 시작합니다. 정책이 적용된 후 지정된 엔드포인트로 트래픽이 허용됩니다. 그러나 정책가 삭제되면 포드가 기본 거부 상태로 돌아가지 않고 대신 기본 허용 상태로 전환됩니다.

 **해결 방법**: 이 문제는 네트워크 정책 에이전트 1.2.0 릴리스가 포함된 VPC CNI 릴리스 1.19.3에서 수정되었습니다. 엄격한 모드가 활성화된 상태에서 수정 후 정책이 제거되면 포드는 예상대로 기본 거부 상태로 돌아갑니다.

### 포드 시작 지연 시간을 위한 보안 그룹
<a name="network-policies-troubleshooting-sgfp-latency"></a>

 **문제**: EKS에서 포드용 보안 그룹 기능을 사용하면 포드 시작 지연 시간이 늘어납니다.

 **해결 방법**: 지연 시간은 VPC 리소스 컨트롤러가 포드에 대한 브랜치 ENI를 생성하는 데 사용하는 `CreateNetworkInterface` API의 API 스로틀링으로 인한 리소스 컨트롤러의 속도 제한 때문에 발생합니다. 이 작업에 대한 계정의 API 한도를 확인하고 필요한 경우 한도 증가 요청을 고려하세요.

### vpc.amazonaws.com/pod-eni 부족으로 인한 FailedScheduling
<a name="network-policies-troubleshooting-insufficient-pod-eni"></a>

 **문제**: `FailedScheduling 2m53s (x28 over 137m) default-scheduler 0/5 nodes are available: 5 Insufficient vpc.amazonaws.com/pod-eni. preemption: 0/5 nodes are available: 5 No preemption victims found for incoming pod.` 오류와 함께 포드 예약에 실패합니다.

 **해결 방법**: 이전 문제와 마찬가지로 포드에 보안 그룹을 할당하면 포드 예약 지연 시간이 증가하고 각 ENI를 추가하는 데 걸리는 시간 동안 CNI 임곗값을 초과하여 포드를 시작하지 못할 수 있습니다. 포드에 보안 그룹을 사용할 때 예상되는 동작입니다. 워크로드 아키텍처를 설계할 때 예약에 미치는 영향을 고려하세요.

### IPAM 연결 문제 및 세분화 결함
<a name="network-policies-troubleshooting-systemd-udev"></a>

 **문제**: IPAM 연결 문제, 스로틀링 요청, 세분화 결함 등의 여러 오류가 발생합니다.
+  `Checking for IPAM connectivity …​` 
+  `Throttling request took 1.047064274s` 
+  `Retrying waiting for IPAM-D` 
+  `panic: runtime error: invalid memory address or nil pointer dereference` 

 **해결 방법**: AL2023에 `systemd-udev`를 설치하면 파일이 잘못된 정책으로 다시 작성되어 이 문제가 발생합니다. 이는 업데이트된 패키지가 있는 다른 `releasever`로 업데이트하거나 패키지 자체를 수동으로 업데이트할 때 발생할 수 있습니다. AL2023 노드에 `systemd-udev`를 설치하거나 업데이트하지 마세요.

### 이름 오류로 디바이스를 찾을 수 없음
<a name="network-policies-troubleshooting-device-not-found"></a>

 **문제**: 오류 메시지: `{"level":"error","ts":"2025-02-05T20:27:18.669Z","caller":"ebpf/bpf_client.go:578","msg":"failed to find device by name eni9ea69618bf0: %!w(netlink.LinkNotFoundError={0xc000115310})"}` 

 **해결 방법**: 이 문제는 최신 버전의 Amazon VPC CNI 네트워크 정책 에이전트(v1.2.0)에서 확인되어 수정되었습니다. 이 문제를 해결하려면 최신 버전의 VPC CNI로 업데이트하세요.

### Multus CNI 이미지의 CVE 취약성
<a name="network-policies-troubleshooting-cve-multus"></a>

 **문제**: 고급 EKS ImageScan CVE 보고서에서 Multus CNI 이미지 버전 v4.1.4-eksbuild.2\$1thick의 취약점을 식별합니다.

 **해결 방법**: 취약성이 없는 새 버전의 Multus CNI 이미지와 새 네트워크 정책 컨트롤러 이미지로 업데이트하세요. 이전 버전에서 발견된 취약성을 해결하도록 스캐너를 업데이트할 수 있습니다.

### 로그의 흐름 정보 DENY 판정
<a name="network-policies-troubleshooting-flow-info-deny"></a>

 **문제**: 네트워크 정책 로그에 DENY 판정이 표시됩니다. `{"level":"info","ts":"2024-11-25T13:34:24.808Z","logger":"ebpf-client","caller":"events/events.go:193","msg":"Flow Info: ","Src IP":"","Src Port":9096,"Dest IP":"","Dest Port":56830,"Proto":"TCP","Verdict":"DENY"}` 

 **해결 방법**: 이 문제는 새로운 버전의 네트워크 정책 컨트롤러에서 해결되었습니다. 로깅 문제를 해결하려면 최신 EKS 플랫폼 버전으로 업데이트하세요.

### Calico에서 마이그레이션 후 포드 간 통신 문제
<a name="network-policies-troubleshooting-calico-migration"></a>

 **문제**: EKS 클러스터를 버전 1.30으로 업그레이드하고 네트워크 정책을 위해 Calico에서 Amazon VPC CNI로 전환한 후 네트워크 정책 적용 시 포드 간 통신이 실패합니다. 네트워크 정책이 삭제되면 통신이 복원됩니다.

 **해결 방법**: VPC CNI의 네트워크 정책 에이전트는 Calico만큼 많은 포트를 지정할 수 없습니다. 대신 네트워크 정책에서 포트 범위를 사용하세요. 네트워크 정책의 각 `ingress:` 또는 `egress:` 선택기에서 각 프로토콜의 고유한 포트 조합 최대 수는 24입니다. 포트 범위를 사용하여 고유한 포트 수를 줄이고 이러한 제한을 방지하세요.

### 네트워크 정책 에이전트는 독립 실행형 포드를 지원하지 않습니다.
<a name="network-policies-troubleshooting-standalone-pods"></a>

 **문제**: 독립 실행형 포드에 적용된 네트워크 정책에 일관되지 않은 동작이 있을 수 있습니다.

 **해결 방법**: 네트워크 정책 에이전트는 현재 배포/replicaset의 일부로 배포된 포드만 지원합니다. 네트워크 정책이 독립 실행형 포드에 적용되는 경우 동작에 일부 불일치가 있을 수 있습니다. 이는 이 페이지 상단의 [고려 사항](cni-network-policy.md#cni-network-policy-considerations)과 GitHub의 [aws-network-policy-agent GitHub 이슈 \$1327](https://github.com/aws/aws-network-policy-agent/issues/327)에 문서화되어 있습니다. 일관된 네트워크 정책 동작을 위해 배포 또는 replicaset의 일부로 포드를 배포하세요.

# Amazon EKS 네트워크 정책에 대한 Stars 데모
<a name="network-policy-stars-demo"></a>

이 데모는 Amazon EKS 클러스터에 프런트엔드, 백엔드 및 클라이언트 서비스를 생성합니다. 데모는 또한 각 서비스 간 이용 가능한 수신 및 발신 경로를 보여주는 관리 그래픽 사용자 인터페이스를 생성합니다. 프로덕션 워크로드를 실행하지 않는 클러스터에서 데모를 완료하는 것이 좋습니다.

네트워크 정책을 생성하기 전에 모든 서비스는 양방향으로 통신할 수 있습니다. 네트워크 정책을 적용하면 클라이언트가 프런트엔드 서비스와만 통신할 수 있고 백엔드는 프런트엔드의 트래픽만 수신하는 것을 볼 수 있습니다.

1. 프런트엔드, 백엔드, 클라이언트 및 관리 사용자 인터페이스 서비스를 적용합니다.

   ```
   kubectl apply -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/namespace.yaml
   kubectl apply -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/management-ui.yaml
   kubectl apply -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/backend.yaml
   kubectl apply -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/frontend.yaml
   kubectl apply -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/client.yaml
   ```

1. 클러스터의 모든 포드를 봅니다.

   ```
   kubectl get pods -A
   ```

   예제 출력은 다음과 같습니다.

   출력에서 다음 출력에 표시된 네임스페이스에 포드가 표시되어야 합니다. 포드의 *이름*과 `READY` 열의 포드 수는 다음 출력과 다릅니다. 이름이 비슷하고 `STATUS` 열에 `Running`이 있는 포드가 보일 때까지 계속하지 마세요.

   ```
   NAMESPACE         NAME                                       READY   STATUS    RESTARTS   AGE
   [...]
   client            client-xlffc                               1/1     Running   0          5m19s
   [...]
   management-ui     management-ui-qrb2g                        1/1     Running   0          5m24s
   stars             backend-sz87q                              1/1     Running   0          5m23s
   stars             frontend-cscnf                             1/1     Running   0          5m21s
   [...]
   ```

1. 관리 사용자 인터페이스에 연결하려면 클러스터에서 실행 중인 서비스의 `EXTERNAL-IP`에 연결합니다.

   ```
   kubectl get service/management-ui -n management-ui
   ```

1. 브라우저를 열어 이전 단계의 위치로 이동합니다. 관리 사용자 인터페이스가 표시됩니다. **C** 노드는 클라이언트 서비스이고, **F** 노드는 프런트엔드 서비스이며, **B** 노드는 백엔드 서비스입니다. 각 노드는 기타 모든 노드에 대한 전체 통신 액세스를 보유합니다(진한 색상의 선으로 표시).  
![\[개방형 네트워크 정책\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/stars-default.png)

1. `stars` 및 `client` 네임스페이스 모두에 다음 네트워크 정책을 적용하여 서비스를 각각 격리시킵니다.

   ```
   kind: NetworkPolicy
   apiVersion: networking.k8s.io/v1
   metadata:
     name: default-deny
   spec:
     podSelector:
       matchLabels: {}
   ```

   다음 명령을 사용하여 두 네임스페이스 모두에 정책을 적용할 수 있습니다.

   ```
   kubectl apply -n stars -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/apply_network_policies.files/default-deny.yaml
   kubectl apply -n client -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/apply_network_policies.files/default-deny.yaml
   ```

1. 브라우저를 새로 고칩니다. 관리 사용자 인터페이스가 더 이상 노드에 도달하지 않아 사용자 인터페이스에 표시되지 않는 것을 확인할 수 있습니다.

1. 다음의 다른 네트워크 정책을 적용하여 관리 사용자 인터페이스가 서비스에 액세스하도록 허용합니다. 이 정책을 적용하여 UI 허용:

   ```
   kind: NetworkPolicy
   apiVersion: networking.k8s.io/v1
   metadata:
     namespace: stars
     name: allow-ui
   spec:
     podSelector:
       matchLabels: {}
     ingress:
       - from:
           - namespaceSelector:
               matchLabels:
                 role: management-ui
   ```

   이 정책을 적용하여 클라이언트를 허용합니다.

   ```
   kind: NetworkPolicy
   apiVersion: networking.k8s.io/v1
   metadata:
     namespace: client
     name: allow-ui
   spec:
     podSelector:
       matchLabels: {}
     ingress:
       - from:
           - namespaceSelector:
               matchLabels:
                 role: management-ui
   ```

   다음 명령을 사용하여 두 정책을 모두 적용할 수 있습니다.

   ```
   kubectl apply -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/apply_network_policies.files/allow-ui.yaml
   kubectl apply -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/apply_network_policies.files/allow-ui-client.yaml
   ```

1. 브라우저를 새로 고칩니다. 관리 사용자 인터페이스가 노드에 다시 도달할 수 있지만, 노드가 서로 통신할 수 없음을 확인할 수 있습니다.  
![\[UI 액세스 네트워크 정책\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/stars-no-traffic.png)

1. 다음 네트워크 정책을 적용하여 프런트엔드 서비스에서 백엔드 서비스로의 트래픽을 허용합니다.

   ```
   kind: NetworkPolicy
   apiVersion: networking.k8s.io/v1
   metadata:
     namespace: stars
     name: backend-policy
   spec:
     podSelector:
       matchLabels:
         role: backend
     ingress:
       - from:
           - podSelector:
               matchLabels:
                 role: frontend
         ports:
           - protocol: TCP
             port: 6379
   ```

1. 브라우저를 새로 고칩니다. 프런트엔드가 백엔드와 통신할 수 있음을 알 수 있습니다.  
![\[프런트엔드에서 백엔드 간 정책\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/stars-front-end-back-end.png)

1. 다음 네트워크 정책을 적용하여 클라이언트에서 프런트엔드 서비스로의 트래픽을 허용합니다.

   ```
   kind: NetworkPolicy
   apiVersion: networking.k8s.io/v1
   metadata:
     namespace: stars
     name: frontend-policy
   spec:
     podSelector:
       matchLabels:
         role: frontend
     ingress:
       - from:
           - namespaceSelector:
               matchLabels:
                 role: client
         ports:
           - protocol: TCP
             port: 80
   ```

1. 브라우저를 새로 고칩니다. 클라이언트가 프런트엔드 서비스와 통신할 수 있음을 알게 됩니다. 프런트엔드 서비스는 여전히 백엔드 서비스와 통신할 수 있습니다.  
![\[최종 네트워크 정책\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/stars-final.png)

1. (선택사항) 데모를 마쳤으면 리소스를 삭제할 수 있습니다.

   ```
   kubectl delete -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/client.yaml
   kubectl delete -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/frontend.yaml
   kubectl delete -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/backend.yaml
   kubectl delete -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/management-ui.yaml
   kubectl delete -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/namespace.yaml
   ```

   리소스를 삭제한 후에도 클러스터에서 예기치 않은 방식으로 네트워킹을 방해할 수 있는 네트워크 정책 엔드포인트가 노드에 있을 수 있습니다. 이러한 규칙을 제거하는 유일한 방법은 노드를 재부팅하거나 모든 노드를 종료하고 휴지통으로 이동하는 것입니다. 모든 노드를 종료하려면 Auto Scaling 그룹의 원하는 개수를 0으로 설정한 다음, 원하는 개수로 백업하거나 노드를 종료하면 됩니다.

# 사용자 지정 네트워킹을 통해 대체 서브넷에 포드 배포
<a name="cni-custom-network"></a>

 **적용 대상**: Linux `IPv4` Fargate 노드, Amazon EC2 인스턴스가 있는 Linux 노드

![\[여러 네트워크 인터페이스가 있는 노드 다이어그램\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/cn-image.png)


기본적으로 Kubernetes용 Amazon VPC CNI 플러그인은 Amazon EC2 노드의 [보조 Elastic 네트워크 인터페이스](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html)(네트워크 인터페이스)를 생성하는 경우 노드의 기본 네트워크 인터페이스와 동일한 서브넷에서 생성합니다. 또한 기본 네트워크 인터페이스에 연결된 보조 네트워크 인터페이스에 동일한 보안 그룹을 연결합니다. 다음 중 하나 이상의 이유로 플러그 인이 다른 서브넷에서 보조 네트워크 인터페이스를 생성하거나 다른 보안 그룹을 보조 네트워크 인터페이스에 연결하거나, 둘 다 하려고 할 수 있습니다.
+ 기본 네트워크 인터페이스가 있는 서브넷에서 사용할 수 있는 `IPv4` 주소의 수는 제한되어 있습니다. 이렇게 하면 서브넷에서 생성할 수 있는 포드 수가 제한될 수 있습니다. 보조 네트워크 인터페이스에 다른 서브넷을 사용하면 포드에 사용 가능한 `IPv4` 주소 수를 늘릴 수 있습니다.
+ 보안상의 이유로 포드는 노드의 기본 네트워크 인터페이스와 다른 서브넷 또는 보안 그룹을 사용해야 할 수 있습니다.
+ 노드는 퍼블릭 서브넷에서 구성되며, 포드를 프라이빗 서브넷에 배치할 수 있습니다. 퍼블릭 서브넷과 연결된 라우팅 테이블에는 인터넷 게이트웨이로 가는 경로가 포함됩니다. 프라이빗 서브넷과 연결된 라우팅 테이블에는 인터넷 게이트웨이로 가는 경로가 포함되지 않습니다.

**작은 정보**  
사용자 지정 네트워킹을 사용하지 않고 Amazon EKS 클러스터에 직접 새 서브넷 또는 기존 서브넷을 추가할 수도 있습니다. 자세한 내용은 [관리 콘솔에서 Amazon EKS 클러스터에 기존 VPC 서브넷 추가](eks-networking.md#add-existing-subnet) 단원을 참조하십시오.

## 고려 사항
<a name="cni-custom-network-considerations"></a>

다음은 기능 사용 시 고려 사항입니다.
+ 사용자 지정 네트워킹을 사용 설정하면 기본 네트워크 인터페이스에 할당된 IP 주소가 포드에 할당되지 않습니다. 보조 네트워크 인터페이스의 IP 주소만 포드에 할당됩니다.
+ 클러스터에서 `IPv6` 패밀리를 사용하는 경우 사용자 지정 네트워킹을 사용할 수 없습니다.
+ 사용자 지정 네트워킹을 사용하여 `IPv4` 주소 소모를 완화하려는 경우 대신 `IPv6` 패밀리를 사용하여 클러스터를 생성할 수 있습니다. 자세한 내용은 [클러스터, 포드 및 서비스에 대한 IPv6 주소에 대해 알아보기](cni-ipv6.md) 단원을 참조하십시오.
+ 보조 네트워크 인터페이스에 지정된 서브넷에 배포된 포드는 노드의 기본 네트워크 인터페이스와 다른 서브넷 및 보안 그룹을 사용할 수 있다고 해도 서브넷과 보안 그룹은 노드와 동일한 VPC에 있어야 합니다.
+ Fargate의 경우 서브넷은 Fargate 프로필을 통해 제어됩니다. 자세한 내용은 [시작 시 AWS Fargate를 사용하는 포드 정의](fargate-profile.md) 섹션을 참조하세요.

# Amazon EKS 노드에서 보조 네트워크 인터페이스 사용자 지정
<a name="cni-custom-network-tutorial"></a>

자습서를 시작하기 전에 다음을 완료합니다.
+ 고려 사항 검토
+ Kubernetes용 Amazon VPC CNI 플러그인이 보조 네트워크 인터페이스를 생성하고 포드에 IP 주소를 할당하는 방법 숙지하기. 자세한 내용을 알아보려면 GitHub의 [ENI 할당](https://github.com/aws/amazon-vpc-cni-k8s#eni-allocation)을 참조하세요.
+ 장치에 설치 및 구성된 AWS 명령줄 인터페이스(AWS CLI)의 버전 `2.12.3` 이상 또는 버전 `1.27.160` 이상 또는 AWS CloudShell. 현재 버전을 확인하려면 `aws --version | cut -d / -f2 | cut -d ' ' -f1`을 사용합니다. `yum`, `apt-get` 또는 macOS용 Homebrew와 같은 패키지 관리자는 최신 버전의 AWS CLI 이전에 나온 버전이 몇 가지 있을 때도 있습니다. 최신 버전을 설치하려면 * AWS 명령줄 인터페이스 사용 설명서*에서 [설치](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) 및 [aws config를 사용하여 빠른 구성](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config)을 참조하세요. AWS CloudShell에 설치된 AWS CLI 버전도 최신 버전보다 여러 버전 이전일 수도 있습니다. 업데이트하려면 * AWS CloudShell 사용 설명서*의 [홈 디렉터리에 AWS CLI 설치하기](https://docs.aws.amazon.com/cloudshell/latest/userguide/vm-specs.html#install-cli-software)를 참조하세요.
+ `kubectl` 명령줄 도구는 장치 또는 AWS CloudShell에 설치됩니다. `kubectl`을 설치하거나 업그레이드하려면 [`kubectl` 및 `eksctl` 설정](install-kubectl.md) 부분을 참조하세요.
+ Bash 셸에서 이 주제의 단계를 완료하는 것이 좋습니다. Bash 셸을 사용하지 않는 경우 줄 연속 문자 및 변수 설정 및 사용 방식과 같은 일부 스크립트 명령을 통해 셸이 조정되어야 합니다. 또한 쉘의 인용 및 이스케이프 규칙이 다를 수 있습니다. 자세한 내용은 AWS 명령줄 인터페이스 사용 설명서의 [AWS CLI에서 문자열에 따옴표 사용하기](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-parameters-quoting-strings.html)를 참조하세요.

본 자습서에서는 예제 값을 바꾸라고 언급된 경우를 제외하고는 이를 사용하는 것이 좋습니다. 프로덕션 클러스터의 단계를 완료하는 경우 예제 값을 바꿀 수 있습니다. 동일한 터미널에서 모든 단계를 완료하는 것이 좋습니다. 이는 변수가 여러 단계에서 설정되고 사용되면서 서로 다른 터미널에 존재하지 않기 때문입니다.

이 주제의 명령은 [AWS CLI 예제 사용](https://docs.aws.amazon.com/cli/latest/userguide/welcome-examples.html)에 나열된 규칙에 따라 형식이 지정되었습니다. 사용 중인 AWS CLI [프로필](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-profiles)에 정의된 기본 AWS 리전과 다른 AWS 리전에 있는 리소스에 대해 명령줄의 명령을 실행하는 경우에는 명령에 `--region us-west-2`를 추가하고 `us-west-2`를 해당 AWS 지역으로 바꿔야 합니다.

프로덕션 클러스터에 사용자 지정 네트워킹을 배포하려면 [2단계: VPC 구성](#custom-networking-configure-vpc)로 이동합니다.

## 1단계: 테스트 VPC 및 클러스터 생성
<a name="custom-networking-create-cluster"></a>

다음 절차를 활용하면 테스트 VPC 및 클러스터를 생성하고 해당 클러스터에 대해 사용자 지정 네트워킹을 구성할 수 있습니다. 프로덕션 클러스터에서 사용할 수 있는 관련 없는 기능들은 이 주제에서 다루지 않으므로 프로덕션 워크로드에 테스트 클러스터를 사용하지 않는 것이 좋습니다. 자세한 내용은 [Amazon EKS 클러스터 생성](create-cluster.md) 섹션을 참조하세요.

1. 다음 명령을 실행하여 `account_id` 변수를 정의합니다.

   ```
   account_id=$(aws sts get-caller-identity --query Account --output text)
   ```

1. VPC를 생성합니다.

   1. 테스트 시스템에 배포하는 경우 Amazon EKS AWS CloudFormation 템플릿을 사용하여 VPC를 생성합니다.

      ```
      aws cloudformation create-stack --stack-name my-eks-custom-networking-vpc \
        --template-url https://s3.us-west-2.amazonaws.com/amazon-eks/cloudformation/2020-10-29/amazon-eks-vpc-private-subnets.yaml \
        --parameters ParameterKey=VpcBlock,ParameterValue=192.168.0.0/24 \
        ParameterKey=PrivateSubnet01Block,ParameterValue=192.168.0.64/27 \
        ParameterKey=PrivateSubnet02Block,ParameterValue=192.168.0.96/27 \
        ParameterKey=PublicSubnet01Block,ParameterValue=192.168.0.0/27 \
        ParameterKey=PublicSubnet02Block,ParameterValue=192.168.0.32/27
      ```

   1. AWS CloudFormation 스택을 만드는 데 몇 분 정도 걸립니다. 스택의 배포 상태를 확인하려면 다음 명령을 실행합니다.

      ```
      aws cloudformation describe-stacks --stack-name my-eks-custom-networking-vpc --query Stacks\[\].StackStatus  --output text
      ```

      명령의 출력이 `CREATE_COMPLETE`가 될 때까지 다음 단계를 계속하지 마세요.

   1. 템플릿에서 생성한 프라이빗 서브넷 ID 값으로 변수를 정의합니다.

      ```
      subnet_id_1=$(aws cloudformation describe-stack-resources --stack-name my-eks-custom-networking-vpc \
          --query "StackResources[?LogicalResourceId=='PrivateSubnet01'].PhysicalResourceId" --output text)
      subnet_id_2=$(aws cloudformation describe-stack-resources --stack-name my-eks-custom-networking-vpc \
          --query "StackResources[?LogicalResourceId=='PrivateSubnet02'].PhysicalResourceId" --output text)
      ```

   1. 이전 단계에서 검색된 서브넷의 가용 영역으로 변수를 정의합니다.

      ```
      az_1=$(aws ec2 describe-subnets --subnet-ids $subnet_id_1 --query 'Subnets[*].AvailabilityZone' --output text)
      az_2=$(aws ec2 describe-subnets --subnet-ids $subnet_id_2 --query 'Subnets[*].AvailabilityZone' --output text)
      ```

1. 클러스터 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.html#iam-term-principal)을 생성하려면 역할을 생성하는 IAM 보안 주체에 `iam:CreateRole` 작업(권한)을 할당해야 합니다.

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

   1. 역할에 [AmazonEKSClusterPolicy](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonEKSClusterPolicy.html#AmazonEKSClusterPolicy-json)라는 Amazon EKS 관리 정책을 연결합니다. IAM 정책을 [IAM 보안 주체](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html#iam-term-principal)에 연결하려면 정책을 연결하는 보안 주체에 `iam:AttachUserPolicy` 또는 `iam:AttachRolePolicy`의 IAM 작업(권한) 중 하나를 할당해야 합니다.

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

1. Amazon EKS 클러스터를 생성하고 이와 통신하도록 디바이스를 구성합니다.

   1. 클러스터를 생성합니다.

      ```
      aws eks create-cluster --name my-custom-networking-cluster \
         --role-arn arn:aws:iam::$account_id:role/myCustomNetworkingAmazonEKSClusterRole \
         --resources-vpc-config subnetIds="$subnet_id_1","$subnet_id_2"
      ```
**참고**  
요청의 가용 영역 중 하나에 Amazon EKS 클러스터를 생성하는 데 충분한 용량이 없다는 오류가 표시될 수 있습니다. 이 경우 오류 출력에는 새 클러스터를 지원할 수 있는 가용 영역이 포함됩니다. 사용자 계정의 지원 가용 영역에 있는 2개 이상의 서브넷을 사용하여 클러스터를 다시 생성합니다. 자세한 내용은 [용량 부족](troubleshooting.md#ice) 섹션을 참조하세요.

   1. 클러스터를 생성하는 데 몇 분 정도 걸립니다. 클러스터의 배포 상태를 확인하려면 다음 명령을 실행합니다.

      ```
      aws eks describe-cluster --name my-custom-networking-cluster --query cluster.status
      ```

      명령의 출력이 `"ACTIVE"`가 될 때까지 다음 단계를 계속하지 마세요.

   1. 클러스터와 통신하도록 `kubectl`을 구성합니다.

      ```
      aws eks update-kubeconfig --name my-custom-networking-cluster
      ```

## 2단계: VPC 구성
<a name="custom-networking-configure-vpc"></a>

이 자습서를 시작하려면 [1단계: 테스트 VPC 및 클러스터 생성](#custom-networking-create-cluster)에서 생성된 VPC가 있어야 합니다. 프로덕션 클러스터의 경우 모든 예제 값을 사용자 값으로 바꿔 사용자 VPC 맞게 단계를 조정합니다.

1. 현재 설치된 Kubernetes용 Amazon VPC CNI 플러그인이 최신 버전인지 확인합니다. Amazon EKS 추가 기능 유형의 최신 버전을 확인하고 사용 중인 버전을 이 버전으로 업데이트하려면 [Amazon EKS 추가 기능 업데이트](updating-an-add-on.md) 부분을 참조하세요. 자체 관리형 추가 기능 유형의 최신 버전을 확인하고 사용 중인 버전을 이 버전으로 업데이트하려면 [Amazon VPC CNI를 통해 포드에 IP 할당](managing-vpc-cni.md) 부분을 참조하세요.

1. 클러스터 VPC ID를 검색하여 이후 단계에서 사용할 수 있도록 변수에 저장합니다.

   ```
   vpc_id=$(aws eks describe-cluster --name my-custom-networking-cluster --query "cluster.resourcesVpcConfig.vpcId" --output text)
   ```

1. 추가 CIDR(Classless Inter-Domain Routing) 블록을 클러스터의 VPC 연결합니다. CIDR 블록은 기존에 연결된 모든 CIDR 블록과 겹칠 수 없습니다.

   1. VPC에 연결된 현재 CIDR 블록을 봅니다.

      ```
      aws ec2 describe-vpcs --vpc-ids $vpc_id \
          --query 'Vpcs[*].CidrBlockAssociationSet[*].{CIDRBlock: CidrBlock, State: CidrBlockState.State}' --out table
      ```

      예제 출력은 다음과 같습니다.

      ```
      ----------------------------------
      |          DescribeVpcs          |
      +-----------------+--------------+
      |    CIDRBlock    |    State     |
      +-----------------+--------------+
      |  192.168.0.0/24 |  associated  |
      +-----------------+--------------+
      ```

   1. 추가 CIDR 블록을 VPC에 연결합니다. 다음 명령에서 CIDR 블록 값을 바꿉니다. 자세한 내용을 알아보려면 Amazon VPC 사용 설명서의 [추가 IPv4 CIDR 블록을 VPC와 연결](https://docs.aws.amazon.com/vpc/latest/userguide/modify-vpcs.html#add-ipv4-cidr)을 참조하세요.

      ```
      aws ec2 associate-vpc-cidr-block --vpc-id $vpc_id --cidr-block 192.168.1.0/24
      ```

   1. 새 블록이 연결되어 있는지 확인합니다.

      ```
      aws ec2 describe-vpcs --vpc-ids $vpc_id --query 'Vpcs[*].CidrBlockAssociationSet[*].{CIDRBlock: CidrBlock, State: CidrBlockState.State}' --out table
      ```

      예제 출력은 다음과 같습니다.

      ```
      ----------------------------------
      |          DescribeVpcs          |
      +-----------------+--------------+
      |    CIDRBlock    |    State     |
      +-----------------+--------------+
      |  192.168.0.0/24 |  associated  |
      |  192.168.1.0/24 |  associated  |
      +-----------------+--------------+
      ```

   새 CIDR 블록의 `State`가 `associated`가 될 때까지 다음 단계를 진행하지 마세요.

1. 기존 서브넷이 있는 각 가용 영역에서 사용하려는 만큼 서브넷을 생성합니다. 이전 단계에서 VPC와 연결한 CIDR 블록 내에 있는 CIDR 블록을 지정합니다.

   1. 새 서브넷을 생성합니다. 다음 명령에서 CIDR 블록 값을 바꿉니다. 서브넷은 기존 서브넷이 있는 것과 다른 VPC CIDR 블록에서 생성되어야 하지만 기존 서브넷과 동일한 가용 영역에서 생성되어야 합니다. 이 예제에서는 하나의 서브넷이 현재 프라이빗 서브넷이 존재하는 각 가용 영역의 새 CIDR 블록에서 생성됩니다. 생성된 서브넷의 ID는 이후 단계에서 사용할 수 있도록 변수에 저장됩니다. `Name` 값은 이전 단계에서 Amazon EKS VPC 템플릿을 사용하여 생성된 서브넷에 할당된 값과 일치합니다. 이름은 필요하지 않습니다. 다른 이름을 사용할 수 있습니다.

      ```
      new_subnet_id_1=$(aws ec2 create-subnet --vpc-id $vpc_id --availability-zone $az_1 --cidr-block 192.168.1.0/27 \
          --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=my-eks-custom-networking-vpc-PrivateSubnet01},{Key=kubernetes.io/role/internal-elb,Value=1}]' \
          --query Subnet.SubnetId --output text)
      new_subnet_id_2=$(aws ec2 create-subnet --vpc-id $vpc_id --availability-zone $az_2 --cidr-block 192.168.1.32/27 \
          --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=my-eks-custom-networking-vpc-PrivateSubnet02},{Key=kubernetes.io/role/internal-elb,Value=1}]' \
          --query Subnet.SubnetId --output text)
      ```
**중요**  
기본적으로 새로운 서브넷은 VPC의 [기본 라우팅 테이블](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Route_Tables.html#RouteTables)과 암시적으로 연결됩니다. 이 라우팅 테이블을 사용하면 VPC 배포된 모든 리소스 간에 통신할 수 있습니다. 그러나 VPC와 연결된 CIDR 블록 외부에 있는 IP 주소를 보유한 리소스와는 통신할 수 없습니다. 자체 라우팅 테이블을 서브넷에 연결하여 이 동작을 변경할 수 있습니다. 자세한 내용을 알아보려면 Amazon VPC 사용 설명서의 [서브넷 라우팅 테이블](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Route_Tables.html#subnet-route-tables)을 참조하세요.

   1. VPC에서 현재 서브넷을 확인합니다.

      ```
      aws ec2 describe-subnets --filters "Name=vpc-id,Values=$vpc_id" \
          --query 'Subnets[*].{SubnetId: SubnetId,AvailabilityZone: AvailabilityZone,CidrBlock: CidrBlock}' \
          --output table
      ```

      예제 출력은 다음과 같습니다.

      ```
      ----------------------------------------------------------------------
      |                           DescribeSubnets                          |
      +------------------+--------------------+----------------------------+
      | AvailabilityZone |     CidrBlock      |         SubnetId           |
      +------------------+--------------------+----------------------------+
      |  us-west-2d      |  192.168.0.0/27    |     subnet-example1        |
      |  us-west-2a      |  192.168.0.32/27   |     subnet-example2        |
      |  us-west-2a      |  192.168.0.64/27   |     subnet-example3        |
      |  us-west-2d      |  192.168.0.96/27   |     subnet-example4        |
      |  us-west-2a      |  192.168.1.0/27    |     subnet-example5        |
      |  us-west-2d      |  192.168.1.32/27   |     subnet-example6        |
      +------------------+--------------------+----------------------------+
      ```

      생성한 `192.168.1.0` CIDR 블록의 서브넷이 `192.168.0.0` CIDR 블록의 서브넷과 동일한 가용 영역에 있는지 확인할 수 있습니다.

## 3단계: Kubernetes 리소스 구성
<a name="custom-networking-configure-kubernetes"></a>

1. `AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG` DaemonSet에서 `true` 환경 변수를 `aws-node`로 설정합니다.

   ```
   kubectl set env daemonset aws-node -n kube-system AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=true
   ```

1. [클러스터 보안 그룹](sec-group-reqs.md)의 ID를 검색하여 이후 단계에서 사용할 수 있도록 변수에 저장합니다. Amazon EKS는 클러스터를 생성하는 경우 이 보안 그룹을 자동으로 생성합니다.

   ```
   cluster_security_group_id=$(aws eks describe-cluster --name my-custom-networking-cluster --query cluster.resourcesVpcConfig.clusterSecurityGroupId --output text)
   ```

1.  포드를 배포하려는 각 서브넷에 대해 `ENIConfig` 사용자 지정 리소스를 만듭니다.

   1. 각 네트워크 인터페이스 구성에 대해 고유한 파일을 생성합니다.

      다음 명령은 이전 단계에서 생성된 두 서브넷용 `ENIConfig` 파일을 별도로 생성합니다. `name`의 값은 고유해야 합니다. 이름은 서브넷이 있는 가용 영역과 동일합니다. 클러스터 보안 그룹은 `ENIConfig`에 할당됩니다.

      ```
      cat >$az_1.yaml <<EOF
      apiVersion: crd.k8s.amazonaws.com/v1alpha1
      kind: ENIConfig
      metadata:
        name: $az_1
      spec:
        securityGroups:
          - $cluster_security_group_id
        subnet: $new_subnet_id_1
      EOF
      ```

      ```
      cat >$az_2.yaml <<EOF
      apiVersion: crd.k8s.amazonaws.com/v1alpha1
      kind: ENIConfig
      metadata:
        name: $az_2
      spec:
        securityGroups:
          - $cluster_security_group_id
        subnet: $new_subnet_id_2
      EOF
      ```

      프로덕션 클러스터의 경우 이전 명령을 다음과 같이 변경할 수 있습니다.
      + \$1cluster\$1security\$1group\$1id를 각 `ENIConfig`에 사용할 기존 [보안 그룹](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html)의 ID로 바꿉니다.
      + 가능하면 `ENIConfig`를 사용할 가용 영역과 동일하게 `ENIConfigs`의 이름을 지정하는 것이 좋습니다. 여러 이유로 가용 영역의 이름과 다른 `ENIConfigs`의 이름을 사용해야 할 수 있습니다. 예를 들어, 동일한 가용 영역에 두 개 이상의 서브넷이 있고 사용자 지정 네트워킹에서 둘 다 사용하려는 경우 동일한 가용 영역에 대한 여러 `ENIConfigs`가 필요합니다. 각 `ENIConfig`는 고유한 이름이 필요하므로 가용 영역 이름을 사용하여 `ENIConfigs`에 두 개 이상의 이름을 지정할 수 없습니다.

        `ENIConfig` 이름이 모두 가용 영역 이름과 동일하지 않은 경우 \$1az\$11 및 \$1az\$12를 이전 명령의 사용자 자신의 이름으로 바꾸고 이 자습서의 뒷부분에서 [ENIConfig를 사용하여 노드에 주석을 답니다](#custom-networking-annotate-eniconfig).
**참고**  
프로덕션 클러스터에서 사용할 유효한 보안 그룹을 지정하지 않고 다음을 사용하는 경우
      + Kubernetes용 Amazon VPC CNI 플러그인의 버전 `1.8.0` 이상을 사용하는 경우 노드의 기본 Elastic 네트워크 인터페이스와 연결된 보안 그룹이 사용됩니다.
      + Kubernetes용 Amazon VPC CNI 플러그인을 `1.8.0`보다 이전 버전으로 설정하면 VPC의 기본 보안 그룹이 보조 네트워크 인터페이스에 할당됩니다.
**중요**  
 `AWS_VPC_K8S_CNI_EXTERNALSNAT=false`는 Kubernetes용 Amazon VPC CNI 플러그인 구성의 기본 설정입니다. 기본 설정을 사용하는 경우 VPC와 연결된 CIDR 블록 중 하나에 있지 않은 IP 주소로 향하는 트래픽은 노드의 기본 네트워크 인터페이스의 보안 그룹 및 서브넷을 사용합니다. 보조 네트워크 인터페이스를 생성하는 데 사용된 `ENIConfigs`에서 정의된 서브넷 및 보안 그룹은 이 트래픽에는 사용되지 않습니다. 이 설정에 대한 자세한 내용을 알아보려면 [포드에 대한 아웃바운드 인터넷 액세스 활성화](external-snat.md) 섹션을 참조하세요.
포드에 보안 그룹도 사용하는 경우 `SecurityGroupPolicy`에 지정된 보안 그룹이 `ENIConfigs`에 지정된 보안 그룹 대신 사용됩니다. 자세한 내용은 [개별 포드에 보안 그룹 할당](security-groups-for-pods.md) 섹션을 참조하세요.

   1. 다음 명령을 사용하여 생성된 각 사용자 지정 리소스 파일을 클러스터에 적용합니다.

      ```
      kubectl apply -f $az_1.yaml
      kubectl apply -f $az_2.yaml
      ```

1. `ENIConfigs`가 생성되었는지 확인합니다.

   ```
   kubectl get ENIConfigs
   ```

   예제 출력은 다음과 같습니다.

   ```
   NAME         AGE
   us-west-2a   117s
   us-west-2d   105s
   ```

1. 프로덕션 클러스터에서 사용자 지정 네트워킹을 활성화하고 사용 중인 가용 영역 이외의 것으로 `ENIConfigs`의 이름을 지정한 경우 [다음 단계](#custom-networking-deploy-nodes)로 이동하여 Amazon EC2 노드를 배포합니다.

   Kubernetes가 클러스터에 생성된 모든 새로운 Amazon EC2 노드에 가용 영역의 `ENIConfig`를 자동으로 적용할 수 있습니다.

   1. 이 자습서의 테스트 클러스터의 경우 [다음 단계](#custom-networking-automatically-apply-eniconfig)로 이동합니다.

      프로덕션 클러스터의 경우 `k8s.amazonaws.com/eniConfig` 환경 변수에 대한 키 ` [ENI\$1CONFIG\$1ANNOTATION\$1DEF](https://github.com/aws/amazon-vpc-cni-k8s#eni_config_annotation_def) `가 포함된 주석이 `aws-node` DaemonSet의 컨테이너 사양에 있는지 확인합니다.

      ```
      kubectl describe daemonset aws-node -n kube-system | grep ENI_CONFIG_ANNOTATION_DEF
      ```

      출력이 반환되는 경우 주석이 존재합니다. 출력이 반환되지 않으면 변수가 설정되지 않은 것입니다. 프로덕션 클러스터의 경우 이 설정이나 다음 단계의 설정 중 하나를 사용할 수 있습니다. 이 설정을 사용하는 경우 다음 단계의 설정을 재정의합니다. 이 튜토리얼에서는 다음 단계의 설정이 사용됩니다.

   1.  `aws-node` DaemonSet을 업데이트하여 클러스터에 생성된 모든 새로운 Amazon EC2 노드에 가용 영역의 `ENIConfig`를 자동으로 적용합니다.

      ```
      kubectl set env daemonset aws-node -n kube-system ENI_CONFIG_LABEL_DEF=topology.kubernetes.io/zone
      ```

## 4단계: Amazon EC2 노드 배포
<a name="custom-networking-deploy-nodes"></a>

1. 노드 IAM 역할을 생성합니다.

   1. 다음 명령을 실행하여 IAM 신뢰 정책 JSON 파일을 생성합니다.

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

   1. IAM 역할을 생성하고 이후 단계에서 사용할 수 있도록 반환된 Amazon 리소스 이름(ARN)을 변수에 저장합니다.

      ```
      node_role_arn=$(aws iam create-role --role-name myCustomNetworkingNodeRole --assume-role-policy-document file://"node-role-trust-relationship.json" \
          --query Role.Arn --output text)
      ```

   1. 필요한 3개의 IAM 관리형 정책을 IAM 역할에 연결합니다.

      ```
      aws iam attach-role-policy \
        --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy \
        --role-name myCustomNetworkingNodeRole
      aws iam attach-role-policy \
        --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly \
        --role-name myCustomNetworkingNodeRole
      aws iam attach-role-policy \
          --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy \
          --role-name myCustomNetworkingNodeRole
      ```
**중요**  
이 튜토리얼에서는 단순화를 위해 노드 IAM 역할에 [AmazonEKS\$1CNI\$1Policy](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonEKS_CNI_Policy.html) 정책이 연결되어 있습니다. 그러나 프로덕션 클러스터에서는 정책을 Kubernetes용 Amazon VPC CNI 플러그인에서만 사용되는 별도의 IAM 역할에 연결하는 것이 좋습니다. 자세한 내용은 [IRSA를 사용하도록 Amazon VPC CNI 플러그인 구성](cni-iam-role.md) 섹션을 참조하세요.

1. 다음 노드 그룹 유형 중 하나를 생성합니다. 배포할 인스턴스 유형을 확인하려면 [최적의 Amazon EC2 노드 인스턴스 유형 선택](choosing-instance-type.md) 섹션을 참조하세요. 이 자습서에서는 **관리형**, **시작 템플릿을 사용하지 않거나 AMI ID가 지정되지 않은 시작 템플릿을 사용하는 경우,(Without a launch template or with a launch template without an AMI ID specified)**의 옵션을 완료합니다. 프로덕션 워크로드에 노드 그룹을 사용하려는 경우 노드 그룹을 배포하기 전에 [관리형 노드 그룹](create-managed-node-group.md) 및 [자체 관리형 노드 그룹](worker.md) 옵션을 모두 숙지하는 것이 좋습니다.
   +  **관리형** - 다음 옵션 중 하나를 사용하여 노드 그룹을 배포합니다.
     +  **시작 템플릿을 사용하지 않거나 AMI ID가 지정되지 않은 시작 템플릿을 사용하는 경우,(Without a launch template or with a launch template without an AMI ID specified)** - 다음 명령을 실행합니다. 이 자습서에서는 예제 값을 사용합니다. 프로덕션 노드 그룹의 경우 모든 예제 값을 사용자 자신의 것으로 바꿉니다. 노드 그룹 이름은 63자를 초과할 수 없습니다. 문자나 숫자로 시작하되, 나머지 문자의 경우 하이픈과 밑줄을 포함할 수 있습니다.

       ```
       aws eks create-nodegroup --cluster-name my-custom-networking-cluster --nodegroup-name my-nodegroup \
           --subnets $subnet_id_1 $subnet_id_2 --instance-types t3.medium --node-role $node_role_arn
       ```
     +  **AMI ID가 지정된 시작 템플릿을 사용하는 경우(With a launch template with a specified AMI ID)** 

       1. 노드에 대한 Amazon EKS 권장 최대 포드 수를 결정합니다. 의 지침에 따라 해당 주제의 3단계에 `--cni-custom-networking-enabled`를 추가합니다. 다음 단계에서 사용할 수 있도록 출력을 적어 둡니다.

       1. 시작 템플릿에서 Amazon EKS 최적화 AMI ID 또는 Amazon EKS 최적화 AMI에서 빌드한 사용자 지정 AMI를 지정한 다음 [시작 템플릿을 사용하여 노드 그룹 배포](launch-templates.md)를 지정하고 시작 템플릿에 다음 사용자 데이터를 입력합니다. 이 사용자 데이터는 인수를 `NodeConfig` 사양으로 전달합니다. NodeConfig에 대한 자세한 내용은 [NodeConfig API 참조](https://awslabs.github.io/amazon-eks-ami/nodeadm/doc/api/#nodeconfig)를 참조하세요. `20`을 이전 단계의 값(권장) 또는 고유한 값으로 바꿉니다.

          ```
          ---
          MIME-Version: 1.0
          Content-Type: multipart/mixed; boundary="BOUNDARY"
          --BOUNDARY
          Content-Type: application/node.eks.aws
          
          ---
          apiVersion: node.eks.aws/v1alpha1
          kind: NodeConfig
          spec:
            cluster:
              name: my-cluster
              ...
              kubelet:
                config:
                  maxPods: 20
          ```

          Amazon EKS 최적화 AMI에서 빌드되지 않은 사용자 지정 AMI를 생성한 경우 직접 구성을 사용자 지정하여 생성해야 합니다.
   +  **자체 관리형** 

     1. 노드에 대한 Amazon EKS 권장 최대 포드 수를 결정합니다. 의 지침을 따라 해당 주제의 3단계에 `--cni-custom-networking-enabled`를 추가하세요. 다음 단계에서 사용할 수 있도록 출력을 적어 둡니다.

     1. [자체 관리형 Amazon Linux 노드 생성](launch-workers.md)의 지침에 따라 노드 그룹을 배포합니다.
**참고**  
프로덕션 클러스터의 노드가 훨씬 더 많은 수의 포드를 지원하도록 하려는 경우 다시 에서 스크립트를 실행합니다. 또한 `--cni-prefix-delegation-enabled` 옵션을 명령에 추가합니다. 예를 들어 `m5.large` 인스턴스 유형에 대해 `110`이 반환됩니다. 이 기능을 사용 설정하는 방법에 대한 지침은 [접두사를 사용하여 Amazon EKS 노드에 추가 IP 주소 할당](cni-increase-ip-addresses.md) 부분을 참조하세요. 사용자 지정 네트워킹에서 이 기능을 사용할 수 있습니다.

1. 노드 그룹을 생성하는 데 몇 분 정도 걸립니다. 다음 명령을 사용하여 관리형 노드 그룹의 생성 상태를 확인할 수 있습니다.

   ```
   aws eks describe-nodegroup --cluster-name my-custom-networking-cluster --nodegroup-name my-nodegroup --query nodegroup.status --output text
   ```

   반환되는 출력이 `ACTIVE`가 될 때까지 다음 단계를 진행하지 마세요.

1.  튜토리얼에서는 이 단계를 건너뛸 수 있습니다.

   프로덕션 클러스터의 경우 사용 중인 가용 영역과 동일하게 `ENIConfigs`의 이름을 지정하지 않은 경우 노드에서 사용해야 하는 `ENIConfig` 이름으로 해당 노드에 주석을 달아야 합니다. 각 가용 영역에 서브넷이 하나만 있고 가용 영역과 동일한 이름으로 `ENIConfigs`의 이름을 지정한 경우에는 이 단계가 필요하지 않습니다. 이는 [이전 단계](#custom-networking-automatically-apply-eniconfig)에서 활성화한 경우 Kubernetes용 Amazon VPC CNI 플러그인이 자동으로 올바른 `ENIConfig`를 노드에 연결하기 때문입니다.

   1. 클러스터의 노드 목록을 가져옵니다.

      ```
      kubectl get nodes
      ```

      예제 출력은 다음과 같습니다.

      ```
      NAME                                          STATUS   ROLES    AGE     VERSION
      ip-192-168-0-126.us-west-2.compute.internal   Ready    <none>   8m49s   v1.22.9-eks-810597c
      ip-192-168-0-92.us-west-2.compute.internal    Ready    <none>   8m34s   v1.22.9-eks-810597c
      ```

   1. 각 노드가 있는 가용 영역을 확인합니다. 이전 단계에서 반환된 각 노드에 대해 다음 명령을 실행합니다. 이때 이전 출력을 기반으로 IP 주소를 바꿉니다.

      ```
      aws ec2 describe-instances --filters Name=network-interface.private-dns-name,Values=ip-192-168-0-126.us-west-2.compute.internal \
      --query 'Reservations[].Instances[].{AvailabilityZone: Placement.AvailabilityZone, SubnetId: SubnetId}'
      ```

      예제 출력은 다음과 같습니다.

      ```
      [
          {
              "AvailabilityZone": "us-west-2d",
              "SubnetId": "subnet-Example5"
          }
      ]
      ```

   1. 각 노드에 서브넷 ID 및 가용 영역에 대해 생성한 `ENIConfig`로 주석을 답니다. 여러 노드에 동일한 `ENIConfig`로 주석을 달 수 있지만, 노드에는 하나의 `ENIConfig`로만 주석을 달 수 있습니다. 예제 값을 사용자의 값으로 바꿉니다.

      ```
      kubectl annotate node ip-192-168-0-126.us-west-2.compute.internal k8s.amazonaws.com/eniConfig=EniConfigName1
      kubectl annotate node ip-192-168-0-92.us-west-2.compute.internal k8s.amazonaws.com/eniConfig=EniConfigName2
      ```

1.  사용자 지정 네트워킹 기능 사용으로 전환하기 전에 프로덕션 클러스터에 실행 중인 포드가 있는 노드가 있는 경우 다음 태스크를 완료해야 합니다.

   1. 사용자 지정 네트워킹 기능을 사용하는 사용 가능한 노드가 있는지 확인합니다.

   1. 노드를 차단하고 드레이닝하여 포드를 정상적으로 종료합니다. 자세한 내용을 알아보려면 Kubernetes 문서의 [안전한 노드 드레이닝](https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/)을 참조하세요.

   1. 노드를 종료합니다. 노드가 기존 관리형 노드 그룹에 있는 경우 노드 그룹을 삭제할 수 있습니다. 다음 명령을 실행합니다.

      ```
      aws eks delete-nodegroup --cluster-name my-custom-networking-cluster --nodegroup-name my-nodegroup
      ```

   `k8s.amazonaws.com/eniConfig` 레이블에 등록된 새 노드만 사용자 지정 네트워킹 기능을 사용합니다.

1. 포드가 이전 단계에서 생성한 서브넷 중 하나에 연결된 CIDR 블록의 IP 주소를 할당하는지 확인합니다.

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

   예제 출력은 다음과 같습니다.

   ```
   NAMESPACE     NAME                       READY   STATUS    RESTARTS   AGE     IP              NODE                                          NOMINATED NODE   READINESS GATES
   kube-system   aws-node-2rkn4             1/1     Running   0          7m19s   192.168.0.92    ip-192-168-0-92.us-west-2.compute.internal    <none>           <none>
   kube-system   aws-node-k96wp             1/1     Running   0          7m15s   192.168.0.126   ip-192-168-0-126.us-west-2.compute.internal   <none>           <none>
   kube-system   coredns-657694c6f4-smcgr   1/1     Running   0          56m     192.168.1.23    ip-192-168-0-92.us-west-2.compute.internal    <none>           <none>
   kube-system   coredns-657694c6f4-stwv9   1/1     Running   0          56m     192.168.1.28    ip-192-168-0-92.us-west-2.compute.internal    <none>           <none>
   kube-system   kube-proxy-jgshq           1/1     Running   0          7m19s   192.168.0.92    ip-192-168-0-92.us-west-2.compute.internal    <none>           <none>
   kube-system   kube-proxy-wx9vk           1/1     Running   0          7m15s   192.168.0.126   ip-192-168-0-126.us-west-2.compute.internal   <none>           <none>
   ```

   Coredns 포드에 VPC 추가한 `192.168.1.0` CIDR 블록의 IP 주소가 할당되는지 볼 수 있습니다. 사용자 지정 네트워킹을 사용하지 않는 경우 원래 CIDR 블록만 VPC와 연결되기 때문에 `192.168.0.0` CIDR 블록의 주소가 할당되었을 것입니다.

   포드의 `spec`이 `hostNetwork=true`를 포함하는 경우 노드의 기본 IP 주소가 할당됩니다. 추가한 서브넷의 주소는 할당되지 않습니다. 기본적으로 이 값은 `false`로 설정됩니다. 이 값은 클러스터에서 실행되는 Kubernetes용 Amazon VPC CNI 플러그인(`aws-node`) 포드와 `kube-proxy`에 대해 `true`로 설정됩니다. 따라서 `kube-proxy` 및 플러그인의 `aws-node` 포드에 이전 출력의 192.168.1.x 주소가 할당되지 않습니다. 포드의 `hostNetwork` 설정에 대한 자세한 내용은 Kubernetes API Reference의 [PodSpec v1 core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#podspec-v1-core)를 참조하세요.

## 5단계: 튜토리얼 리소스 삭제
<a name="custom-network-delete-resources"></a>

튜토리얼을 완료하면 생성한 리소스를 삭제하는 것이 좋습니다. 그런 다음 단계를 조정하여 프로덕션 클러스터에 대해 사용자 지정 네트워킹을 사용 설정할 수 있습니다.

1. 생성한 노드 그룹이 테스트용일 경우 삭제하세요.

   ```
   aws eks delete-nodegroup --cluster-name my-custom-networking-cluster --nodegroup-name my-nodegroup
   ```

1. AWS CLI 출력에 클러스터가 삭제되었다고 표시된 이후에도 삭제 프로세스는 실제로 완료되지 않을 수 있습니다. 삭제 프로세스는 몇 분 정도 걸릴 수 있습니다. 다음 명령을 실행하여 완료되었는지 확인합니다.

   ```
   aws eks describe-nodegroup --cluster-name my-custom-networking-cluster --nodegroup-name my-nodegroup --query nodegroup.status --output text
   ```

   반환된 출력이 다음 출력과 비슷하게 될 때까지 진행하지 마세요.

   ```
   An error occurred (ResourceNotFoundException) when calling the DescribeNodegroup operation: No node group found for name: my-nodegroup.
   ```

1. 생성한 노드 그룹이 테스트용일 경우 노드 IAM 역할을 삭제하세요.

   1. 역할에서 정책을 분리합니다.

      ```
      aws iam detach-role-policy --role-name myCustomNetworkingNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
      aws iam detach-role-policy --role-name myCustomNetworkingNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
      aws iam detach-role-policy --role-name myCustomNetworkingNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
      ```

   1. 역할을 삭제합니다.

      ```
      aws iam delete-role --role-name myCustomNetworkingNodeRole
      ```

1. 클러스터를 삭제하세요.

   ```
   aws eks delete-cluster --name my-custom-networking-cluster
   ```

   다음 명령을 사용하여 클러스터가 삭제되었는지 확인합니다.

   ```
   aws eks describe-cluster --name my-custom-networking-cluster --query cluster.status --output text
   ```

   다음과 비슷한 출력이 반환되면 클러스터가 성공적으로 삭제됩니다.

   ```
   An error occurred (ResourceNotFoundException) when calling the DescribeCluster operation: No cluster found for name: my-custom-networking-cluster.
   ```

1. 클러스터 IAM 역할을 삭제합니다.

   1. 역할에서 정책을 분리합니다.

      ```
      aws iam detach-role-policy --role-name myCustomNetworkingAmazonEKSClusterRole --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
      ```

   1. 역할을 삭제합니다.

      ```
      aws iam delete-role --role-name myCustomNetworkingAmazonEKSClusterRole
      ```

1. 이전 단계에서 생성한 서브넷을 삭제합니다.

   ```
   aws ec2 delete-subnet --subnet-id $new_subnet_id_1
   aws ec2 delete-subnet --subnet-id $new_subnet_id_2
   ```

1. 생성한 VPC를 삭제합니다.

   ```
   aws cloudformation delete-stack --stack-name my-eks-custom-networking-vpc
   ```

# 접두사를 사용하여 Amazon EKS 노드에 추가 IP 주소 할당
<a name="cni-increase-ip-addresses"></a>

 **적용 대상**: Amazon EC2 인스턴스가 있는 Linux 및 Windows 노드

 **적용 대상:** 퍼블릭 및 프라이빗 서브넷

각 Amazon EC2 인스턴스는 최대 탄력적 네트워크 인터페이스 수와 각 네트워크 인터페이스에 할당할 수 있는 최대 IP 주소 수를 지원합니다. 각 노드에는 네트워크 인터페이스마다 IP 주소가 하나씩 필요합니다. 사용 가능한 다른 모든 IP 주소를 `Pods`에 할당할 수 있습니다. 각 `Pod`에는 자체 IP 주소가 필요합니다. 따라서 사용 가능한 컴퓨팅 및 메모리 리소스가 있지만 `Pods`에 할당할 IP 주소가 부족하여 추가 `Pods`를 수용할 수 없는 노드가 있을 수 있습니다.

노드에 개별 보조 IP 주소를 할당하는 대신 IP 접두사를 할당하여 노드가 `Pods`에 할당할 수 있는 IP 주소 수를 크게 늘릴 수 있습니다. 각 접두사에는 여러 IP 주소가 포함됩니다. IP 접두사 할당을 위해 클러스터를 구성하지 않는 경우 클러스터는 포드 연결에 필요한 네트워크 인터페이스와 IP 주소를 구성하기 위해 더 많은 Amazon EC2 애플리케이션 프로그래밍 인터페이스(API)를 직접적으로 직접 호출해야 합니다. 클러스터가 더 큰 규모로 성장함에 따라 이러한 API 직접 호출의 빈도가 증가하여 포드 및 인스턴스 시작 시간이 더 길어질 수 있습니다. 이로 인해 규모가 크고 까다로운 워크로드의 수요를 충족하기 위해 확장이 지연되고 확장 요구 사항을 충족하기 위해 추가 클러스터와 VPC를 프로비저닝해야 하므로 비용 및 관리 오버헤드가 추가됩니다. 자세한 내용은 GitHub의 [Kubernetes Scalability thresholds](https://github.com/kubernetes/community/blob/master/sig-scalability/configs-and-limits/thresholds.md)를 참조하세요.

## Kubernetes용 Amazon VPC CNI 플러그인 기능과의 호환성
<a name="cni-increase-ip-addresses-compatability"></a>

IP 접두사를 다음 기능과 함께 사용할 수 있습니다.
+ IPv4 소스 네트워크 주소 변환-자세한 내용은 [포드에 대한 아웃바운드 인터넷 액세스 활성화](external-snat.md) 섹션을 참조하세요.
+ 클러스터, 포드 및 서비스에 대한 IPv6 주소-자세한 내용은 [클러스터, 포드 및 서비스에 대한 IPv6 주소에 대해 알아보기](cni-ipv6.md) 섹션을 참조하세요.
+ Kubernetes 네트워크 정책을 사용하여 트래픽 제한-자세한 내용은 [Kubernetes 네트워크 정책을 통해 pod 트래픽 제한](cni-network-policy.md) 섹션을 참조하세요.

다음 목록에서는 적용되는 Amazon VPC CNI 플러그인 설정에 대한 정보를 제공합니다. 각 설정에 대한 자세한 내용은 GitHub의 [amazon-vpc-cni-k8s](https://github.com/aws/amazon-vpc-cni-k8s/blob/master/README.md)를 참조하세요.
+  `WARM_IP_TARGET` 
+  `MINIMUM_IP_TARGET` 
+  `WARM_PREFIX_TARGET` 

## 고려 사항
<a name="cni-increase-ip-addresses-considerations"></a>

이 기능을 사용할 때 다음 사항을 고려하세요.
+ 각 Amazon EC2 인스턴스 유형은 최대 포드 수를 지원합니다. 관리형 노드 그룹이 여러 인스턴스 유형으로 구성된 경우 클러스터의 인스턴스에 대한 최대 포드 수 가운데 최소 수가 클러스터의 모든 노드에 적용됩니다.
+ 기본적으로 노드에서 실행할 수 있는 최대 `Pods` 수는 110개이지만 이 수를 변경할 수 있습니다. 숫자를 변경하고 기존 관리형 노드 그룹이 있는 경우 노드 그룹의 다음 AMI 또는 시작 템플릿 업데이트로 인해 새 노드에 변경된 값이 나타납니다.
+ IP 주소 할당에서 IP 접두사 할당으로 전환할 때 기존 노드를 순차적으로 바꾸는 대신 새 노드 그룹을 생성하여 사용 가능한 IP 주소 수를 늘리는 것이 좋습니다. IP 주소와 접두사가 모두 할당된 노드에서 포드를 실행하면 광고된 IP 주소 용량에 불일치가 발생하여 노드의 향후 워크로드에 영향을 줄 수 있습니다. 전환을 수행하는 데 있어 권장되는 방법은 *Amazon EKS 모범 사례 가이드*의 [Prefix Delegation mode for Linux](https://docs.aws.amazon.com/eks/latest/best-practices/prefix-mode-linux.html)를 참조하세요.
+ 보안 그룹 범위는 노드 수준입니다. 자세한 내용은 [보안 그룹](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html)을 참조하세요.
+ 네트워크 인터페이스에 할당된 IP 접두사는 노드당 높은 포드 밀도를 지원하며, 시작 시간이 가장 빠릅니다.
+ IP 접두사 및 IP 주소는 표준 Amazon EC2 탄력적 네트워크 인터페이스와 연결됩니다. 특정 보안 그룹이 필요한 포드에는 브랜치 네트워크 인터페이스의 기본 IP 주소가 할당됩니다. IP 주소 또는 IP 접두사의 IP 주소를 얻는 포드와 동일한 노드에서 브랜치 네트워크 인터페이스를 얻는 포드와 혼합할 수 있습니다.
+ Linux 노드만 있는 클러스터의 경우
  + 네트워크 인터페이스에 접두사를 할당하도록 추가 기능을 구성한 후에는 클러스터의 모든 노드 그룹에 있는 모든 노드를 제거하지 않으면 `1.9.0`(또는 `1.10.1`) 이전 버전으로 Kubernetes용 Amazon VPC CNI 플러그인 추가 기능을 다운그레이드할 수 없습니다.
  + `POD_SECURITY_GROUP_ENFORCING_MODE`=`standard` 및 `AWS_VPC_K8S_CNI_EXTERNALSNAT`=`false`로 설정하고 포드에 보안 그룹도 사용하는 경우 포드가 VPC 외부의 엔드포인트와 통신할 때 포드에 할당한 보안 그룹이 아닌 노드의 보안 그룹이 사용됩니다.

    또한 [포드에 보안 그룹](security-groups-for-pods.md)을 사용하고 `POD_SECURITY_GROUP_ENFORCING_MODE`=`strict`인 경우 `Pods`가 VPC 외부의 엔드포인트와 통신할 때 `Pod’s` 보안 그룹이 사용됩니다.

# Amazon EKS 노드에 대해 사용 가능한 IP 주소 증가
<a name="cni-increase-ip-addresses-procedure"></a>

노드에 개별 보조 IP 주소를 할당하는 대신 IP 접두사를 할당하여 노드가 포드에 할당할 수 있는 IP 주소 수를 크게 늘릴 수 있습니다.

## 사전 조건
<a name="_prerequisites"></a>
+ 기존 클러스터가 있어야 합니다. 배포하려면 [Amazon EKS 클러스터 생성](create-cluster.md) 부분을 참조하세요.
+ Amazon EKS 노드가 있는 서브넷에는 충분한 연속 `/28`(`IPv4` 클러스터용) 또는 `/80`(`IPv6` 클러스터용) CIDR(Classless Inter-Domain Routing) 블록이 있어야 합니다. `IPv6` 클러스터에는 Linux 노드만 있을 수 있습니다. IP 주소가 서브넷 CIDR 전체에 분산되어 있는 경우 IP 접두사를 사용하지 못할 수 있습니다. 다음과 같이 하는 것이 좋습니다:
  + 서브넷 CIDR 예약을 사용하여 예약된 범위 내의 IP 주소가 아직 사용 중이더라도 릴리스 시 IP 주소가 다시 할당되지 않도록 합니다. 이렇게 하면 분할 없이 접두사를 할당할 수 있습니다.
  + IP 접두사가 할당된 워크로드 실행에 특별히 사용되는 새 서브넷을 사용합니다. IP 접두사를 할당할 때 Windows 및 Linux 워크로드를 모두 동일한 서브넷에서 실행할 수 있습니다.
+ 노드에 IP 접두사를 할당하려면 노드가 AWS Nitro를 기반으로 해야 합니다. NITO 기반이 아닌 인스턴스는 계속해서 개별 보조 IP 주소를 할당하지만 NITO 기반 인스턴스보다 포드에 할당할 IP 주소 수가 상당히 적습니다.
+  **Linux 노드만 있는 클러스터의 경우** – 클러스터가 `IPv4` 패밀리용으로 구성된 경우 버전 `1.9.0` 이상의 Kubernetes용 Amazon VPC CNI 플러그인 추가 기능이 설치되어 있어야 합니다. 현재 설치된 버전은 다음과 같은 명령으로 확인할 수 있습니다.

  ```
  kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2
  ```

  클러스터가 `IPv6` 패밀리용으로 구성된 경우 버전 `1.10.1`의 추가 기능이 설치되어 있어야 합니다. 플러그인 버전이 필요한 버전보다 이전인 경우 업데이트해야 합니다. 자세한 내용은 [Amazon VPC CNI를 사용하여 포드에 IP 할당](managing-vpc-cni.md)의 업데이트 섹션을 참조하세요.
+  **Windows 노드만 있는 클러스터의 경우** 
  + 클러스터에 대해 Windows 지원이 활성화되어 있어야 합니다. 자세한 내용은 [EKS 클러스터에 Windows 노드 배포](windows-support.md) 섹션을 참조하세요.

## 노드에 IP 주소 접두사 할당
<a name="cni-increase-ip-procedure"></a>

노드에 IP 주소 접두사를 할당하도록 클러스터를 구성합니다. 해당 노드의 운영 체제와 일치하는 절차를 완료합니다.

### Linux
<a name="_linux"></a>

1. 파라미터를 활성화하여 Amazon VPC CNI DaemonSet의 네트워크 인터페이스에 접두사를 할당합니다. 클러스터를 배포하는 경우 Kubernetes용 Amazon VPC CNI 플러그인 버전 `1.10.1` 이상의 추가 기능이 함께 배포됩니다. `IPv6` 패밀리를 사용하여 클러스터를 생성한 경우 이 설정은 기본적으로 `true`로 설정되었습니다. `IPv4` 패밀리를 사용하여 클러스터를 생성한 경우 이 설정은 기본적으로 `false`로 설정되었습니다.

   ```
   kubectl set env daemonset aws-node -n kube-system ENABLE_PREFIX_DELEGATION=true
   ```
**중요**  
서브넷에 사용 가능한 IP 주소가 있더라도 서브넷이 인접한 `/28` 블록을 사용할 수 없는 경우 Kubernetes용 Amazon VPC CNI 플러그인 로그에 다음 오류가 표시됩니다.  

   ```
   InsufficientCidrBlocks: The specified subnet does not have enough free cidr blocks to satisfy the request
   ```
이는 서브넷에 분산된 기존 보조 IP 주소의 조각화로 인해 발생할 수 있습니다. 이 오류를 해결하려면 새 서브넷을 생성하고 거기서 포드를 시작하거나 Amazon EC2 서브넷 CIDR 예약을 사용하여 접두사 할당과 함께 사용할 서브넷 내에 공간을 예약합니다. 자세한 내용은 Amazon VPC 사용 설명서의 [서브넷 CIDR 예약](https://docs.aws.amazon.com/vpc/latest/userguide/subnet-cidr-reservation.html)을 참조하세요.

1. 시작 템플릿이 없는 관리형 노드 그룹을 배포하거나 AMI ID를 지정하지 않은 시작 템플릿을 사용하여 배포할 계획이고, 필수 구성 요소에 나열된 버전보다 늦거나 같은 버전의 Kubernetes용 Amazon VPC CNI 플러그인을 사용하는 경우 다음 단계로 건너뛰세요. 관리형 노드 그룹은 자동으로 최대 포드 수를 계산합니다.

   AMI ID를 지정한 시작 템플릿을 사용하여 자체 관리형 노드 그룹 또는 관리형 노드 그룹을 배포하는 경우 Amazon EKS 권장 노드의 최대 포드 수를 결정해야 합니다. `--cni-prefix-delegation-enabled`를 3단계에 추가하여 의 지침을 따릅니다. 이후 단계에서 사용하기 위해 출력을 적어 둡니다.
**중요**  
관리형 노드 그룹은 `maxPods`의 값에 최대 수를 적용합니다. vCPU가 30개 미만인 인스턴스의 경우 최대 수는 110이고 다른 모든 인스턴스의 경우 최대 수는 250입니다. 이 최대 수는 접두사 위임의 활성화 여부에 관계없이 적용됩니다.

1. `IPv6`용으로 구성된 클러스터를 사용하는 경우 다음 단계로 건너뜁니다.

   다음 옵션 중 하나에서 파라미터를 지정합니다. 자신에게 적합한 옵션과 제공할 값을 확인하려면 GitHub의 [WARM\$1PREFIX\$1TARGET, WARM\$1IP\$1TARGET, and MINIMUM\$1IP\$1TARGET](https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/prefix-and-ip-target.md)을 참조하세요.

   예제 값을 0보다 큰 값으로 바꿀 수 있습니다.
   +  `WARM_PREFIX_TARGET` 

     ```
     kubectl set env ds aws-node -n kube-system WARM_PREFIX_TARGET=1
     ```
   +  `WARM_IP_TARGET` 또는 `MINIMUM_IP_TARGET` - 둘 중 하나의 값이 설정되면 `WARM_PREFIX_TARGET`에 설정된 모든 값을 재정의합니다.

     ```
     kubectl set env ds aws-node -n kube-system WARM_IP_TARGET=5
     ```

     ```
     kubectl set env ds aws-node -n kube-system MINIMUM_IP_TARGET=2
     ```

1. 하나 이상의 Amazon EC2 Nitro Amazon Linux 2023 인스턴스 유형으로 다음 유형의 노드 그룹 중 하나를 생성합니다. Nitro 인스턴스 유형의 목록은 Amazon EC2 사용 설명서에서 [Nitro 시스템에 구축된 인스턴스](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html#ec2-nitro-instances) 섹션을 참조하세요. 이 기능은 Windows에서 지원되지 않습니다. *110*을 포함하는 옵션의 경우, 3단계의 값(권장) 또는 고유한 값으로 바꿉니다.
   +  **자체 관리형**-[자체 관리형 Amazon Linux 노드 생성](launch-workers.md)의 지침에 따라 노드 그룹을 배포합니다. CloudFormation 스택을 생성하기 전에 템플릿 파일을 열고 `NodeLaunchTemplate`의 `UserData`를 다음과 같이 조정합니다.

     ```
     ...
                 apiVersion: node.eks.aws/v1alpha1
                 kind: NodeConfig
                 spec:
                   cluster:
                     name: ${ClusterName}
                     apiServerEndpoint: ${ApiServerEndpoint}
                     certificateAuthority: ${CertificateAuthorityData}
                     cidr: ${ServiceCidr}
                   kubelet:
                     config:
                       maxPods: 110
     ...
     ```

     `eksctl`을 사용하여 노드 그룹을 생성하려면 다음 명령을 사용합니다.

     ```
     eksctl create nodegroup --cluster my-cluster --managed=false --max-pods-per-node 110
     ```
   +  **관리형** - 다음 옵션 중 하나를 사용하여 노드 그룹을 배포합니다.
     +  **시작 템플릿이 없거나 AMI ID가 지정되지 않은 시작 템플릿**-[클러스터에 대한 관리형 노드 그룹 생성](create-managed-node-group.md)의 절차를 완료합니다. 관리형 노드 그룹은 자동으로 Amazon EKS 권장 최대 `max-pods` 값을 계산합니다.
     +  **AMI ID가 지정된 시작 템플릿을 사용하는 경우(With a launch template with a specified AMI ID)** - 시작 템플릿에서 Amazon EKS 최적화 AMI ID 또는 Amazon EKS 최적화 AMI에서 빌드한 사용자 지정 AMI를 지정한 다음 [시작 템플릿을 사용하여 노드 그룹 배포](launch-templates.md)를 지정하고 시작 템플릿에 다음 사용자 데이터를 입력합니다. 이 사용자 데이터는 노드의 `nodeadm` 도구에서 읽을 `NodeConfig` 객체를 전달합니다. `nodeadm`에 대한 자세한 내용은 [nodeadm 설명서](https://awslabs.github.io/amazon-eks-ami/nodeadm)를 참조하세요.

       ```
       MIME-Version: 1.0
       Content-Type: multipart/mixed; boundary="//"
       
       --//
       Content-Type: application/node.eks.aws
       
       ---
       apiVersion: node.eks.aws/v1alpha1
       kind: NodeConfig
       spec:
        cluster:
          apiServerEndpoint: [.replaceable]`my-cluster`
          certificateAuthority: [.replaceable]`LS0t...`
          cidr: [.replaceable]`10.100.0.0/16`
          name: [.replaceable]`my-cluster
        kubelet:
          config:
            maxPods: [.replaceable]`110`
       --//--
       ```

       `eksctl`을 사용하여 노드 그룹을 생성하려면 다음 명령을 사용합니다.

       ```
       eksctl create nodegroup --cluster my-cluster --max-pods-per-node 110
       ```

       Amazon EKS 최적화 AMI에서 빌드되지 않은 사용자 지정 AMI를 생성한 경우 직접 구성을 사용자 지정하여 생성해야 합니다.
**참고**  
또한 인스턴스의 서브넷과 다른 서브넷의 포드에 IP 주소를 할당하려면 이 단계에서 기능을 활성화해야 합니다. 자세한 내용은 [사용자 지정 네트워킹을 통해 대체 서브넷에 포드 배포](cni-custom-network.md) 섹션을 참조하세요.

### Windows
<a name="_windows"></a>

1. IP 접두사의 할당을 활성화합니다.

   1. 편집을 위해 `amazon-vpc-cni` `ConfigMap`을 엽니다.

      ```
      kubectl edit configmap -n kube-system amazon-vpc-cni -o yaml
      ```

   1. 다음 줄을 `data` 섹션에 추가합니다.

      ```
        enable-windows-prefix-delegation: "true"
      ```

   1. 파일을 저장하고 편집기를 닫습니다.

   1. 이 줄이 `ConfigMap`에 추가되었는지 확인합니다.

      ```
      kubectl get configmap -n kube-system amazon-vpc-cni -o "jsonpath={.data.enable-windows-prefix-delegation}"
      ```

      반환된 출력이 `true`가 아닌 경우 오류가 있을 수 있습니다. 단계를 다시 완료해 봅니다.
**중요**  
서브넷에 사용 가능한 IP 주소가 있더라도 서브넷이 인접한 `/28` 블록을 사용할 수 없는 경우 Kubernetes용 Amazon VPC CNI 플러그인 로그에 다음 오류가 표시됩니다.  

      ```
      InsufficientCidrBlocks: The specified subnet does not have enough free cidr blocks to satisfy the request
      ```
이는 서브넷에 분산된 기존 보조 IP 주소의 조각화로 인해 발생할 수 있습니다. 이 오류를 해결하려면 새 서브넷을 생성하고 거기서 포드를 시작하거나 Amazon EC2 서브넷 CIDR 예약을 사용하여 접두사 할당과 함께 사용할 서브넷 내에 공간을 예약합니다. 자세한 내용은 Amazon VPC 사용 설명서의 [서브넷 CIDR 예약](https://docs.aws.amazon.com/vpc/latest/userguide/subnet-cidr-reservation.html)을 참조하세요.

1. (선택 사항) 클러스터의 사전 규모 조정 및 동적 규모 조정 동작을 제어하기 위한 추가 구성을 지정합니다. 자세한 내용은 GitHub에서 [Windows의 접두사 위임 모드를 사용한 구성 옵션](https://github.com/aws/amazon-vpc-resource-controller-k8s/blob/master/docs/windows/prefix_delegation_config_options.md)을 참조하세요.

   1. 편집을 위해 `amazon-vpc-cni` `ConfigMap`을 엽니다.

      ```
      kubectl edit configmap -n kube-system amazon-vpc-cni -o yaml
      ```

   1. 예제 값을 0보다 큰 값으로 바꾸고 필요한 항목을 `ConfigMap`의 `data` 섹션에 추가하세요. `warm-ip-target` 또한 `minimum-ip-target`에 대한 값을 설정하면 해당 값이 `warm-prefix-target`에 대해 설정된 모든 값을 재정의합니다.

      ```
        warm-prefix-target: "1"
        warm-ip-target: "5"
        minimum-ip-target: "2"
      ```

   1. 파일을 저장하고 편집기를 닫습니다.

1. 하나 이상의 Amazon EC2 Nitro 인스턴스 유형으로 Windows 노드 그룹을 생성합니다. Nitro 인스턴스 유형의 목록은 Amazon EC2 사용 설명서에서 [Nitro 시스템에 구축된 인스턴스](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/instance-types.html#ec2-nitro-instances) 섹션을 참조하세요. 기본적으로 노드에 배포할 수 있는 최대 포드 수는 110개입니다. 이 수를 늘리거나 줄이려면 부트스트랩 구성의 사용자 데이터에 다음을 지정합니다. *max-pods-quantity*를 최대 포드 값으로 바꿉니다.

   ```
   -KubeletExtraArgs '--max-pods=max-pods-quantity'
   ```

   관리형 노드 그룹을 배포하는 경우 시작 템플릿에 이 구성을 추가해야 합니다. 자세한 내용은 [시작 템플릿을 사용한 관리형 노드 사용자 지정](launch-templates.md) 섹션을 참조하세요. Windows 부트스트랩 스크립트의 구성 파라미터에 대한 자세한 내용은 [부트스트랩 스크립트 구성 파라미터](eks-optimized-windows-ami.md#bootstrap-script-configuration-parameters) 섹션을 참조하세요.

## 최대 포드 및 사용 가능한 IP 주소 확인
<a name="cni-increase-ip-verify"></a>

1. 노드가 배포되면 클러스터의 노드를 확인합니다.

   ```
   kubectl get nodes
   ```

   예제 출력은 다음과 같습니다.

   ```
   NAME                                             STATUS     ROLES    AGE   VERSION
   ip-192-168-22-103.region-code.compute.internal   Ready      <none>   19m   v1.XX.X-eks-6b7464
   ip-192-168-97-94.region-code.compute.internal    Ready      <none>   19m   v1.XX.X-eks-6b7464
   ```

1. 노드 중 하나를 설명하여 노드에 대한 `max-pods` 값과 사용 가능한 IP 주소 수를 결정합니다. *192.168.30.193*을 이전 출력에서 반환된 노드 중 하나의 이름에 있는 `IPv4` 주소로 바꿉니다.

   ```
   kubectl describe node ip-192-168-30-193.region-code.compute.internal | grep 'pods\|PrivateIPv4Address'
   ```

   예제 출력은 다음과 같습니다.

   ```
   pods:                                  110
   vpc.amazonaws.com/PrivateIPv4Address:  144
   ```

   이전 출력에서 `110`은 *144*개의 IP 주소를 사용할 수 있더라도 Kubernetes가 노드에 배포할 최대 포드 수입니다.

# 개별 포드에 보안 그룹 할당
<a name="security-groups-for-pods"></a>

 **적용 대상**: Amazon EC2 인스턴스가 있는 Linux 노드

 **적용 대상**: 프라이빗 서브넷

포드용 보안 그룹은 Amazon EC2 보안 그룹을 Kubernetes 포드와 통합합니다. Amazon EC2 보안 그룹을 사용하여 여러 Amazon EC2 인스턴스 유형 및 Fargate 에서 실행 중인 노드에 배포하는 포드와의 인바운드 및 아웃바운드 네트워크 트래픽을 허용하는 규칙을 정의할 수 있습니다. 이 기능에 대한 자세한 설명은 [포드에 대한 보안 그룹 소개](https://aws.amazon.com/blogs/containers/introducing-security-groups-for-pods) 블로그 게시물을 참조하세요.

## Kubernetes용 Amazon VPC CNI 플러그인 기능과의 호환성
<a name="security-groups-for-pods-compatability"></a>

다음 기능과 함께 포드에 대한 보안 그룹을 사용할 수 있습니다.
+ IPv4 소스 네트워크 주소 변환-자세한 내용은 [포드에 대한 아웃바운드 인터넷 액세스 활성화](external-snat.md) 섹션을 참조하세요.
+ 클러스터, 포드 및 서비스에 대한 IPv6 주소-자세한 내용은 [클러스터, 포드 및 서비스에 대한 IPv6 주소에 대해 알아보기](cni-ipv6.md) 섹션을 참조하세요.
+ Kubernetes 네트워크 정책을 사용하여 트래픽 제한 - 자세한 내용은 [Kubernetes 네트워크 정책을 통해 pod 트래픽 제한](cni-network-policy.md) 섹션을 참조하세요.

## 고려 사항
<a name="sg-pods-considerations"></a>

포드의 보안 그룹을 배포하기 전에 다음 제한 사항 및 조건을 고려하세요.
+ 포드에 대한 보안 그룹은 Windows 노드 또는 EKS Auto Mode와 함께 사용할 수 없습니다.
+ 포드의 보안 그룹은 Amazon VPC CNI 플러그인 버전 1.16.0 이상을 사용하여 Amazon EC2 노드가 포함된 `IPv6` 패밀리에 대해 구성된 클러스터에서 사용할 수 있습니다. Amazon VPC CNI 플러그인 버전 1.7.7 이상을 사용하여 Fargate 노드만 포함하는 `IPv6` 패밀리에 대해 구성된 클러스터에서 포드의 보안 그룹을 사용할 수 있습니다. 자세한 내용은 [클러스터, 포드 및 서비스에 대한 IPv6 주소에 대해 알아보기](cni-ipv6.md) 섹션을 참조하세요.
+ 포드에 대한 보안 그룹은 대다수 [Nitro 기반](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html#ec2-nitro-instances) Amazon EC2 인스턴스 패밀리에서 지원하지만, 패밀리의 모든 세대에서 지원하지는 않습니다. 예를 들면 `m5`, `c5`, `r5`, `m6g`, `c6g` 및 `r6g` 인스턴스 패밀리와 세대는 지원됩니다. `t` 패밀리의 인스턴스 유형은 지원되지 않습니다. 지원되는 인스턴스 유형의 전체 목록은 GitHub의 [limits.go](https://github.com/aws/amazon-vpc-resource-controller-k8s/blob/v1.5.0/pkg/aws/vpc/limits.go) 파일을 참조하세요. 노드는 해당 파일에 `IsTrunkingCompatible: true`가 있는 나열된 인스턴스 유형 중 하나여야 합니다.
+ 사용자 지정 네트워킹 및 포드의 보안 그룹을 함께 사용하는 경우 `ENIConfig`에 지정된 보안 그룹 대신 포드의 보안 그룹에 지정된 보안 그룹이 사용됩니다.
+ 버전 `1.10.2` 이하의 Amazon VPC CNI 플러그인을 사용하고 포드 사양에 `terminationGracePeriodSeconds` 설정이 포함된 경우 설정 값은 0이 될 수 없습니다.
+ 버전 `1.10` 이하의 Amazon VPC CNI 플러그인이나 기본 설정인 `POD_SECURITY_GROUP_ENFORCING_MODE`=`strict`로 버전 `1.11`를 사용하는 경우 `externalTrafficPolicy`를 `Local`로 설정한 인스턴스 대상을 사용하는 유형 `NodePort` 및 `LoadBalancer`의 Kubernetes 서비스는 보안 그룹을 할당하는 포드에서 지원하지 않습니다. 인스턴스 대상에 로드 밸런서를 사용하는 데 대한 자세한 내용은 [Network Load Balancer를 사용하여 TCP 및 UDP 트래픽 라우팅](network-load-balancing.md) 섹션을 참조하세요.
+ 버전 `1.10` 이하의 Amazon VPC CNI 플러그인이나 기본 설정인 `POD_SECURITY_GROUP_ENFORCING_MODE`=`strict`로 버전 `1.11`를 사용하는 경우 소스 NAT는 보안 그룹이 할당된 에서 아웃바운드 트래픽에 대해 사용 중지되므로 아웃바운드 보안 그룹 규칙이 적용됩니다. 인터넷에 액세스하려면 보안 그룹이 할당된 포드를 NAT 게이트웨이 또는 인스턴스로 구성된 프라이빗 서브넷에 배포된 노드에서 실행해야 합니다. 퍼블릭 서브넷에 할당된 보안 그룹이 있는 포드는 인터넷에 액세스할 수 없습니다.

  `POD_SECURITY_GROUP_ENFORCING_MODE`=`standard`로 설정된 버전 `1.11` 이상의 플러그인을 사용하는 경우 VPC 외부로 향하는 포드 트래픽은 인스턴스의 기본 네트워크 인터페이스의 IP 주소로 변환됩니다. 이 트래픽의 경우 포드의 보안 그룹의 규칙이 아닌 기본 네트워크 인터페이스에 대한 보안 그룹의 규칙이 사용됩니다.
+ 연결된 보안 그룹이 있는 포드를 통해 Calico 네트워크 정책을 사용하려면 버전 `1.11.0` 이상의 Amazon VPC CNI 플러그인을 사용하고 `POD_SECURITY_GROUP_ENFORCING_MODE`=`standard`로 설정해야 합니다. 그렇지 않으면 연결된 보안 그룹이 있는 포드에서 주고받는 트래픽 흐름에는 Calico 네트워크 정책이 적용되지 않으며, Amazon EC2 보안 그룹으로만 적용이 제한됩니다. Amazon VPC CNI 버전을 업데이트하려면 [Amazon VPC CNI를 통해 포드에 IP 할당](managing-vpc-cni.md) 섹션을 참조하세요.
+ [NodeLocal DNSCache](https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/)를 사용하는 클러스터에서 보안 그룹을 사용하는 Amazon EC2 노드에서 실행되는 포드는 `POD_SECURITY_GROUP_ENFORCING_MODE`=`standard`로 설정된 버전 `1.11.0` 이상의 Amazon VPC CNI 플러그인에서만 지원됩니다. Amazon VPC CNI 플러그인 버전을 업데이트하려면 [Amazon VPC CNI를 통해 포드에 IP 할당](managing-vpc-cni.md) 섹션을 참조하세요.
+ 포드의 보안 그룹은 변동이 많은 포드의 경우 포드 시작 지연 시간 증가로 이어질 수 있습니다. 이는 리소스 컨트롤러의 속도 제한 때문입니다.
+ EC2 보안 그룹 범위는 포드 수준입니다. 자세한 내용은 [보안 그룹](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html)을 참조하세요.

  `POD_SECURITY_GROUP_ENFORCING_MODE=standard` 및 `AWS_VPC_K8S_CNI_EXTERNALSNAT=false`를 설정하는 경우 VPC 외부의 엔드포인트로 향하는 트래픽은 포드의 보안 그룹이 아닌 노드의 보안 그룹을 사용합니다.

# Amazon EKS 포드의 보안 그룹에 대해 Kubernetes용 Amazon VPC CNI 플러그인 구성
<a name="security-groups-pods-deployment"></a>

Amazon EC2 인스턴스에서 포드를 사용하는 경우 보안 그룹에 대한 Kubernetes용 Amazon VPC CNI 플러그인을 구성해야 합니다.

Fargate 포드만 사용하고 클러스터에 Amazon EC2 노드가 없는 경우 [Amazon EKS 포드에 대한 보안 그룹 정책 사용](sg-pods-example-deployment.md) 섹션을 참조하세요.

1. 현재 Kubernetes용 Amazon VPC CNI 플러그인 버전은 다음 명령을 통해 확인할 수 있습니다.

   ```
   kubectl describe daemonset aws-node --namespace kube-system | grep amazon-k8s-cni: | cut -d : -f 3
   ```

   예제 출력은 다음과 같습니다.

   ```
   v1.7.6
   ```

   Kubernetes용 Amazon VPC CNI 플러그인 버전이 `1.7.7` 이하인 경우 플러그인을 버전 `1.7.7` 이상으로 업데이트합니다. 자세한 내용은 [Amazon VPC CNI를 통해 포드에 IP 할당](managing-vpc-cni.md) 섹션을 참조하세요.

1. Amazon EKS 클러스터와 연결된 [클러스터 역할](cluster-iam-role.md#create-service-role)에 [AmazonEKSVPCResourceController](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AmazonEKSVPCResourceController) 관리형 IAM 정책을 추가합니다. 정책을 사용하면 역할이 네트워크 인터페이스, 프라이빗 IP 주소, 네트워크 인스턴스의 연결 및 분리를 관리할 수 있습니다.

   1. 클러스터 IAM 역할의 이름을 검색하고 변수에 저장합니다. *my-cluster*를 해당 클러스터의 이름으로 바꿉니다.

      ```
      cluster_role=$(aws eks describe-cluster --name my-cluster --query cluster.roleArn --output text | cut -d / -f 2)
      ```

   1. 책을 역할에 연결합니다.

      ```
      aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEKSVPCResourceController --role-name $cluster_role
      ```

1. `aws-node` DaemonSet에서 `ENABLE_POD_ENI` 변수를 `true`로 설정하여 Amazon VPC CNI 추가 기능이 의 네트워크 인터페이스를 관리하도록 합니다. 이 설정이 `true`로 설정되면 클러스터의 각 노드에서 추가 기능이 `cninode` 사용자 지정 리소스를 생성합니다. VPC 리소스 컨트롤러는 설명 `aws-k8s-trunk-eni`를 사용하여 *트렁크 네트워크 인터페이스*라는 하나의 특수 네트워크 인터페이스를 생성하고 연결합니다.

   ```
   kubectl set env daemonset aws-node -n kube-system ENABLE_POD_ENI=true
   ```
**참고**  
트렁크 네트워크 인터페이스는 인스턴스 유형에서 지원하는 최대 네트워크 인터페이스 수에 포함됩니다. 인스턴스 유형별로 지원되는 최대 네트워크 인터페이스 수 목록은 *Amazon EC2 사용 설명서*에서 [인스턴스 유형별 네트워크 인터페이스당 IP 주소](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI) 섹션을 참조하세요. 노드에 이미 최대 수의 표준 네트워크 인터페이스가 연결되어 있는 경우 VPC 리소스 컨트롤러가 공간을 예약합니다. 컨트롤러가 표준 네트워크 인터페이스를 분리 및 삭제하고 트렁크 네트워크 인터페이스를 만든 다음 인스턴스에 연결할 수 있도록 실행 중인 포드를 스케일 다운해야 합니다.

1. 다음 명령을 사용하여 `CNINode` 사용자 지정 리소스를 포함하는 노드를 확인할 수 있습니다. `No resources found`가 반환된 경우 몇 초 정도 기다렸다가 다시 시도하세요. 이전 단계에서는 몇 초 정도 걸리는 Kubernetes용 Amazon VPC CNI 플러그인 포드를 다시 시작해야 합니다.

   ```
   kubectl get cninode -A
        NAME FEATURES
        ip-192-168-64-141.us-west-2.compute.internal [{"name":"SecurityGroupsForPods"}]
        ip-192-168-7-203.us-west-2.compute.internal [{"name":"SecurityGroupsForPods"}]
   ```

   `1.15` 이전의 VPC CNI 버전을 사용하는 경우 `CNINode` 사용자 지정 리소스 대신 노드 레이블이 사용됩니다. 다음 명령을 사용하여 노드 레이블 `aws-k8s-trunk-eni` 레이블이 `true`로 설정된 노드를 확인할 수 있습니다. `No resources found`가 반환된 경우 몇 초 정도 기다렸다가 다시 시도하세요. 이전 단계에서는 몇 초 정도 걸리는 Kubernetes용 Amazon VPC CNI 플러그인 포드를 다시 시작해야 합니다.

   ```
   kubectl get nodes -o wide -l vpc.amazonaws.com/has-trunk-attached=true
   ```

   트렁크 네트워크 인터페이스가 만들어지면 트렁크 또는 표준 네트워크 인터페이스에서 포드에 보조 IP 주소를 할당합니다. 노드가 삭제되면 트렁크 인터페이스가 자동으로 삭제됩니다.

   이후 단계에서 포드에 대한 보안 그룹을 배포하면 VPC 리소스 컨트롤러가 `aws-k8s-branch-eni`의 설명과 함께 *브랜치 네트워크 인터페이스*라는 특수한 네트워크 인터페이스를 생성하고 거기에 보안 그룹을 연결합니다. 브랜치 네트워크 인터페이스는 노드에 연결된 표준 및 트렁크 네트워크 인터페이스와 함께 생성됩니다.

   라이브니스 또는 준비 상태 프로브를 사용하는 경우 `kubelet`가 TCP를 사용하여 브랜치 네트워크 인터페이스의 포드에 연결할 수 있도록 *TCP 초기 demux*도 비활성화해야 합니다. *TCP 초기 Demux*를 비활성화하려면 다음 명령을 실행합니다.

   ```
   kubectl patch daemonset aws-node -n kube-system \
     -p '{"spec": {"template": {"spec": {"initContainers": [{"env":[{"name":"DISABLE_TCP_EARLY_DEMUX","value":"true"}],"name":"aws-vpc-cni-init"}]}}}}'
   ```
**참고**  
다음 단계에 설명된 대로 Kubernetes용 Amazon VPC CNI 플러그인 `1.11.0` 이상을 사용하고 `POD_SECURITY_GROUP_ENFORCING_MODE`=`standard`를 설정한 경우에는 이전 명령을 실행할 필요가 없습니다.

1. 클러스터에서 `NodeLocal DNSCache`를 사용하거나, 자체 보안 그룹이 있는 포드를 통해 Calico 네트워크 정책을 사용하거나, 보안 그룹을 할당하려는 포드에 대해 `externalTrafficPolicy`를 `Local`로 설정한 인스턴스 대상을 사용하는 `NodePort` 및 `LoadBalancer` 유형의 Kubernetes 서비스가 있는 경우 버전 `1.11.0` 이상의 Kubernetes용 Amazon VPC CNI 플러그인 추가 기능을 사용하고 있어야 하며 다음 설정을 활성화해야 합니다.

   ```
   kubectl set env daemonset aws-node -n kube-system POD_SECURITY_GROUP_ENFORCING_MODE=standard
   ```

   중요: **포드 보안 그룹 규칙은 동일한 노드에 있는 포드 간 또는 포드와 서비스(예: `kubelet` 또는 `nodeLocalDNS`) 간의 트래픽에는 적용되지 않습니다. 동일한 노드에서 서로 다른 보안 그룹을 사용하는 포드는 서로 다른 서브넷에 구성되어 있기 때문에 통신할 수 없으며, 이러한 서브넷 사이에 라우팅이 비활성화되어 있습니다.** 포드에서 VPC 외부의 주소로 향하는 아웃바운드 트래픽은 인스턴스의 기본 네트워크 인터페이스의 IP 주소로 변환된 네트워크 주소입니다(`AWS_VPC_K8S_CNI_EXTERNALSNAT=true`로 설정하지 않은 경우 제외). 이 트래픽의 경우 포드의 보안 그룹의 규칙이 아닌 기본 네트워크 인터페이스에 대한 보안 그룹의 규칙이 사용됩니다. \$1\$1 이 설정을 기존 포드에 적용하려면 포드 또는 포드가 실행되고 있는 노드를 다시 시작해야 합니다.

1. 포드에 대한 보안 그룹 정책을 사용하는 방법을 보려면 [Amazon EKS 포드에 대한 보안 그룹 정책 사용](sg-pods-example-deployment.md) 섹션을 참조하세요.

# Amazon EKS 포드에 대한 보안 그룹 정책 사용
<a name="sg-pods-example-deployment"></a>

포드에 대한 보안 그룹을 사용하려면 기존 보안 그룹이 있어야 합니다. 다음 단계에서는 포드의 보안 그룹 정책을 사용하는 방법을 보여 줍니다. 달리 명시되지 않는 한, 변수가 터미널에 걸쳐 지속되지 않는 다음 단계에서 사용되므로 동일한 터미널에서 모든 단계를 완료합니다.

Amazon EC2 인스턴스에 포드가 있는 경우 이 절차를 사용하기 전에 플러그인을 구성해야 합니다. 자세한 내용은 [Amazon EKS 포드의 보안 그룹에 대해 Kubernetes용 Amazon VPC CNI 플러그인 구성](security-groups-pods-deployment.md) 섹션을 참조하세요.

1. 리소스를 배포할 Kubernetes 네임스페이스를 만듭니다. 사용하려는 네임스페이스의 이름으로 *my-namespace*를 바꿀 수 있습니다.

   ```
   kubectl create namespace my-namespace
   ```

1.  Amazon EKS `SecurityGroupPolicy`를 클러스터에 배포합니다.

   1. 다음 콘텐츠를 디바이스에 복사합니다. 서비스 계정 레이블에 따라 포드를 선택하려는 경우 *podSelector*를 `serviceAccountSelector`로 바꿀 수 있습니다. 두 선택기 중 하나만 지정해야 합니다. 비어 있는 `podSelector`(예: `podSelector: {}`)는 네임스페이스의 모든 포드를 선택합니다. *my-role*을 자신의 역할 이름으로 변경할 수 있습니다. 비어 있는 `serviceAccountSelector`는 네임스페이스의 모든 서비스 계정을 선택합니다. *my-security-group-policy*를 자신의 `SecurityGroupPolicy`에 대한 이름으로 바꾸고 `SecurityGroupPolicy`를 생성하려는 네임스페이스로 *my-namespace*를 바꿀 수 있습니다.

      *my\$1pod\$1security\$1group\$1id*를 기존 보안 그룹의 ID로 바꿔야 합니다. 기존 보안 그룹이 없으면 하나를 생성해야 합니다. 자세한 내용은 [Amazon EC2 사용 설명서](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/)의 [Linux 인스턴스용 Amazon EC2 보안 그룹](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html)을 참조하세요. 보안 그룹 ID는 1\$15개를 지정할 수 있습니다. 둘 이상의 ID를 지정하면 모든 보안 그룹의 모든 규칙 조합이 선택한 포드에 적용됩니다.

      ```
      cat >my-security-group-policy.yaml <<EOF
      apiVersion: vpcresources.k8s.aws/v1beta1
      kind: SecurityGroupPolicy
      metadata:
        name: my-security-group-policy
        namespace: my-namespace
      spec:
        podSelector:
          matchLabels:
            role: my-role
        securityGroups:
          groupIds:
            - my_pod_security_group_id
      EOF
      ```
**중요**  
포드에 대해 지정한 보안 그룹 또는 그룹은 다음 기준을 충족해야 합니다.  
존재해야 합니다. 존재하지 않을 경우 선택기와 일치하는 포드를 배포하면 포드가 생성 프로세스에 계속 남아 있습니다. 포드에 대해 설명하면 다음과 유사한 오류 메시지가 표시됩니다. `An error occurred (InvalidSecurityGroupID.NotFound) when calling the CreateNetworkInterface operation: The securityGroup ID 'sg-05b1d815d1EXAMPLE' does not exist`.
보안 그룹에서는 프로브를 구성한 모든 포트를 통해 노드에 적용된 보안 그룹의 인바운드 통신(`kubelet`의 경우)을 허용해야 합니다.
CoreDNS를 실행하는 (또는 포드가 실행되는 노드)에 할당된 보안 그룹에 대한 `TCP` 및 `UDP` 포트 53을 통한 아웃바운드 통신을 허용해야 합니다. CoreDNS 포드의 보안 그룹에서는 지정하는 보안 그룹의 인바운드 `TCP` 및 `UDP` 포트 53 트래픽을 허용해야 합니다.
통신하려면 필요한 다른 포드와 통신하는 데 필요한 인바운드 및 아웃바운드 규칙이 있어야 합니다.
Fargate에서 보안 그룹을 사용하는 경우 포드가 Kubernetes 컨트롤 플레인과 통신할 수 있는 규칙이 있어야 합니다. 이 작업을 수행할 수 있는 가장 쉬운 방법은 클러스터 보안 그룹을 보안 그룹 중 하나로 지정하는 것입니다.
보안 그룹 정책은 새로 예약된 포드에만 적용되며, 실행 중인 포드에는 영향을 주지 않습니다.

   1. 정책을 배포합니다.

      ```
      kubectl apply -f my-security-group-policy.yaml
      ```

1. 이전 단계에서 지정한 *podSelector*의 *my-role* 값과 일치하는 레이블을 사용하여 샘플 애플리케이션을 배포하세요.

   1. 다음 콘텐츠를 디바이스에 복사합니다. 예제 값을 사용자 값으로 바꾼 다음 수정된 명령을 실행합니다. *my-role*을 바꾸는 경우 이전 단계에서 선택기에 지정한 값과 동일한지 확인합니다.

      ```
      cat >sample-application.yaml <<EOF
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: my-deployment
        namespace: my-namespace
        labels:
          app: my-app
      spec:
        replicas: 4
        selector:
          matchLabels:
            app: my-app
        template:
          metadata:
            labels:
              app: my-app
              role: my-role
          spec:
            terminationGracePeriodSeconds: 120
            containers:
            - name: nginx
              image: public.ecr.aws/nginx/nginx:1.23
              ports:
              - containerPort: 80
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: my-app
        namespace: my-namespace
        labels:
          app: my-app
      spec:
        selector:
          app: my-app
        ports:
          - protocol: TCP
            port: 80
            targetPort: 80
      EOF
      ```

   1. 다음 명령을 사용하여 애플리케이션을 배포합니다. 애플리케이션을 배포할 때 `role` 레이블과 일치하는 Kubernetes용 Amazon VPC CNI 플러그인과 이전 단계에서 지정한 보안 그룹이 포드에 적용됩니다.

      ```
      kubectl apply -f sample-application.yaml
      ```

1. 샘플 애플리케이션을 통해 배포된 포드를 봅니다. 이 주제의 나머지 부분에서는 이 터미널을 `TerminalA`로 언급합니다.

   ```
   kubectl get pods -n my-namespace -o wide
   ```

   예제 출력은 다음과 같습니다.

   ```
   NAME                             READY   STATUS    RESTARTS   AGE     IP               NODE                                            NOMINATED NODE   READINESS GATES
   my-deployment-5df6f7687b-4fbjm   1/1     Running   0          7m51s   192.168.53.48    ip-192-168-33-28.region-code.compute.internal   <none>           <none>
   my-deployment-5df6f7687b-j9fl4   1/1     Running   0          7m51s   192.168.70.145   ip-192-168-92-33.region-code.compute.internal   <none>           <none>
   my-deployment-5df6f7687b-rjxcz   1/1     Running   0          7m51s   192.168.73.207   ip-192-168-92-33.region-code.compute.internal   <none>           <none>
   my-deployment-5df6f7687b-zmb42   1/1     Running   0          7m51s   192.168.63.27    ip-192-168-33-28.region-code.compute.internal   <none>           <none>
   ```
**참고**  
포드가 멈춘 경우 다음 팁을 시도해 보세요.  
포드가 `Waiting` 상태에서 멈춘 경우 `kubectl describe pod my-deployment-xxxxxxxxxx-xxxxx -n my-namespace `를 실행합니다. `Insufficient permissions: Unable to create Elastic Network Interface.`(권한 부족: 탄력적 네트워크 인터페이스를 생성할 수 없습니다.)가 표시되면 이전 단계에서 IAM 클러스터 역할에 IAM 정책을 추가했는지 확인합니다.
포드가 `Pending` 상태로 멈춰 있는 경우 노드 인스턴스 유형이 [limits.go](https://github.com/aws/amazon-vpc-resource-controller-k8s/blob/master/pkg/aws/vpc/limits.go)에 나열되어 있고 인스턴스 유형에서 지원하는 최대 브랜치 네트워크 인터페이스 수와 노드 그룹의 노드 수를 곱한 값이 아직 충족되지 않았는지 확인합니다. 예를 들어, `m5.large` 인스턴스는 9개의 브랜치 네트워크 인터페이스를 지원합니다. 노드 그룹에 5개의 노드가 있는 경우 노드 그룹에 대해 최대 45개의 브랜치 네트워크 인터페이스를 생성할 수 있습니다. 배포하려는 46 번째 포드는 연결된 보안 그룹이 있는 다른 포드가 삭제될 때까지 `Pending` 상태로 남아 있습니다.

   `kubectl describe pod my-deployment-xxxxxxxxxx-xxxxx -n my-namespace `를 실행할 때 다음 메시지와 유사한 메시지가 표시될 경우 무시해도 됩니다. 이 메시지는 Kubernetes용 Amazon VPC CNI 플러그인이 호스트 네트워킹을 설정하려고 할 때 네트워크 인터페이스가 생성되는 동안 실패할 경우 나타날 수 있습니다. 플러그인은 네트워크 인터페이스가 생성될 때까지 이 이벤트를 기록합니다.

   ```
   Failed to create Pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "e24268322e55c8185721f52df6493684f6c2c3bf4fd59c9c121fd4cdc894579f" network for Pod "my-deployment-5df6f7687b-4fbjm": networkPlugin
   cni failed to set up Pod "my-deployment-5df6f7687b-4fbjm-c89wx_my-namespace" network: add cmd: failed to assign an IP address to container
   ```

   인스턴스 유형에서 실행할 수 있는 최대 포드 수를 초과할 수 없습니다. 각 인스턴스 유형에서 실행할 수 있는 최대 포드 수 목록은 GitHub의 [eni-max-pods.txt](https://github.com/aws/amazon-vpc-cni-k8s/blob/master/misc/eni-max-pods.txt)를 참조하세요. 연결된 보안 그룹이 있는 포드를 삭제하거나 포드가 실행 중인 노드를 삭제하면 VPC 리소스 컨트롤러가 브랜치 네트워크 인터페이스를 삭제합니다. 보안 그룹에 대해 포드를 사용하는 포드가 있는 클러스터를 삭제하면 컨트롤러가 브랜치 네트워크 인터페이스를 삭제하지 않으므로 직접 삭제해야 합니다. 네트워크 인터페이스를 삭제하는 방법에 대한 자세한 내용은 Amazon EC2 사용 설명서의 [네트워크 인터페이스 삭제](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#delete_eni)를 참조하세요.

1. 별도의 터미널에서 포드 중 하나에 쉘을 적용합니다. 이 주제의 나머지 부분에서는 이 터미널을 `TerminalB`로 언급합니다. *5df6f7687b-4fbjm*을 이전 단계의 결과에서 반환된 포드 중 하나의 ID로 바꾸세요.

   ```
   kubectl exec -it -n my-namespace my-deployment-5df6f7687b-4fbjm -- /bin/bash
   ```

1. `TerminalB`의 셸에서 샘플 애플리케이션이 작동하는지 확인합니다.

   ```
   curl my-app
   ```

   예제 출력은 다음과 같습니다.

   ```
   <!DOCTYPE html>
   <html>
   <head>
   <title>Welcome to nginx!</title>
   [...]
   ```

   애플리케이션이 실행되는 모든 포드는 사용자가 생성한 보안 그룹과 연결되기 때문에 이 결과가 표시됩니다. 해당 그룹에는 보안 그룹이 연결되는 모든 포드 간에 모든 트래픽을 허용하는 규칙이 포함되어 있습니다. DNS 트래픽은 해당 보안 그룹에서 노드와 연결된 클러스터 보안 그룹으로 아웃바운드 트래픽이 허용됩니다. 노드가 포드에서 이름 조회를 수행한 CoreDNS 포드를 실행하고 있습니다.

1. 보안 그룹에서 클러스터 보안 그룹으로의 DNS 통신을 허용하는 보안 그룹 규칙을 `TerminalA`에서 제거합니다. 이전 단계에서 클러스터 보안 그룹에 DNS 규칙을 추가하지 않은 경우 *\$1my\$1cluster\$1security\$1group\$1id*를 사용자가 규칙을 생성한 보안 그룹의 ID로 바꿉니다.

   ```
   aws ec2 revoke-security-group-ingress --group-id $my_cluster_security_group_id --security-group-rule-ids $my_tcp_rule_id
   aws ec2 revoke-security-group-ingress --group-id $my_cluster_security_group_id --security-group-rule-ids $my_udp_rule_id
   ```

1. `TerminalB`에서 다시 애플리케이션에 액세스하려고 시도합니다.

   ```
   curl my-app
   ```

   예제 출력은 다음과 같습니다.

   ```
   curl: (6) Could not resolve host: my-app
   ```

   포드에서 클러스터 보안 그룹을 연결해 주는 CoreDNS 포드에 더 이상 액세스할 수 없기 때문에 이 시도는 실패합니다. 클러스터 보안 그룹에는 포드에 연결된 보안 그룹에서 DNS 통신을 허용하는 보안 그룹 규칙이 더 이상 없습니다.

   이전 단계에서 포드 중 하나에 대해 반환된 IP 주소를 사용하여 애플리케이션에 액세스하려고 시도하는 경우 보안 그룹이 연결되어 있는 포드 간에 모든 포트가 허용되고 이름 조회가 필요 없기 때문에 응답이 계속 표시됩니다.

1. 실험이 끝나면 생성한 샘플 보안 그룹 정책, 애플리케이션 및 보안 그룹을 제거할 수 있습니다. `TerminalA`에서 다음 명령을 실행합니다.

   ```
   kubectl delete namespace my-namespace
   aws ec2 revoke-security-group-ingress --group-id $my_pod_security_group_id --security-group-rule-ids $my_inbound_self_rule_id
   wait
   sleep 45s
   aws ec2 delete-security-group --group-id $my_pod_security_group_id
   ```

# 포드에 여러 네트워크 인터페이스 연결
<a name="pod-multiple-network-interfaces"></a>

기본적으로 Amazon VPC CNI 플러그인은 각 포드에 1개의 IP 주소를 할당합니다. 이 IP 주소는 포드의 모든 수신 및 발신 트래픽을 처리하는 *탄력적 네트워크 인터페이스*에 연결됩니다. 초당 대역폭 및 패킷 속도 성능을 높이려면 VPC CNI의 *멀티 NIC 기능*을 사용하여 멀티 호밍 포드를 구성할 수 있습니다. 멀티 호밍 포드는 여러 네트워크 인터페이스(및 여러 IP 주소)를 사용하는 단일 Kubernetes 포드입니다. 멀티 호밍 포드를 실행하면 동시 연결을 사용하여 여러 네트워크 인터페이스에 애플리케이션 트래픽을 분산할 수 있습니다. 이는 인공 지능(AI), 기계 학습(ML) 및 고성능 컴퓨팅(HPC) 사용 사례에 특히 유용합니다.

다음 다이어그램은 여러 개의 네트워크 인터페이스 카드(NIC)가 사용 중인 워커 노드에서 실행되는 멀티 호밍 포드를 보여줍니다.

![\[네트워크 인터페이스 2개가 ENA가 있는 네트워크 인터페이스 1개와 ENA 및 EFA가 있는 네트워크 인터페이스 1개가 연결된 멀티 호밍 포드\]](http://docs.aws.amazon.com/ko_kr/eks/latest/userguide/images/multi-homed-pod.png)


## 배경
<a name="pod-multi-nic-background"></a>

Amazon EC2에서 *탄력적 네트워크 인터페이스*는 VPC에서 가상 네트워크 카드를 나타내는 논리적 네트워킹 구성 요소입니다. 많은 EC2 인스턴스 유형의 경우 네트워크 인터페이스는 하드웨어에서 단일 네트워크 인터페이스 카드(NIC)를 공유합니다. 이 단일 NIC의 대역폭과 초당 패킷 속도는 최대입니다.

멀티 NIC 기능이 활성화된 경우 VPC CNI는 기본적으로 IP 주소를 대량으로 할당하지 않습니다. 대신 VPC CNI는 새 포드가 시작될 때 온디맨드 방식으로 각 네트워크 카드의 네트워크 인터페이스에 1개의 IP 주소를 할당합니다. 이 동작은 멀티 호밍 포드 사용으로 인해 증가하는 IP 주소 소진 속도를 줄입니다. VPC CNI는 온디맨드 방식으로 IP 주소를 할당하기 때문에 멀티 NIC 기능이 활성화된 인스턴스에서 포드를 시작하는 데 더 오랜 시간이 걸릴 수 있습니다.

## 고려 사항
<a name="pod-multi-nic-considerations"></a>
+ Kubernetes 클러스터가 VPC CNI 버전 `1.20.0` 이상을 실행 중이어야 합니다. 멀티 NIC 기능은 VPC CNI 이상 버전에서만 사용할 수 `1.20.0` 있습니다.
+ VPC CNI 플러그인에서 `ENABLE_MULTI_NIC` 환경 변수를 활성화합니다. 다음 명령을 실행하여 변수를 설정하고 DaemonSet의 배포를 시작할 수 있습니다.
  +  `kubectl set env daemonset aws-node -n kube-system ENABLE_MULTI_NIC=true` 
+ 여러 개의 네트워크 인터페이스 카드(NIC)가 있는 워커 노드를 생성해야 합니다. 여러 개의 네트워크 인터페이스 카드가 있는 EC2 인스턴스 목록은 **Amazon EC2 사용 설명서**의 [네트워크 카드](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#network-cards)를 참조하세요.
+ 멀티 NIC 기능이 활성화된 경우 VPC CNI는 기본적으로 IP 주소를 대량으로 할당하지 않습니다. VPC CNI는 온디맨드 방식으로 IP 주소를 할당하기 때문에 멀티 NIC 기능이 활성화된 인스턴스에서 포드를 시작하는 데 더 오랜 시간이 걸릴 수 있습니다. 자세한 내용은 이전[배경](#pod-multi-nic-background) 섹션을 참조하세요.
+ 멀티 NIC 기능이 활성화된 경우 포드에는 기본적으로 여러 개의 네트워크 인터페이스가 없습니다. 멀티 NIC를 사용하도록 각 워크로드를 구성해야 합니다. 여러 개의 네트워크 인터페이스가 있어야 하는 워크로드에 `k8s.amazonaws.com/nicConfig: multi-nic-attachment` 주석을 추가합니다.

### `IPv6` 고려 사항
<a name="pod-multi-nic-considerations-ipv6"></a>
+  **사용자 지정 IAM 정책** - `IPv6` 클러스터의 경우 VPC CNI에 대해 다음 사용자 지정 IAM 정책을 생성하고 사용합니다. 이 정책은 멀티 NIC에만 해당됩니다. `IPv6` 클러스터에서 VPC CNI를 사용하는 방법에 대한 자세한 내용은 [클러스터, 포드 및 서비스에 대한 IPv6 주소에 대해 알아보기](cni-ipv6.md) 섹션을 참조하세요.

  ```
  {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
          {
              "Sid": "AmazonEKSCNIPolicyIPv6MultiNIC",
              "Effect": "Allow",
              "Action": [
                  "ec2:CreateNetworkInterface",
                  "ec2:DescribeInstances",
                  "ec2:AssignIpv6Addresses",
                  "ec2:DetachNetworkInterface",
                  "ec2:DescribeNetworkInterfaces",
                  "ec2:DescribeTags",
                  "ec2:ModifyNetworkInterfaceAttribute",
                  "ec2:DeleteNetworkInterface",
                  "ec2:DescribeInstanceTypes",
                  "ec2:UnassignIpv6Addresses",
                  "ec2:AttachNetworkInterface",
                  "ec2:DescribeSubnets"
              ],
              "Resource": "*"
          },
          {
              "Sid": "AmazonEKSCNIPolicyENITagIPv6MultiNIC",
              "Effect": "Allow",
              "Action": "ec2:CreateTags",
              "Resource": "arn:aws:ec2:*:*:network-interface/*"
          }
      ]
  }
  ```
+  `IPv6` **전환 메커니즘 사용 불가** - 멀티 NIC 기능을 사용하는 경우 VPC CNI는 `IPv6` 클러스터의 포드에 `IPv4` 주소를 할당하지 않습니다. 그렇지 않으면 VPC CNI는 포드가 다른 Amazon VPC 또는 인터넷의 외부 `IPv4` 리소스와 통신할 수 있도록 각 포드에 호스트-로컬 `IPv4` 주소를 할당합니다.

## 사용법
<a name="pod-multi-NIC-usage"></a>

VPC CNI에서 멀티 NIC 기능이 활성화되고 `aws-node` 포드가 다시 시작된 후에는 각 워크로드를 멀티 호밍으로 구성할 수 있습니다. 필요한 주석이 포함된 YAML 구성 예시:

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: orders-deployment
  namespace: ecommerce
  labels:
    app: orders
spec:
  replicas: 3
  selector:
    matchLabels:
      app: orders
  template:
    metadata:
      annotations:
         k8s.amazonaws.com/nicConfig: multi-nic-attachment
      labels:
        app: orders
    spec:
...
```

## FAQ
<a name="pod-muti-nic-faqs"></a>

### **1: 네트워크 인터페이스 카드(NIC)란 무엇인가요?**
<a name="pod-muti-nic-faqs-nic"></a>

네트워크 카드라고도 하는 네트워크 인터페이스 카드(NIC)는 기본 클라우드 컴퓨팅 하드웨어에 대한 네트워크 연결을 활성화하는 물리적 디바이스입니다. 최신 EC2 서버에서는 Nitro 네트워크 카드를 의미합니다. 탄력적 네트워크 인터페이스(ENI)는 이 기본 네트워크 카드를 가상으로 표현한 것입니다.

일부 EC2 인스턴스 유형에는 대역폭 및 패킷 속도 성능을 높이기 위해 여러 개의 NIC가 있습니다. 이러한 인스턴스의 경우 추가 네트워크 카드에 보조 ENI를 할당할 수 있습니다. 예를 들어, ENI \$11은 네트워크 카드 인덱스 0에 연결된 NIC의 인터페이스로 기능할 수 있는 반면, ENI \$12는 별도의 네트워크 카드 인덱스에 연결된 NIC의 인터페이스로 기능할 수 있습니다.

### **2. 멀티 호밍 포드란 무엇인가요?**
<a name="pod-muti-nic-faqs-pod"></a>

멀티 호밍 포드는 여러 네트워크 인터페이스(및 여러 IP 주소)를 사용하는 단일 Kubernetes 포드입니다. 각 포드 네트워크 인터페이스는 [탄력적 네트워크 인터페이스(ENI)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html)와 연결되고, 이러한 ENI는 기본 워커 노드에 있는 별도의 NIC를 논리적으로 표현한 것입니다. 네트워크 인터페이스가 여러 개인 멀티 호밍 포드에는 추가 데이터 전송 용량이 있어 데이터 전송 속도를 높입니다.

**중요**  
VPC CNI는 인스턴스 유형에 여러 개의 NIC가 있는 멀티 호밍 포드만 구성할 수 있습니다.

### **3. 왜 이 기능을 사용해야 하나요?**
<a name="pod-muti-nic-faqs-why"></a>

Kubernetes 기반 워크로드에서 네트워크 성능을 조정해야 하는 경우 멀티 NIC 기능을 사용하여 ENA 디바이스가 연결된 모든 기본 NIC와 접속하는 멀티 호밍 포드를 실행할 수 있습니다. 추가 네트워크 카드를 활용하면 여러 동시 연결에 애플리케이션 트래픽을 분산하여 애플리케이션의 대역폭 용량과 패킷 속도 성능이 증가합니다. 이는 인공 지능(AI), 기계 학습(ML) 및 고성능 컴퓨팅(HPC) 사용 사례에 특히 유용합니다.

### **4. 이 기능은 어떻게 사용하나요?**
<a name="pod-muti-nic-faqs-how-to-enable"></a>

1. 먼저 Kubernetes 클러스터가 VPC CNI 버전 1.20 이상을 사용하는지 확인해야 합니다. VPC CNI를 EKS 추가 기능으로 업데이트하는 단계는 [Amazon VPC CNI 업데이트(Amazon EKS 추가 기능)](vpc-add-on-update.md) 섹션을 참조하세요.

1. 그런 다음 `ENABLE_MULTI_NIC` 환경 변수를 사용하여 VPC CNI에서 멀티 NIC 지원을 활성화해야 합니다.

1. 그리고 여러 네트워크 카드가 있는 노드를 만들고 조인해야 합니다. 여러 개의 네트워크 카드가 있는 EC2 인스턴스 유형 목록은 *Amazon EC2 사용 설명서*의 [네트워크 카드](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#network-cards)를 참조하세요.

1. 마지막으로 여러 네트워크 인터페이스(멀티 호밍 포드)를 사용하거나 단일 네트워크 인터페이스를 사용하도록 각 워크로드를 구성합니다.

### **5. 지원되는 워커 노드에서 여러 개의 NIC를 사용하도록 워크로드를 구성하려면 어떻게 해야 하나요?**
<a name="pod-muti-nic-faqs-how-to-workloads"></a>

멀티 호밍 포드를 사용하려면 `k8s.amazonaws.com/nicConfig: multi-nic-attachment` 주석을 추가해야 합니다. 이렇게 하면 기본 인스턴스의 모든 NIC에서 포드로 ENI가 연결됩니다(포드와 NIC 사이에 일대다 매핑).

이 주석이 누락된 경우 VPC CNI는 포드에 네트워크 인터페이스가 1개만 필요하다고 가정하고 사용 가능한 NIC의 ENI에서 IP를 할당합니다.

### **6. 이 기능이 지원되는 네트워크 인터페이스 어댑터는 무엇인가요?**
<a name="pod-muti-nic-faqs-adapters"></a>

IP 트래픽용 기본 네트워크 카드에 ENA가 하나 이상 연결되어 있는 경우 모든 네트워크 인터페이스 어댑터를 사용할 수 있습니다. 자세한 내용은 *Amazon EC2 사용 설명서*의 [Elastic Network Adapter(ENA)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enhanced-networking-ena.html)를 참조하세요.

지원되는 네트워크 디바이스 구성:
+  **ENA** 인터페이스는 VPC를 위한 IP 네트워킹을 지원하는 데 필요한 모든 기존 IP 네트워킹 및 라우팅 기능을 제공합니다. 자세한 내용은 [EC2 인스턴스에서 ENA로 향상된 네트워킹 활성화](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enhanced-networking-ena.html)를 참조하세요.
+  **EFA**(**ENA 포함** **EFA**) 인터페이스는 IP 네트워킹을 위한 ENA 디바이스와 짧은 지연 시간, 높은 처리량 통신을 위한 EFA 디바이스를 모두 제공합니다.

**중요**  
네트워크 카드에 **EFA 전용** 어댑터만 연결된 경우 VPC CNI는 멀티 호밍 포드에 대한 네트워크 연결을 프로비저닝할 때 이를 건너뜁니다. 하지만 **EFA 전용** 어댑터를 네트워크 카드의 **ENA** 어댑터와 결합하면 VPC CNI가 디바이스의 ENI도 관리합니다. EKS 클러스터에서 EFA 전용 인터페이스를 사용하려면 [Elastic Fabric Adapter를 사용한 Amazon EKS에서 기계 학습 훈련 실행](node-efa.md) 섹션을 참조하세요.

### **7. 클러스터의 노드에 ENA 지원이 있는지 확인할 수 있나요?**
<a name="pod-muti-nic-faqs-node-ena"></a>

예, AWS CLI 또는 EC2 API를 사용하여 클러스터의 EC2 인스턴스에 대한 네트워크 정보를 검색할 수 있습니다. 인스턴스에 ENA 지원이 있는지 여부에 대한 세부 정보가 제공됩니다. 다음 예시에서 `<your-instance-id>`를 노드의 EC2 인스턴스 ID로 바꾸세요.

 AWS CLI 예제:

```
aws ec2 describe-instances --instance-ids <your-instance-id> --query "Reservations[].Instances[].EnaSupport"
```

출력 예시:

```
[ true ]
```

### **8. 포드와 연결된 다른 IP 주소를 볼 수 있나요?**
<a name="pod-muti-nic-faqs-list-ips"></a>

아니요, 쉽지 않습니다. 하지만 노드에서 `nsenter`를 사용하여 `ip route show`와 같은 일반적인 네트워크 도구를 실행하고 추가 IP 주소 및 인터페이스를 볼 수 있습니다.

### **9. 포드의 네트워크 인터페이스 수를 제어할 수 있나요?**
<a name="pod-muti-nic-faqs-number-of-enis"></a>

아니요. 워크로드가 지원되는 인스턴스에서 여러 NIC를 사용하도록 구성된 경우 단일 포드는 인스턴스의 모든 네트워크 카드에서 자동으로 IP 주소를 보유합니다. 또는 싱글 호밍 포드에는 인스턴스의 NIC 하나에 네트워크 인터페이스 하나가 연결됩니다.

**중요**  
**EFA 전용** 디바이스에 *한하여* 연결된 네트워크 카드는 VPC CNI에서 건너뛰게 됩니다.

### **10. 특정 NIC를 사용하도록 포드를 구성할 수 있나요?**
<a name="pod-muti-nic-faqs-specify-nic"></a>

아니요, 이 기능은 지원되지 않습니다. 포드에 관련 주석이 있는 경우 VPC CNI는 워커 노드의 ENA 어댑터에서 모든 NIC를 사용하도록 자동으로 구성합니다.

### **11. 이 기능은 다른 VPC CNI 네트워킹 기능과 함께 작동하나요?**
<a name="pod-muti-nic-faqs-modes"></a>

예, VPC CNI의 멀티 NIC 기능은 *사용자 지정 네트워킹*과 *향상된 서브넷 검색* 모두에서 작동합니다. 하지만 멀티 호밍 포드는 사용자 지정 서브넷 또는 보안 그룹을 사용하지 않습니다. 대신 VPC CNI는 노드와 동일한 서브넷 및 보안 그룹 구성을 가진 멀티 호밍 포드에 IP 주소 및 네트워크 인터페이스를 할당합니다. 사용자 지정 네트워킹에 대한 자세한 내용은 [사용자 지정 네트워킹을 통해 대체 서브넷에 포드 배포](cni-custom-network.md) 섹션을 참조하세요.

VPC CNI의 멀티 NIC 기능은 작동하지 않으며 *포드의 보안 그룹*과 함께 사용할 수 없습니다.

### **12. 이 기능에서 네트워크 정책을 사용할 수 있나요?**
<a name="pod-muti-nic-faqs-netpol"></a>

예, 멀티 NIC에서 Kubernetes 네트워크 정책을 사용할 수 있습니다. Kubernetes 네트워크 정책은 포드에서 송수신되는 네트워크 트래픽을 제한합니다. VPC CNI에 네트워크 정책 적용에 대한 자세한 내용은 [Kubernetes 네트워크 정책을 통해 pod 트래픽 제한](cni-network-policy.md) 섹션을 참조하세요.

### **13. EKS Auto Mode에서 멀티 NIC 지원이 활성화되어 있나요?**
<a name="pod-muti-nic-faqs-auto-mode"></a>

EKS Auto Mode 클러스터에서는 멀티 NIC가 지원되지 않습니다.