Amazon EKS 노드의 보조 네트워크 인터페이스 사용자 지정

Amazon EKS 노드의 보조 네트워크 인터페이스 사용자 지정

본 튜토리얼에서는 Amazon EKS 클러스터에 사용자 지정 네트워킹(custom networking)을 구성하여, Pod를 노드의 기본 네트워크 인터페이스와 다른 서브넷에 배포하는 방법을 단계별로 살펴봅니다.

출처: 문서

본문

튜토리얼 시작 전에 다음을 완료하세요

다음 항목을 시작 전에 확인합니다.

  1. 고려 사항(considerations)을 검토합니다.
  2. Amazon VPC CNI 플러그인 for Kubernetes가 보조 네트워크 인터페이스를 만들고 IP 주소를 Pod에 할당하는 방법을 이해합니다. 자세한 내용은 GitHub의 ENI Allocation을 참조하세요.
  3. AWS Command Line Interface(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 Command Line Interface User Guide에서 Installing 및 aws configure로 빠른 구성을 참조하세요. AWS CloudShell에 설치된 AWS CLI 버전도 최신 버전보다 뒤처져 있을 수 있습니다. 업데이트하려면 AWS CloudShell User Guide에서 홈 디렉터리에 AWS CLI 설치를 참조하세요.
  4. 기기나 AWS CloudShell에 kubectl 명령줄 도구가 설치되어 있습니다. kubectl을 설치하거나 업그레이드하려면 kubectl 및 eksctl 설정을 참조하세요.
  5. 이 주제의 단계는 Bash 셸에서 완료할 것을 권장합니다. Bash 셸을 사용하지 않으면 줄 연속 문자나 변수의 설정·사용 방식 같은 일부 스크립트 명령을 셸에 맞게 조정해야 합니다. 또한 셸의 따옴표와 이스케이프 규칙이 다를 수 있습니다. 자세한 내용은 AWS Command Line Interface User Guide에서 문자열과 함께 따옴표 사용을 참조하세요.

이 튜토리얼에서는 특별히 교체하라고 표시된 곳을 제외하고 예시 값을 사용할 것을 권장합니다. 프로덕션 클러스터에서 단계를 완료할 때는 예시 값을 원하는 값으로 바꿀 수 있습니다. 모든 단계를 같은 터미널에서 완료할 것을 권장합니다. 변수가 여러 단계에 걸쳐 설정되고 사용되므로 다른 터미널에는 존재하지 않기 때문입니다.

이 주제의 명령은 AWS CLI 예제 사용에 나열된 규칙에 따라 형식이 지정되어 있습니다. 사용 중인 AWS CLI 프로필에 정의된 기본 AWS 리전과 다른 AWS 리전의 리소스에 대해 명령줄에서 명령을 실행하는 경우 명령에 --region us-west-2를 추가하고 us-west-2를 사용자의 AWS 리전으로 바꿔야 합니다.

프로덕션 클러스터에 사용자 지정 네트워킹을 배포하려면 2단계: VPC 구성으로 건너뛰세요.

1단계: 테스트 VPC와 클러스터 생성

다음 절차는 테스트 VPC와 클러스터를 만들고 해당 클러스터에 사용자 지정 네트워킹을 구성하는 데 도움이 됩니다. 테스트 클러스터는 프로덕션 워크로드에 사용하지 않는 것이 좋습니다. 프로덕션 클러스터에서 사용할 수 있는 여러 무관한 기능이 이 주제에서 다루어지지 않기 때문입니다. 자세한 내용은 Amazon EKS 클러스터 생성을 참조하세요.

다음 명령을 실행해 account_id 변수를 정의합니다.

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

VPC를 만듭니다. 테스트 시스템에 배포하는 경우 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

AWS CloudFormation 스택을 만드는 데 몇 분이 걸릴 수 있습니다. 스택의 배포 상태를 확인하려면 다음 명령을 실행합니다.

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

명령 출력이 CREATE_COMPLETE가 될 때까지 다음 단계로 진행하지 마세요.

템플릿이 만든 프라이빗 서브넷 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)

이전 단계에서 가져온 서브넷의 가용 영역(Availability Zone)으로 변수를 정의합니다.

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)

클러스터 IAM 역할을 만듭니다. 다음 명령을 실행해 IAM 신뢰 정책 JSON 파일을 만듭니다.

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

