Amazon EKS에서 여러 CIDR 범위를 사용하려면 어떻게 해야 하나요?

최종 업데이트 날짜: 2021년 12월 10일

Amazon Elastic Kubernetes Service(Amazon EKS)에서 여러 CIDR 범위를 사용하여 포드 관련 문제를 해결하려고 합니다. 예를 들어 Amazon Virtual Private Cloud(Amazon VPC)에 다른 CIDR 범위가 추가된 포드를 실행하려면 어떻게 해야 합니까? 또한 서브넷에 IP 주소가 부족할 때 서브넷에 IP 주소를 추가하려면 어떻게 해야 합니까? 마지막으로 작업자 노드에서 실행되는 포드의 IP 범위가 서로 다른지 확인하려면 어떻게 해야 합니까?

간략한 설명

문제 해결 섹션의 단계를 완료하기 전에 다음 항목이 있는지 확인합니다.

  • 실행 중인 Amazon EKS 클러스터
  • AWS 명령줄 인터페이스(AWS CLI)의 버전(1.16.284 이전)에 액세스
  • Amazon VPC를 관리하기 위한 AWS Identity and Access Management(IAM) 권한
  • 사용자 지정 리소스를 생성하고 DaemonsSet를 편집할 수 있는 권한이 있는 kubectl
  • 시스템에 설치된 jq 웹 사이트의 jq 버전
  • Bash 셸을 사용하는 Unix 기반 시스템

다음 사항에 유의하세요.

  • 다른 CIDR 범위에서 포드를 실행할 경우 Amazon EKS에서 관리하는 포드에 대해 더 많은 IP 주소를 사용할 수 있습니다. 또한 네트워킹 아키텍처의 유연성을 개선할 수 있습니다. 포드는 두 가지 조건에서 VPC의 RFC 1918 IP 주소를 사용하지 않습니다. 첫 번째 조건은 100.64.0.0/10198.19.0.0/16 범위에서 VPC에 보조 CIDR 블록을 추가하는 것입니다. 두 번째 조건은 CNI 사용자 지정 네트워킹을 사용하는 것입니다.
  • 통신사급 네트워크 주소 변환(NAT)을 사용하는 시나리오에서 100.64.0.0/10은 프라이빗 네트워크 범위입니다. 이 프라이빗 네트워크 범위는 서비스 공급자와 가입자 간의 통신을 위한 공유 주소 공간에서 사용됩니다. 포드가 인터넷과 통신하려면 라우팅 테이블에 NAT 게이트웨이가 구성되어 있어야 합니다. Daemonsets는 AWS Fargate 클러스터에서 지원되지 않습니다. Fargate 프로파일에 보조 CIDR 범위를 추가하려면 VPC의 보조 CIDR 블록의 서브넷을 사용합니다. 그런 다음 Fargate 프로파일에 서브넷을 추가하기 전에 새 서브넷에 태그를 지정합니다.

중요: 특정 상황에서 Amazon EKS는 클러스터가 생성된 후 VPC에 추가된 추가 CIDR 블록에서 서브넷에서 시작된 노드와 통신할 수 없습니다. 기존 클러스터에 CIDR 블록을 추가하여 발생하는 업데이트된 범위는 표시되는 데 5시간까지 걸릴 수 있습니다.

해결 방법

참고: AWS CLI 명령을 실행할 때 오류가 발생하는 경우 최신 버전의 AWS CLI를 사용하고 있는지 확인하세요.

다음 해결 방법에서는, 우선 VPC를 설정합니다. 그런 다음, 새 CIDR 범위를 사용하도록 CNI 플러그인 구성

CIDR 범위를 추가하여 VPC 네트워크 확장

1.    VPC를 찾습니다.

VPC에 태그가 있는 경우 다음 명령을 실행하여 VPC를 찾습니다.

VPC_ID=$(aws ec2 describe-vpcs --filters Name=tag:Name,Values=yourVPCName | jq -r '.Vpcs[].VpcId')

VPC에 태그가 없는 경우 다음 명령을 실행하여 AWS 리전에 모든 VPC를 나열합니다.

aws ec2 describe-vpcs --filters  | jq -r '.Vpcs[].VpcId'

2.    VPC_ID 변수에 VPC를 연결하려면 다음 명령을 실행합니다.

export VPC_ID=vpc-xxxxxxxxxxxx

3.    VPC에 대해 100.64.0.0/16 범위의 CIDR 블록을 연결하려면 다음 명령을 실행합니다.

aws ec2 associate-vpc-cidr-block --vpc-id $VPC_ID --cidr-block 100.64.0.0/16

새 CIDR 범위를 사용하여 서브넷 생성

1.    AWS 리전의 모든 가용 영역을 나열하려면 다음 명령을 실행합니다.

aws ec2 describe-availability-zones --region us-east-1 --query 'AvailabilityZones[*].ZoneName'

참고: us-east-1을 사용자의 AWS 리전으로 바꿉니다.

