Amazon EKS IPv6 클러스터 및 관리형 Amazon Linux 노드 배포하기

Amazon EKS IPv6 클러스터 및 관리형 Amazon Linux 노드 배포하기 (Deploying an Amazon EKS IPv6 cluster and managed Amazon Linux nodes)

이 튜토리얼에서는 IPv6 Amazon VPC, IPv6 패밀리의 Amazon EKS 클러스터, Amazon EC2 Amazon Linux 노드가 있는 관리형 노드 그룹을 배포해요. IPv6 클러스터에는 Amazon EC2 Windows 노드를 배포할 수 없어요. 또한 클러스터에 Fargate 노드를 배포할 수 있지만, 단순화를 위해 이 주제에서는 해당 지침을 제공하지 않아요.

출처: 문서

본문

사전 요구 사항 (Prerequisites)

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

Amazon EKS 클러스터를 만들고 관리하는 데 필요한 다음 도구와 리소스를 설치하고 구성해요.

모든 설정에 익숙해지고 요구사항을 충족하는 설정으로 클러스터를 배포하는 것을 권장해요. 자세한 내용은 Amazon EKS 클러스터 생성하기, 관리형 노드 그룹으로 노드 수명 주기 단순화하기, 이 주제의 고려 사항을 참고하세요. 일부 설정은 클러스터를 만들 때만 활성화할 수 있어요.

  • 기기 또는 AWS CloudShell에 kubectl 명령줄 도구가 설치되어 있어야 해요. 버전은 클러스터의 Kubernetes 버전과 같거나 최대 한 마이너 버전 앞뒤일 수 있어요. 예를 들어 클러스터 버전이 1.29라면 kubectl 버전 1.28, 1.29, 1.30을 사용할 수 있어요. kubectl을 설치하거나 업그레이드하려면 kubectl 및 eksctl 설정하기를 참고하세요.
  • 사용 중인 IAM 보안 주체는 Amazon EKS IAM 역할, service linked 역할, AWS CloudFormation, VPC 및 관련 리소스로 작업할 수 있는 권한이 있어야 해요. 자세한 내용은 IAM 사용 설명서의 작업 및 서비스 연결 역할 사용하기를 참고하세요.
  • eksctl을 사용한다면 컴퓨터에 버전 0.215.0 이상을 설치하세요. 설치하거나 업데이트하려면 eksctl 문서의 Installation(설치)을 참고하세요.
  • 기기 또는 AWS CloudShell에 AWS CLI 버전 2.12.3 이상 또는 버전 1.27.160 이상이 설치되고 구성되어 있어야 해요. 현재 버전을 확인하려면 aws --version | cut -d / -f2 | cut -d ' ' -f1을 사용하세요. yum, apt-get, macOS용 Homebrew 같은 패키지 관리자는 최신 AWS CLI보다 몇 버전 뒤처진 경우가 많아요. 최신 버전을 설치하려면 AWS Command Line Interface 사용 설명서의 aws configure로 설치 및 빠른 구성하기를 참고하세요. AWS CloudShell에 설치된 AWS CLI 버전도 최신 버전보다 몇 버전 뒤처질 수 있어요. 업데이트하려면 AWS CloudShell 사용 설명서의 홈 디렉터리에 AWS CLI 설치하기를 참고하세요. AWS CloudShell을 사용한다면 AWS CLI 버전 2.12.3 이상 또는 1.27.160 이상을 설치해야 할 수도 있는데, AWS CloudShell에 기본 설치된 AWS CLI 버전이 이전 버전일 수 있기 때문이에요.

eksctl 또는 CLI로 IPv6 클러스터를 배포할 수 있어요.

eksctl로 IPv6 클러스터 배포

ipv6-cluster.yaml 파일을 만들어요. 다음 명령을 복사하고 필요한 대로 수정한 후 실행하세요.

  • my-cluster를 클러스터 이름으로 바꾸세요. 이름은 영숫자 문자(대소문자 구분)와 하이픈만 포함할 수 있어요. 영숫자 문자로 시작해야 하며 100자를 초과할 수 없어요. 이름은 클러스터를 만드는 AWS 리전과 AWS 계정 내에서 고유해야 해요.
  • region-code를 Amazon EKS가 지원하는 모든 AWS 리전으로 바꾸세요. AWS 리전 목록은 AWS 일반 참조의 Amazon EKS 엔드포인트 및 할당량을 참고하세요.
  • version의 값을 클러스터 버전으로 설정하세요. 자세한 내용은 Amazon EKS 지원 버전을 참고하세요.
  • my-nodegroup을 노드 그룹 이름으로 바꾸세요. 노드 그룹 이름은 63자를 초과할 수 없어요. 문자 또는 숫자로 시작해야 하며 나머지 문자에는 하이픈과 밑줄도 포함할 수 있어요.
  • t3.medium을 모든 AWS Nitro System 인스턴스 유형으로 바꾸세요.