Amazon EKS 클러스터 IAM 역할을 만듭니다. 필요한 경우 eks-cluster-role-trust-policy.json 앞에 이전 단계에서 파일을 저장한 경로를 붙입니다. 이 명령은 이전 단계에서 만든 신뢰 정책을 역할에 연결합니다. IAM 역할을 만들려면 역할을 만드는 IAM 보안 주체(principal)에 iam:CreateRole 작업(권한)이 할당되어 있어야 합니다.

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

AmazonEKSClusterPolicy라는 Amazon EKS 관리형 정책을 역할에 연결합니다. IAM 정책을 IAM 보안 주체에 연결하려면 정책을 연결하는 보안 주체에 iam:AttachUserPolicy 또는 iam:AttachRolePolicy 중 하나의 IAM 작업(권한)이 할당되어 있어야 합니다.

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

Amazon EKS 클러스터를 만들고 기기가 클러스터와 통신하도록 구성합니다.

클러스터를 만듭니다.

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 클러스터를 만들 수 있는 충분한 용량이 없다는 오류가 발생할 수 있습니다. 이 경우 오류 출력에 새 클러스터를 지원할 수 있는 가용 영역이 포함됩니다. 계정에서 지원되는 가용 영역에 있는 서브넷을 두 개 이상 사용해 클러스터 만들기를 다시 시도하세요. 자세한 내용은 용량 부족(Insufficient capacity)을 참조하세요.

클러스터를 만드는 데 몇 분이 걸릴 수 있습니다. 클러스터의 배포 상태를 확인하려면 다음 명령을 실행합니다.

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

명령 출력이 "ACTIVE"가 될 때까지 다음 단계로 진행하지 마세요.

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

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

2단계: VPC 구성

이 튜토리얼은 1단계: 테스트 VPC와 클러스터 생성에서 만든 VPC가 필요합니다. 프로덕션 클러스터의 경우 모든 예시 값을 사용자의 값으로 바꿔 VPC에 맞게 단계를 조정하세요.

현재 설치된 Amazon VPC CNI 플러그인 for Kubernetes가 최신 버전인지 확인합니다. Amazon EKS 추가 기능 유형의 최신 버전을 확인하고 버전을 업데이트하려면 Amazon EKS 추가 기능 업데이트를 참조하세요. self-managed 추가 기능 유형의 최신 버전을 확인하고 업데이트하려면 Amazon VPC CNI로 Pod에 IP 할당을 참조하세요.

클러스터 VPC의 ID를 가져와 이후 단계에서 사용할 변수에 저장합니다.

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

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

현재 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  |
+-----------------+--------------+

VPC에 추가 CIDR 블록을 연결합니다. 다음 명령에서 CIDR 블록 값을 바꿉니다. 자세한 내용은 Amazon VPC User Guide에서 VPC에 추가 IPv4 CIDR 블록 연결을 참조하세요.

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

새 블록이 연결되었는지 확인합니다.

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가 될 때까지 다음 단계로 진행하지 마세요.

기존 서브넷이 있는 각 가용 영역에 원하는 만큼 서브넷을 만듭니다. 이전 단계에서 VPC에 연결한 CIDR 블록 안에 있는 CIDR 블록을 지정합니다.

새 서브넷을 만듭니다. 다음 명령에서 CIDR 블록 값을 바꿉니다. 서브넷은 기존 서브넷과는 다른 VPC CIDR 블록에 만들되, 기존 서브넷과 같은 가용 영역에 있어야 합니다. 이 예시에서는 현재 프라이빗 서브넷이 있는 각 가용 영역의 새 CIDR 블록에 서브넷 하나씩을 만듭니다. 만들어진 서브넷의 ID는 이후 단계에서 사용할 변수에 저장됩니다. Name 값은 이전 단계에서 Amazon EKS VPC 템플릿을 사용해 만든 서브넷에 할당된 값과 일치합니다. Name은 필수가 아닙니다. 다른 이름을 사용해도 됩니다.

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의 메인 라우팅 테이블에 암시적으로 연결됩니다. 이 라우팅 테이블은 VPC에 배포된 모든 리소스 간의 통신을 허용합니다. 그러나 VPC에 연결된 CIDR 블록 밖의 IP 주소를 가진 리소스와의 통신은 허용하지 않습니다. 이 동작을 변경하려면 자체 라우팅 테이블을 서브넷에 연결할 수 있습니다. 자세한 내용은 Amazon VPC User Guide의 서브넷 라우팅 테이블을 참조하세요.

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 리소스 구성

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

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