2.    서브넷을 추가할 가용 영역을 선택한 다음 해당 가용 영역을 변수에 할당합니다. 예를 들면 다음과 같습니다.

export AZ1=us-east-1a
export AZ2=us-east-1b
export AZ3=us-east-1c

참고: 변수를 더 생성하여 가용 영역을 추가할 수 있습니다.

3.    VPC에서 새 CIDR 범위를 사용하여 새 서브넷을 생성하려면 다음 명령을 실행합니다.

CUST_SNET1=$(aws ec2 create-subnet --cidr-block 100.64.0.0/19 --vpc-id $VPC_ID --availability-zone $AZ1 | jq -r .Subnet.SubnetId)
CUST_SNET2=$(aws ec2 create-subnet --cidr-block 100.64.32.0/19 --vpc-id $VPC_ID --availability-zone $AZ2 | jq -r .Subnet.SubnetId)
CUST_SNET3=$(aws ec2 create-subnet --cidr-block 100.64.64.0/19 --vpc-id $VPC_ID --availability-zone $AZ3 | jq -r .Subnet.SubnetId)

새 서브넷에 태그 지정

Kubernetes 1.18 이전 버전에서 실행되는 클러스터의 경우, 모든 서브넷에 태그를 지정해야 Amazon EKS가 서브넷을 검색할 수 있습니다.

참고: Amazon EKS는 Kubernetes 버전 1.19부터는 kubernetes.io 태그 없이도 서브넷 자동 검색을 지원합니다. 자세한 내용은 Kubernetes GitHub 사이트의 변경 로그를 참조하세요.

1.    (선택 사항) 키–값 페어를 설정하여 서브넷에 이름 태그를 추가합니다. 예를 들면 다음과 같습니다.

aws ec2 create-tags --resources $CUST_SNET1 --tags Key=Name,Value=SubnetA
aws ec2 create-tags --resources $CUST_SNET2 --tags Key=Name,Value=SubnetB
aws ec2 create-tags --resources $CUST_SNET3 --tags Key=Name,Value=SubnetC

2.    Kubernetes 1.18 이하 버전에서 실행되는 클러스터의 경우, Amazon EKS에서 검색할 수 있도록 서브넷에 태그를 지정합니다. 예를 들면 다음과 같습니다.

aws ec2 create-tags --resources $CUST_SNET1 --tags Key=kubernetes.io/cluster/yourClusterName,Value=shared
aws ec2 create-tags --resources $CUST_SNET2 --tags Key=kubernetes.io/cluster/yourClusterName,Value=shared
aws ec2 create-tags --resources $CUST_SNET3 --tags Key=kubernetes.io/cluster/yourClusterName,Value=shared

참고: yourClusterName을 Amazon EKS 클러스터 이름으로 바꾸세요.

팁: Elastic Load Balancing을 사용하려 하는 경우, 추가 태그를 더하는 것이 좋습니다.

새 서브넷을 라우팅 테이블에 연결

1.    VPC에서 전체 라우팅 테이블을 나열하려면 다음 명령을 실행합니다.

aws ec2 describe-route-tables --filters Name=vpc-id,Values=$VPC_ID |jq -r '.RouteTables[].RouteTableId'

2.    서브넷과 연결하려는 라우팅 테이블에 대해 다음 명령을 실행하여 변수로 내보냅니다. 그런 다음 rtb-xxxxxxxxx를 1단계의 값으로 바꿉니다.

export RTASSOC_ID=rtb-xxxxxxxxx

3.    라우팅 테이블을 모든 새 서브넷에 연결합니다. 예를 들면 다음과 같습니다.

aws ec2 associate-route-table --route-table-id $RTASSOC_ID --subnet-id $CUST_SNET1
aws ec2 associate-route-table --route-table-id $RTASSOC_ID --subnet-id $CUST_SNET2
aws ec2 associate-route-table --route-table-id $RTASSOC_ID --subnet-id $CUST_SNET3

자세한 정보는 라우팅을 참조하세요.

새 CIDR 범위를 사용하도록 CNI 플러그인 구성

1.    최신 버전의 CNI 플러그인이 있는지 확인하려면 다음 명령을 실행합니다.

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

CNI 플러그인 버전이 1.5.3 이하인 경우 다음 명령을 실행하여 최신 버전으로 업데이트합니다.

kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/config/v1.5/aws-k8s-cni.yaml

2.    CNI 플러그인에 대한 사용자 지정 네트워크 구성을 활성화하려면 다음 명령을 실행합니다.

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

3.    작업자 노드를 식별하기 위한 ENIConfig 레이블을 추가하려면 다음 명령을 실행합니다.

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

4.    ENIConfig 사용자 지정 리소스 정의를 설치하려면(Kubernetes 웹사이트에서) 다음 명령을 실행합니다.

cat << EOF | kubectl apply -f -
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: eniconfigs.crd.k8s.amazonaws.com
spec:
  scope: Cluster
  group: crd.k8s.amazonaws.com
  version: v1alpha1
  names:
    plural: eniconfigs
    singular: eniconfig
    kind: ENIConfig