cat >ipv6-cluster.yaml
...

(eksctl yarn 파일의 실제 내용으로 채워짐 — cat을 통해 생성됨)

클러스터가 생성된 후 다음을 수행해요.

  1. 기본 Pod가 IP 열에서 IPv6 주소를 할당받았는지 확인해요.
    kubectl get pods -n kube-system -o wide
    
    예시 출력은 다음과 같아요.
    NAME                       READY   STATUS    RESTARTS   AGE     IP                                       NODE
    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
    coredns-85d5b4454c-cw7w2   1/1     Running   0          56m     2600:1f13:b66:8203:34e5::                ip-192-168-253-70.region-code.compute.internal
    coredns-85d5b4454c-tx6n8   1/1     Running   0          56m     2600:1f13:b66:8203:34e5::1               ip-192-168-253-70.region-code.compute.internal
    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
    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
    
  2. 기본 서비스가 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           53/UDP,53/TCP   57m   k8s-app=kube-dns
    
  3. (선택 사항) 샘플 애플리케이션을 배포하거나, AWS Load Balancer Controller와 샘플 애플리케이션을 배포해 Application Load Balancer로 HTTP 트래픽을 라우팅하거나 Network Load Balancer로 TCP/UDP 트래픽을 라우팅하여 IPv6 Pod로 HTTP 애플리케이션을 로드 밸런싱해요.
  4. 이 튜토리얼에서 만든 클러스터와 노드 사용이 끝나면 다음 명령으로 만든 리소스를 정리해야 해요.
    eksctl delete cluster my-cluster
    

AWS CLI로 IPv6 클러스터 배포

중요

이 절차의 모든 단계를 같은 사용자로 완료해야 해요. 현재 사용자를 확인하려면 다음 명령을 실행하세요.

aws sts get-caller-identity

이 절차의 모든 단계를 같은 셸에서 완료해야 해요. 여러 단계가 이전 단계에서 설정한 변수를 사용해요. 변수 값이 다른 셸에서 설정되면 변수를 사용하는 단계가 제대로 작동하지 않아요. AWS CloudShell로 다음 절차를 완료한다면 키보드나 포인터로 약 20~30분 동안 상호작용하지 않으면 셸 세션이 종료된다는 점을 기억하세요. 실행 중인 프로세스는 상호작용으로 간주되지 않아요.

지침은 Bash 셸용으로 작성됐으며, 다른 셸에서는 조정이 필요할 수 있어요.

이 절차의 단계에서 모든 예시 값을 자신의 값으로 바꾸세요.

1. 변수 설정

이후 단계에서 사용할 변수를 설정하려면 다음 명령을 실행해요. region-code를 리소스를 배포하려는 AWS 리전으로 바꾸세요. 값은 Amazon EKS가 지원하는 모든 AWS 리전일 수 있어요. my-cluster를 클러스터 이름으로 바꾸세요. my-nodegroup을 노드 그룹 이름으로 바꾸세요. 111122223333을 계정 ID로 바꾸세요.

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

2. Amazon VPC 생성

Amazon EKS 및 IPv6 요구사항을 충족하는 공용 및 프라이빗 서브넷이 있는 Amazon VPC를 만들어요.

다음 명령으로 AWS CloudFormation 스택 이름 변수를 설정해요. my-eks-ipv6-vpc를 원하는 이름으로 바꿀 수 있어요.

export vpc_stack_name=my-eks-ipv6-vpc

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

3. 공용 서브넷 ID 검색 및 IPv6 자동 할당 활성화

만들어진 공용 서브넷의 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

만들어진 공용 서브넷에 대해 auto-assign IPv6 address 옵션을 활성화해요.

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

배포된 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}

4. 클러스터 IAM 역할 생성

클러스터 IAM 역할을 만들고 필수 Amazon EKS IAM 관리형 정책을 연결해요. Amazon EKS가 관리하는 Kubernetes 클러스터는 여러분을 대신해 AWS 서비스에 호출을 하여 서비스와 함께 사용하는 리소스를 관리해요.

eks-cluster-role-trust-policy.json 파일을 만들려면 다음 명령을 실행해요.

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