클러스터 보안 그룹의 ID를 가져와 다음 단계에서 사용할 변수에 저장합니다. Amazon EKS는 클러스터를 만들 때 이 보안 그룹을 자동으로 만듭니다.

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

Pod를 배포하려는 각 서브넷에 ENIConfig 사용자 지정 리소스를 만듭니다. 각 네트워크 인터페이스 구성에 대해 고유한 파일을 만듭니다.

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

cat >$az_1.yaml $az_2.yaml

$cluster_security_group_id를 각 ENIConfig에 사용할 기존 보안 그룹의 ID로 바꿉니다.

가능하면 ENIConfig를 사용할 가용 영역과 같은 이름으로 지정할 것을 권장합니다. 다양한 이유로 ENIConfig 이름이 가용 영역 이름과 달라야 할 수도 있습니다. 예를 들어 같은 가용 영역에 서브넷이 둘 이상 있고 둘 다 사용자 지정 네트워킹에 사용하려면 같은 가용 영역에 ENIConfig가 여러 개 필요합니다. 각 ENIConfig는 고유한 이름이 필요하므로 가용 영역 이름으로 ENIConfig를 둘 이상 지정할 수는 없습니다.

ENIConfig 이름이 모두 가용 영역 이름과 같지 않다면 이전 명령에서 $az_1과 $az_2를 사용자 이름으로 바꾸고 이 튜토리얼의 뒷부분에서 노드에 ENIConfig를 주석(annotate)으로 추가하세요.

참고

프로덕션 클러스터에 유효한 보안 그룹을 지정하지 않고 다음을 사용하는 경우:

  • Amazon VPC CNI 플러그인 for Kubernetes 버전 1.8.0 이상: 노드의 기본 탄력적 네트워크 인터페이스에 연결된 보안 그룹이 사용됩니다.
  • Amazon VPC CNI 플러그인 for Kubernetes 버전 1.8.0 미만: VPC의 기본 보안 그룹이 보조 네트워크 인터페이스에 할당됩니다.

중요

AWS_VPC_K8S_CNI_EXTERNALSNAT=false는 Amazon VPC CNI 플러그인 for Kubernetes 구성의 기본 설정입니다. 기본 설정을 사용하면 VPC에 연결된 CIDR 블록 안에 없는 IP 주소를 대상으로 하는 트래픽은 노드 기본 네트워크 인터페이스의 보안 그룹과 서브넷을 사용합니다. 보조 네트워크 인터페이스를 만드는 데 사용되는 ENIConfig에 정의된 서브넷과 보안 그룹은 이 트래픽에 사용되지 않습니다. 이 설정에 대한 자세한 내용은 Pod에 대한 아웃바운드 인터넷 액세스 활성화를 참조하세요.

Pod용 보안 그룹도 사용한다면 SecurityGroupPolicy에 지정된 보안 그룹이 ENIConfig에 지정된 보안 그룹 대신 사용됩니다. 자세한 내용은 개별 Pod에 보안 그룹 할당을 참조하세요.

만든 각 사용자 지정 리소스 파일을 다음 명령으로 클러스터에 적용합니다.

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

ENIConfig가 만들어졌는지 확인합니다.

kubectl get ENIConfigs

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

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

프로덕션 클러스터에서 사용자 지정 네트워킹을 활성화하고 ENIConfig 이름을 사용할 가용 영역과 다르게 지정했다면 다음 단계로 건너뛰어 Amazon EC2 노드를 배포하세요.

Kubernetes가 가용 영역의 ENIConfig를 클러스터에 새로 만들어진 Amazon EC2 노드에 자동으로 적용하도록 활성화합니다.

이 튜토리얼의 테스트 클러스터에서는 다음 단계로 건너뜁니다.

프로덕션 클러스터의 경우 aws-node DaemonSet의 컨테이너 사양에 ENI_CONFIG_ANNOTATION_DEF 환경 변수 키 k8s.amazonaws.com/eniConfig의 주석(annotation)이 있는지 확인합니다.

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

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