EOF

5.    모든 서브넷 및 가용 영역에 대해 ENIConfig 사용자 지정 리소스를 생성하려면 다음 명령을 실행합니다.

cat <<EOF  | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata:
 name: $AZ1
spec:
  subnet: $CUST_SNET1
EOF

cat <<EOF | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata:
 name: $AZ2
spec:
  subnet: $CUST_SNET2
EOF

cat <<EOF | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata:
 name: $AZ3
spec:
  subnet: $CUST_SNET3
EOF

참고: ENIConfig는 작업자 노드의 가용 영역과 일치해야 합니다.

6.    새 작업자 노드를 시작합니다. 참고: 이 단계에서 CNI 플러그인(ipamd)이 새 작업자 노드에서 새 CIDR 범위의 IP 주소를 할당할 수 있습니다.

사용자 지정 네트워킹을 사용하는 경우 기본 네트워크 인터페이스는 포드 배치에 사용되지 않습니다. 이 시나리오에서는 우선 다음 수식을 사용하여 max-pods를 업데이트해야 합니다.

maxPods = (number of interfaces - 1) * (max IPv4 addresses per interface - 1) + 2
  • 자체 관리형 노드 그룹의 경우 자체 관리형 Amazon Linux 노드 시작의 지침에 따라 노드 그룹을 배포할 수 있습니다. 배포한 ENIConfig 리소스에서 사용한 서브넷은 지정하지 마십시오. 대신 BootstrapArguments 파라미터에 다음 텍스트를 지정합니다.
--use-max-pods false --kubelet-extra-args '--max-pods=<20>'
  • 시작 템플릿이 없거나 AMI ID가 지정되지 않은 시작 템플릿을 사용하여 관리형 노드 그룹을 생성하는 경우 관리형 노드 그룹은 Amazon EKS 권장 최대 포드 값을 자동으로 계산합니다. 관리형 노드 그룹 생성 단계를 따르거나 AWS EKS CLI를 사용하여 관리형 노드 그룹을 생성
aws eks create-nodegroup --cluster-name <sample-cluster-name> --nodegroup-name <sample-nodegroup-name> --subnets <subnet-123 subnet-456> --node-role <arn:aws:iam::123456789012:role/SampleNodeRole>

참고: 서브넷 필드의 경우 ENIConfig 리소스에서 지정한 서브넷을 지정하지 마십시오. 필요에 따라 추가 옵션을 지정할 수 있습니다. • 지정된 AMI ID로 시작 템플릿을 사용하여 관리형 노드 그룹을 생성하는 경우 시작 템플릿의 사용자 데이터로 ‘--max-pods= ’ 추가 인수를 제공합니다. 시작 템플릿에서 Amazon EKS 최적화 AMI ID 또는 Amazon EKS 최적화 AMI를 기반으로 구축된 사용자 지정 AMI를 지정합니다. 그런 다음 시작 템플릿을 사용하여 노드 그룹을 배포하고 시작 템플릿에 다음 사용자 데이터를 제공합니다.

  • 지정된 AMI ID를 가진 시작 템플릿을 사용하여 관리형 노드 그룹을 생성하는 경우 시작 템플릿의 사용자 데이터로 ‘--max-pods= ’ 추가 인수를 제공합니다. 시작 템플릿에서 Amazon EKS 최적화 AMI ID 또는 Amazon EKS 최적화 AMI를 기반으로 구축된 사용자 지정 AMI를 지정합니다. 그런 다음 시작 템플릿을 사용하여 노드 그룹을 배포하고 시작 템플릿에 다음 사용자 데이터를 제공합니다.
#!/bin/bash
/etc/eks/bootstrap.sh <my-cluster-name> --kubelet-extra-args <'--max-pods=20'>

7.    노드 그룹을 생성한 후 서브넷의 보안 그룹을 기록하고 보안 그룹을 연결된 ENIConfig에 적용합니다.

다음 예시에서는 sg-xxxxxxxxxxxx를 해당 보안 그룹으로 바꿉니다.

cat <<EOF  | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata:
 name: $AZ1
spec:
  securityGroups: 
    - sg-xxxxxxxxxxxx
  subnet: $CUST_SNET1
EOF

cat <<EOF | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata:
 name: $AZ2
spec:
  securityGroups: 
    - sg-xxxxxxxxxxxx
  subnet: $CUST_SNET2
EOF

cat <<EOF | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata:
 name: $AZ3
spec:
  securityGroups: 
    - sg-xxxxxxxxxxxx
  subnet: $CUST_SNET3
EOF

8.    이전 작업자 노드를 종료한 다음 새 배포를 시작하여 구성을 테스트합니다.

kubectl create deployment nginx-test --image=nginx --replicas=10
kubectl get pods -o wide --selector=app=nginx-test

10개의 새 포드가 추가되고 새 CIDR 범위가 새 작업자 노드에서 예약됩니다.


이 문서가 도움이 되었나요?


결제 또는 기술 지원이 필요하세요?