역할 이름 변수를 설정하려면 다음 명령을 실행해요. myAmazonEKSClusterRole을 원하는 이름으로 바꿀 수 있어요.

export cluster_role_name=myAmazonEKSClusterRole

역할을 만들어요.

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

IAM 역할의 ARN을 검색해 이후 단계에서 사용할 변수에 저장해요.

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

필수 Amazon EKS 관리형 IAM 정책을 역할에 연결해요.

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

5. 클러스터 생성

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

참고: 요청의 가용 영역 중 하나가 Amazon EKS 클러스터를 만들 수 있는 충분한 용량이 없다는 오류를 받을 수 있어요. 이 경우 오류 출력에 새 클러스터를 지원할 수 있는 가용 영역이 포함돼요. 계정에서 지원되는 가용 영역에 위치한 최소 두 개의 서브넷으로 클러스터 만들기를 다시 시도해요. 자세한 내용은 용량 부족을 참고하세요.

클러스터가 만들어지는 데 몇 분 걸려요. 다음 명령을 실행해요. 명령 출력이 ACTIVE가 될 때까지 다음 단계로 진행하지 마세요.

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

클러스터와 통신할 수 있도록 클러스터의 kubeconfig 파일을 만들거나 업데이트해요.

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

기본적으로 config 파일은 ~/.kube에 만들어지거나 새 클러스터의 구성이 ~/.kube의 기존 config 파일에 추가돼요.

6. 노드 IAM 역할 생성

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/*"
            ]
        }
    ]
}

IAM 정책을 만들어요.

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

node-role-trust-relationship.json 파일을 만들려면 다음 명령을 실행해요.

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

역할 이름 변수를 설정하려면 다음 명령을 실행해요. AmazonEKSNodeRole을 원하는 이름으로 바꿀 수 있어요.

export node_role_name=AmazonEKSNodeRole

IAM 역할을 만들어요.

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

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 플러그인 구성하기를 참고하세요.

필수 IAM 관리형 정책 2개를 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

IAM 역할의 ARN을 검색해 이후 단계에서 사용할 변수에 저장해요.

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

7. 관리형 노드 그룹 생성

이전 단계에서 만든 서브넷의 ID를 확인해요.

echo $subnets

예시 출력은 다음과 같아요.

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

노드 그룹을 만들어요. 0a1a56c486EXAMPLE, 099e6ca77aEXAMPLE, 0377963d69EXAMPLE, 0c05f819d5EXAMPLE을 이전 단계의 출력에서 반환된 값으로 바꾸세요. 이전 출력의 서브넷 ID 사이의 쉼표는 다음 명령에서 반드시 제거하세요. t3.medium을 모든 AWS Nitro System 인스턴스 유형으로 바꿀 수 있어요.

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

8. IPv6 주소 확인

기본 Pod가 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
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
coredns-85d5b4454c-cw7w2   1/1     Running   0          56m     2600:1f13:b66:8203:34e5::                ip-192-168-253-70.region-code.compute.internal
coredns-85d5b4454c-tx6n8   1/1     Running   0          56m     2600:1f13:b66:8203:34e5::1               ip-192-168-253-70.region-code.compute.internal
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
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

기본 서비스가 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           53/UDP,53/TCP   57m   k8s-app=kube-dns

(선택 사항) 샘플 애플리케이션을 배포하거나, AWS Load Balancer Controller와 샘플 애플리케이션을 배포해 Application Load Balancer로 HTTP 트래픽을 라우팅하거나 Network Load Balancer로 TCP/UDP 트래픽을 라우팅하여 IPv6 Pod로 HTTP 애플리케이션을 로드 밸런싱해요.

9. 리소스 정리

이 튜토리얼에서 만든 클러스터와 노드 사용이 끝나면 다음 명령으로 만든 리소스를 정리해야 해요. 삭제하기 전에 리소스가 이 튜토리얼 외에 사용되고 있지 않은지 확인하세요.

이전 단계를 완료한 셸과 다른 셸에서 이 단계를 완료한다면 이전 단계에서 사용한 모든 변수의 값을 설정하세요. 이전 단계를 완료한 셸과 같은 셸에서 이 단계를 완료한다면 다음 단계로 건너뛰세요.

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

노드 그룹을 삭제해요.

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

클러스터를 삭제해요.

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.

만든 IAM 리소스를 삭제해요. 이전 단계에서 사용한 이름과 다른 이름을 선택했다면 AmazonEKS_CNI_IPv6_Policy를 선택한 이름으로 바꾸세요.

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

VPC를 만든 AWS CloudFormation 스택을 삭제해요.

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

더 알아보기 (Learn more)