aws-node DaemonSet을 업데이트하여 가용 영역의 ENIConfig를 클러스터에 새로 만들어진 Amazon EC2 노드에 자동으로 적용합니다.

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

4단계: Amazon EC2 노드 배포

노드 IAM 역할을 만듭니다. 다음 명령을 실행해 IAM 신뢰 정책 JSON 파일을 만듭니다.

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

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)

필수 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

중요

이 튜토리얼에서는 간단함을 위해 AmazonEKS_CNI_Policy 정책을 노드 IAM 역할에 연결합니다. 그러나 프로덕션 클러스터에서는 이 정책을 Amazon VPC CNI 플러그인 for Kubernetes에만 사용되는 별도의 IAM 역할에 연결할 것을 권장합니다. 자세한 내용은 IRSA를 사용하도록 Amazon VPC CNI 플러그인 구성(Configure Amazon VPC CNI plugin to use IRSA)을 참조하세요.

다음 유형 중 하나의 노드 그룹을 만듭니다. 배포하려는 인스턴스 유형을 결정하려면 최적의 Amazon EC2 노드 인스턴스 유형 선택을 참조하세요. 이 튜토리얼에서는 관리형(Managed), 시작 템플릿 없이 또는 AMI ID를 지정하지 않은 시작 템플릿 사용 옵션을 완료하세요. 노드 그룹을 프로덕션 워크로드에 사용하려면 노드 그룹을 배포하기 전에 관리형 노드 그룹과 self-managed 노드 그룹의 모든 옵션을 숙지할 것을 권장합니다.

관리형(Managed)

다음 옵션 중 하나로 노드 그룹을 배포합니다.

시작 템플릿 없이 또는 AMI ID를 지정하지 않은 시작 템플릿 사용 – 다음 명령을 실행합니다. 이 튜토리얼에서는 예시 값을 사용하세요. 프로덕션 노드 그룹에서는 모든 예시 값을 사용자의 값으로 바꿉니다. 노드 그룹 이름은 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를 지정한 시작 템플릿 사용

인스턴스 유형에 따른 노드의 최대 Pod 수를 확인합니다. 자세한 내용은 maxPods가 결정되는 방식을 참조하세요. 다음 단계에서 사용할 값을 기록해 둡니다.

시작 템플릿에서 Amazon EKS 최적화 AMI ID 또는 Amazon EKS 최적화 AMI를 기반으로 만든 사용자 지정 AMI를 지정한 다음, 시작 템플릿으로 노드 그룹을 배포하고 시작 템플릿에 다음 사용자 데이터를 제공합니다. 이 사용자 데이터는 NodeConfig 사양에 인수를 전달합니다. NodeConfig에 대한 자세한 내용은 NodeConfig API 참조를 확인하세요. 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를 만들었다면 구성을 직접 직접 만들어야 합니다.

Self-managed

인스턴스 유형에 따른 노드의 최대 Pod 수를 확인합니다. 자세한 내용은 maxPods가 결정되는 방식을 참조하세요. 다음 단계에서 사용할 값을 기록해 둡니다.

self-managed Amazon Linux 노드 생성의 지침에 따라 노드 그룹을 배포합니다.

참고

프로덕션 클러스터의 노드가 훨씬 더 많은 수의 Pod를 지원하길 원한다면 프리픽스 위임(prefix delegation)을 활성화할 수 있습니다. 예를 들어 m5.large 인스턴스 유형에는 110이 반환됩니다. 이 기능을 활성화하는 방법은 프리픽스로 Amazon EKS 노드에 더 많은 IP 주소 할당을 참조하세요. 이 기능은 사용자 지정 네트워킹과 함께 사용할 수 있습니다.

노드 그룹을 만드는 데 몇 분이 걸릴 수 있습니다. 다음 명령으로 관리형 노드 그룹 생성 상태를 확인할 수 있습니다.

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

반환된 출력이 ACTIVE가 될 때까지 다음 단계로 진행하지 마세요.

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

프로덕션 클러스터의 경우 ENIConfig 이름을 사용할 가용 영역과 다르게 지정했다면 노드에 사용할 ENIConfig 이름으로 노드에 주석을 추가해야 합니다. 각 가용 영역에 서브넷이 하나만 있고 ENIConfig 이름을 가용 영역 이름과 같게 지정했다면 이 단계는 필요하지 않습니다. 이전 단계에서 Amazon VPC CNI 플러그인 for Kubernetes가 올바른 ENIConfig를 노드에 자동으로 연결하도록 활성화했기 때문입니다.

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

