Amazon Web Services 한국 블로그
Amazon Elastic Kubernetes Service에 IPv6 네트워킹 기능 추가
오늘부터 Amazon Elastic Kubernetes Service(Amazon EKS)에서 IPv6 주소 공간을 사용하는 애플리케이션을 배포할 수 있습니다.
많은 고객들이 Kubernetes를 클라우드 및 온프레미스 애플리케이션을 위한 컴퓨팅 인프라 플랫폼으로 표준화하고 있습니다. Amazon EKS를 사용하면 컨테이너화된 워크로드를 쉽게 배포할 수 있습니다. 고가용성 클러스터를 제공하고 패치 적용, 노드 프로비저닝 및 업데이트와 같은 태스크를 자동화합니다.
Kubernetes는 각 포드가 IP 주소를 수신해야 하는 플랫 네트워킹 모델을 사용합니다. 이 간소화된 접근 방식을 사용하면 가상 머신에서 컨테이너로 애플리케이션을 원활하게 포팅할 수 있지만 대다수의 프라이빗 VPC IPv4 네트워크에서는 처리할 수 없는 많은 수의 IP 주소가 필요합니다. 일부 클러스터 관리자는 VPC의 상위 계층에서 IP 주소를 가상화하는 컨테이너 네트워크 플러그 인(CNI)을 설치하여 이러한 IPv4 공간 제한을 해결하지만, 이 아키텍처는 관리자가 애플리케이션을 효과적으로 관찰하고 문제를 해결하는 능력을 제한하며 전체적인 네트워크 성능에 부정적인 영향을 미칩니다. 또한 VPC 외부의 인터넷 서비스와 통신하기 위해 IPv4 포드의 트래픽은 대상에 도달하기 전에 여러 네트워크 홉을 통해 라우팅되므로 대기 시간이 늘어나고 네트워크 엔지니어링 팀에는 복잡한 라우팅 설정을 유지해야 하는 부담이 가해집니다.
IP 주소 고갈을 방지하고 전체적인 대기 시간을 최소화하며 라우팅 구성을 간소화하기 위한 해결책은 IPv6 주소 공간을 사용하는 것입니다.
IPv6는 새로운 것이 아닙니다. 1996년에 저는 “IPng, 차세대 인터넷 프로토콜”에 관한 첫 번째 책을 구입했습니다. 25년 전엔 그게 차세대였습니다. IPv6는 64비트 주소 공간을 제공하여 디바이스, 서버 또는 컨테이너에 3.4 x 10^38개의 IP 주소를 사용할 수 있도록 합니다. 지구 표면의 모든 원자에 IPv6 주소를 할당하고도 여전히 100개 이상의 지구에 할당하기에 충분한 숫자입니다.
IPv6 네트워크에서 Amazon EKS 클러스터를 사용하면 몇 가지 이점이 있습니다. 첫째, VPC에서 사용 가능한 모든 IPv4 주소를 소진할 위험 없이 하나의 단일 호스트 또는 서브넷에서 더 많은 포드를 실행할 수 있습니다. 둘째, 추가적인 NAT 홉을 피함으로써 온프레미스, AWS 또는 인터넷에서 실행되는 다른 IPv6 서비스와의 통신 대기 시간을 줄일 수 있습니다. 셋째, 네트워크 엔지니어가 복잡한 라우팅 구성을 유지 관리해야 하는 부담을 덜어줍니다.
Kubernetes 클러스터 관리자는 IPv4 제한 문제를 해결하기 위해 노력할 필요없이 애플리케이션을 마이그레이션하고 크기 조정하는 데 집중할 수 있습니다. 마지막으로, 포드 네트워킹은 포드가 클러스터 외부의 IPv4 기반 애플리케이션과 통신할 수 있도록 구성되므로, 조직 전체에 배포된 모든 종속 서비스를 먼저 IPv6로 마이그레이션할 필요 없이 Amazon EKS에서 IPv6의 이점을 채택할 수 있습니다.
평소처럼 작동 방식을 보여주기 위해 간단한 데모를 만들었습니다.
작동 방식
시작하기 전에 IPv6 VPC를 생성합니다. 이 CDK 스크립트를 사용하여 IPv6 지원 VPC를 몇 분 안에 생성합니다(코드를 제공해 주신 Angus Lees 님께 감사드립니다). CDK v2(npm install -g aws-cdk@next
)를 설치하고 스택을 배포하기만 하세요(cdk bootstrap && cdk deploy
).
IPv6를 사용하는 VPC가 생성되면 콘솔을 사용하여 퍼블릭 서브넷에 배포된 리소스에 대한 IPv6 주소 자동 할당을 구성합니다(이를 각 퍼블릭 서브넷에 대해 수행합니다).
위의 CDK 스크립트에서 생성된 서브넷 ID(스크립트 출력에 나열되어 있음)를 기록해 두고 데모 전체에서 사용할 몇 가지 변수를 정의합니다. 또한 Amazon EKS 설명서에 설명된 대로 클러스터 IAM 역할과 노드 IAM 역할을 생성합니다. 클러스터를 이미 배포했다면 이 두 가지 역할이 이미 존재합니다.
터미널을 열고 다음을 입력합니다.
CLUSTER_ROLE_ARN="arn:aws:iam::0123456789:role/EKSClusterRole"
NODE_ROLE_ARN="arn:aws:iam::0123456789:role/EKSNodeRole"
SUBNET1="subnet-06000a8"
SUBNET2="subnet-03000cc"
CLUSTER_NAME="AWSNewsBlog"
KEYPAIR_NAME="my-key-pair-name"
다음으로 Amazon EKS IPv6 클러스터를 생성합니다. 터미널에 다음을 입력합니다.
aws eks create-cluster --cli-input-json "{
\"name\": \"${CLUSTER_NAME}\",
\"version\": \"1.21\",
\"roleArn\": \"${CLUSTER_ROLE_ARN}\",
\"resourcesVpcConfig\": {
\"subnetIds\": [
\"${SUBNET1}\", \"${SUBNET2}\"
],
\"endpointPublicAccess\": true,
\"endpointPrivateAccess\": true
},
\"kubernetesNetworkConfig\": {
\"ipFamily\": \"ipv6\"
}
}"
{
"cluster": {
"name": "AWSNewsBlog",
"arn": "arn:aws:eks:us-west-2:486652066693:cluster/AWSNewsBlog",
"createdAt": "2021-11-02T17:29:32.989000+01:00",
"version": "1.21",
...redacted for brevity...
"status": "CREATING",
"certificateAuthority": {},
"platformVersion": "eks.4",
"tags": {}
}
}
클러스터가 생성되기를 기다리는 동안 describe-cluster
를 사용합니다. 클러스터가 준비되면 "status" : "ACTIVE"
가 됩니다.
aws eks describe-cluster --name "${CLUSTER_NAME}"
그런 다음 노드 그룹을 생성합니다.
aws eks create-nodegroup \
--cluster-name ${CLUSTER_NAME} \
--nodegroup-name AWSNewsBlog-nodegroup \
--node-role ${NODE_ROLE_ARN} \
--subnets "${SUBNET1}" "${SUBNET2}" \
--remote-access ec2SshKey=${KEYPAIR_NAME}
{
"nodegroup": {
"nodegroupName": "AWSNewsBlog-nodegroup",
"nodegroupArn": "arn:aws:eks:us-west-2:0123456789:nodegroup/AWSNewsBlog/AWSNewsBlog-nodegroup/3ebe70c7-6c45-d498-6d42-4001f70e7833",
"clusterName": "AWSNewsBlog",
"version": "1.21",
"releaseVersion": "1.21.4-20211101",
"status": "CREATING",
"capacityType": "ON_DEMAND",
... redacted for brevity ...
}
노드 그룹이 생성되면 콘솔에 두 개의 EC2 인스턴스가 표시됩니다. AWS Command Line Interface(CLI)를 사용하여 인스턴스가 IPv6 주소를 수신했는지 확인합니다.
aws ec2 describe-instances --query "Reservations[].Instances[? State.Name == 'running' ][].NetworkInterfaces[].Ipv6Addresses" --output text
2600:1f13:812:0000:0000:0000:0000:71eb
2600:1f13:812:0000:0000:0000:0000:3c07
kubectl
명령을 사용하여 Kubernetes의 관점에서 클러스터를 확인합니다.
kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
ip-10-0-0-108.us-west-2.compute.internal Ready <none> 2d13h v1.21.4-eks-033ce7e 2600:1f13:812:0000:0000:0000:0000:2263 18.0.0.205 Amazon Linux 2 5.4.149-73.259.amzn2.x86_64 docker://20.10.7
ip-10-0-1-217.us-west-2.compute.internal Ready <none> 2d13h v1.21.4-eks-033ce7e 2600:1f13:812:0000:0000:0000:0000:7f3e 52.0.0.122 Amazon Linux 2 5.4.149-73.259.amzn2.x86_64 docker://20.10.7
그런 다음 포드를 배포합니다. EKS 설명서에서 다음 단계를 따릅니다. 샘플 nginx 웹 서버를 배포합니다.
kubectl create namespace aws-news-blog
namespace/aws-news-blog created
# sample-service.yml is available at https://docs.aws.amazon.com/eks/latest/userguide/sample-deployment.html
kubectl apply -f sample-service.yml
service/my-service created
deployment.apps/my-deployment created
kubectl get pods -n aws-news-blog -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-deployment-5dd5dfd6b9-7rllg 1/1 Running 0 17m 2600:0000:0000:0000:405b::2 ip-10-0-1-217.us-west-2.compute.internal <none> <none>
my-deployment-5dd5dfd6b9-h6mrt 1/1 Running 0 17m 2600:0000:0000:0000:46f9:: ip-10-0-0-108.us-west-2.compute.internal <none> <none>
my-deployment-5dd5dfd6b9-mrkfv 1/1 Running 0 17m 2600:0000:0000:0000:46f9::1 ip-10-0-0-108.us-west-2.compute.internal <none> <none>
내 포드의 IPv6 주소를 기록해 두고 내 랩톱에서 주소 연결을 시도합니다. 현재 사용 중인 서비스 제공 업체가 아직 집에서 IPv6를 제공하지 않기 때문에 연결이 실패합니다. 포드에 IPv4 주소가 전혀 없기 때문에 이는 예상된 결과입니다. -g
옵션은 curl
이 IP 주소에서 :
를 포트 번호 구분 기호로 고려하지 않도록 지시하고 -6
은 curl
이 IPv6를 통해서만 연결하도록 지시합니다(curl
에 DNS 호스트 이름을 제공할 때 필요).
curl -g -6 http://\[2600:0000:0000:35000000:46f9::1\]
curl: (7) Couldn't connect to server
IPv6 연결을 테스트하기 위해 클러스터와 동일한 VPC에서 듀얼 스택(IPv4 및 IPv6) EC2 인스턴스를 시작합니다. 인스턴스에 SSH로 연결하고 curl
명령을 다시 시도합니다. nginx에서 제공하는 기본 HTML 페이지가 수신되었습니다. 포드에 대한 IPv6 연결이 작동합니다!
curl -g -6 http://\[2600:0000:0000:35000000:46f9::1\]
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
... redacted for brevity ...
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
문제가 해결되지 않으면 클러스터 EC2 노드에 대한 보안 그룹을 확인하고 포트 TCP 80
에서 ::/0
으로부터 들어오는 연결을 허용하는 규칙이 보안 그룹에 있는지 확인합니다.
기억해야 할 몇 가지
마무리하기 전에 이 새로운 기능을 이미 실험해 본 고객들로부터 자주 받는 몇 가지 질문에 답하고 싶습니다.
- IPv6는 현재 IPv4에 사용 중인 플러그 인과 동일한 VPC CNI Kubernetes 플러그 인에 의해 활성화됩니다. 이 플러그 인은 클러스터를 생성할 때 선택한 포드 네트워킹에 따라 IPv4 또는 IPv6에 대해 자동으로 구성됩니다.
- IPv6용으로 구성된 VPC CNI 플러그 인을 사용자의 자체 관리형 클러스터에 설치할 수도 있습니다. 그러나 사용자가 클러스터를 관리하므로 IPv6를 지원하도록 제어 영역을 구성하는 것은 사용자의 책임입니다.
- IPv6 지원은 클러스터 생성 시에만 설정됩니다. 현재는 클러스터를 IPv4에서 IPv6로 마이그레이션할 수 없습니다. 마이그레이션하려는 기존 클러스터가 있는 경우 이 기술 문서에 설명된 대로 새 IPv6 기반 클러스터에 워크로드를 다시 배포하고 IPv4에서 IPv6 클러스터로 트래픽을 점진적으로 마이그레이션해야 할 수 있습니다.
- 고유한 IPv6 범위를 가져올 수 있습니다. 다음 지침에 따라 EC2에서 자체 IP 주소 범위를 가져옵니다.
- IPv6 클러스터에 Linux를 배포할 수 있습니다. Windows는 현재 지원되지 않습니다.
- 클러스터에 최신 버전의 AWS Load Balancer Controller를 설치하여 Application Load Balancer 및/또는 Network Load Balancer를 사용하여 외부 트래픽을 IPv6 포드로 라우팅해야 합니다.
요금 및 가용성
Amazon Elastic Kubernetes Service(EKS) 클러스터에 대한 IPv6 지원은 현재 Amazon EKS를 사용할 수 있는 모든 AWS 리전에서 추가 비용 없이 제공됩니다.