kubectl get nodes

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

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

각 노드가 어느 가용 영역에 있는지 확인합니다. 이전 단계에서 반환된 각 노드에 대해 다음 명령을 실행하고, 이전 출력을 기준으로 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"
    }
]

각 노드에 서브넷 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

사용자 지정 네트워킹 기능으로 전환하기 전에 프로덕션 클러스터에 실행 중인 Pod가 있는 노드가 있었다면 다음 작업을 완료하세요.

  1. 사용자 지정 네트워킹 기능을 사용하는 사용 가능한 노드가 있는지 확인합니다.
  2. Pod를 정상적으로 종료하도록 노드를 cordon하고 drain합니다. 자세한 내용은 Kubernetes 문서의 노드 안전하게 drain(Safely Drain a Node)을 참조하세요.
  3. 노드를 종료합니다. 노드가 기존 관리형 노드 그룹에 있다면 노드 그룹을 삭제할 수 있습니다. 다음 명령을 실행합니다.
aws eks delete-nodegroup --cluster-name my-custom-networking-cluster --nodegroup-name my-nodegroup

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

Pod가 이전 단계에서 만든 서브넷 중 하나에 연결된 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
kube-system   aws-node-k96wp             1/1     Running   0          7m15s   192.168.0.126   ip-192-168-0-126.us-west-2.compute.internal
kube-system   coredns-657694c6f4-smcgr   1/1     Running   0          56m     192.168.1.23    ip-192-168-0-92.us-west-2.compute.internal
kube-system   coredns-657694c6f4-stwv9   1/1     Running   0          56m     192.168.1.28    ip-192-168-0-92.us-west-2.compute.internal
kube-system   kube-proxy-jgshq           1/1     Running   0          7m19s   192.168.0.92    ip-192-168-0-92.us-west-2.compute.internal
kube-system   kube-proxy-wx9vk           1/1     Running   0          7m15s   192.168.0.126   ip-192-168-0-126.us-west-2.compute.internal

coredns Pod가 VPC에 추가했던 192.168.1.0 CIDR 블록의 IP 주소를 할당받는 것을 확인할 수 있습니다. 사용자 지정 네트워킹이 없었다면 원래 VPC에 연결된 유일한 CIDR 블록이었기 때문에 192.168.0.0 CIDR 블록의 주소를 할당받았을 것입니다.

Pod의 spec에 hostNetwork=true가 있으면 노드의 기본 IP 주소가 할당됩니다. 추가한 서브넷의 주소는 할당되지 않습니다. 기본적으로 이 값은 false입니다. 클러스터에서 실행되는 kube-proxy와 Amazon VPC CNI 플러그인 for Kubernetes(aws-node) Pod에는 이 값이 true로 설정됩니다. 그래서 이전 출력에서 kube-proxy와 플러그인의 aws-node Pod에 192.168.1.x 주소가 할당되지 않은 것입니다. Pod의 hostNetwork 설정에 대한 자세한 내용은 Kubernetes API 참조의 PodSpec v1 core를 참조하세요.

5단계: 튜토리얼 리소스 삭제

튜토리얼을 마친 뒤 만든 리소스를 삭제할 것을 권장합니다. 그런 다음 프로덕션 클러스터에 사용자 지정 네트워킹을 활성화하도록 단계를 조정할 수 있습니다.

테스트용으로 만든 노드 그룹이라면 삭제합니다.

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

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.

테스트용으로 만든 노드 그룹이라면 노드 IAM 역할을 삭제합니다.

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

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

역할을 삭제합니다.

aws iam delete-role --role-name myCustomNetworkingNodeRole

클러스터를 삭제합니다.

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.

클러스터 IAM 역할을 삭제합니다. 역할에서 정책을 분리합니다.

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

역할을 삭제합니다.

aws iam delete-role --role-name myCustomNetworkingAmazonEKSClusterRole

이전 단계에서 만든 서브넷을 삭제합니다.

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

만든 VPC를 삭제합니다.

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

더 알아보기 (Learn more)