이 블로그에서는 AWS Region 및 AWS Local Zone 에 걸쳐 EKS 클러스터를 배포하고, 자동 확장 가능한 인클러스터 네트워크 로드 밸런서로서 LoxiLB를 사용하는 방법을 설명할 것입니다. Terraform을 사용해 이러한 클러스터를 완전 자동화된 방식으로 구성하는 전체 단계를 제공할 예정입니다. 또한, 이러한 배포가 최종 사용자 관점에서 제공하는 다양한 이점과 창출할 수 있는 비즈니스 가치를 상세히 설명할 것입니다.
배포 아키텍처 및 그 이점
LoxiLB를 포함한 이 전체 유즈 케이스의 이점을 빠르게 살펴보겠습니다 :
LoxiLB와 자동 확장 노드 그룹을 통해 비용 절감과 유연성 확보
LoxiLB는 ELB와 비교하여 클러스터 내에서 실행됨으로써 비용을 절감할 수 있습니다. ELB 서비스는 Kubernetes 클러스터와 독립적으로 운영됩니다. 본 블로그의 유즈케이스 에서 LoxiLB는 클러스터의 일부로 실행되는 자동 확장 노드 그룹에 배포됩니다. 세분화된 정책을 통해 로드 밸런서 노드는 비즈니스 요구에 맞게 확장되거나 축소될 수 있습니다.
멀티 홈 네트워킹에 최적화됨
Multus(보조 네트워크 인터페이스)를 사용하는 클러스터의 경우, LoxiLB는 더욱 효과적입니다. LoxiLB는 클러스터 내 여러 네트워크 간의 트래픽 라우팅을 관리합니다. 텔코 애플리케이션이나 Kube-virt 기반 애플리케이션과 같은 많은 워크로드는 다중 네트워크를 사용하는 파드를 필요로 합니다
고성능
LoxiLB는 효율적인 eBPF 구현 덕분에 이미 고성능을 자랑합니다. 여기서 EKS VPC CNI의 기능을 활용하여 VPC 내에서 podIP에 직접 접근할 수 있도록 추가 최적화를 제공합니다. 이를 통해 불필요한 Kubernetes 네트워크 계층을 우회하여 EKS 클러스터로의 트래픽 유입을 간소화할 수 있습니다.
모든 AWS Local Zones 이 관리형 ELB 지원을 제공하지는 않습니다.
AWS Local Zones 은 대규모 인구 밀집 지역, 산업, IT 허브에 더 가까이 컴퓨팅, 스토리지, 데이터베이스 및 기타 선택된 AWS 서비스를 배치하는 AWS 인프라 배포 유형입니다. AWS 로컬 존의 주요 목표는 애플리케이션 및 서비스에 대한 초저지연 액세스를 제공하여 실시간 게임, 비디오 스트리밍, 증강/가상 현실(AR/VR), 엣지에서의 머신 러닝 등 특정 사용 사례의 성능을 개선하는 것입니다. 모든 존이 ALB/NLB와 같은 ELB 서비스를 제공하는 것은 아닙니다. 이러한 로컬 존에서는 워크로드를 위한 로드 밸런싱이 필요한 사용자에게 큰 도움이 됩니다.
Route53(DNS GSLB) 와의 완전한 통합
이번 유즈 케이스는 액티브-액티브 고가용성(HA) 모델을 기반으로 합니다. Kubernetes에서 생성된 서비스는 Route53 레코드에 직접 업데이트될 수 있습니다. EKS 외부에 인스턴스의 Elastic IP가 존재하기 때문에 이를 EKS와 직접 통합하는 간단한 방법은 없었습니다. 우리는 LoxiLB, external-dns, 그리고 Route53과의 광범위한 통합 및 자동화를 통해 이를 달성했습니다.
마지막으로, EKS 배포에서 온-프레미스 스타일의 로드 밸런서를 사용할 수 있습니다. 전체 배포 토폴로지는 다음 그림과 같이 구성됩니다:
시작하기 전 사전 준비 사항
호스트에 최신 버전의 awscli, eksctl, kubectl 및 terraform 도구가 구성되어 있는지 확인하십시오. 또한, 호스트에는 클러스터 작업 등을 수행할 수 있는 충분한 IAM 권한이 있어야 합니다.
EKS 클러스터 생성하기
We will create an EKS cluster in the main AWS regional zone, having 3 sets of worker node-groups. One will be created in AWS main region(with one node). The other two node-groups ((with two nodes each) will be used to run LoxiLB and workload pods respectively. This has been completely automated with Terraform. The terraform scripts sets up the cluster and also IAM roles/K8s service accounts necessary for cluster access from inside the cluster using OIDC based scheme. Terraform variables are set to create a cluster in "us-east-1" region. Please feel free to check the GitHub repo and change as per your need.
우리는 AWS 주요 Region 에 EKS 클러스터를 생성하고, 3개의 Worker Node-Groups 을 설정할 것입니다. 하나는 AWS 주요 Region에 생성되며(노드 1개), 나머지 두 Node Group(각각 2개의 노드 포함)은 각각 LoxiLB와 워크로드 파드를 실행하는 데 사용됩니다. 이 과정은 Terraform을 통해 완전히 자동화되었습니다. Terraform 스크립트는 클러스터를 설정하고 OIDC 기반 방식을 사용해 클러스터 내부에서 클러스터에 접근할 수 있도록 필요한 IAM 역할 및 Kubernetes 서비스 계정도 설정합니다. Terraform 변수는 "us-east-1" 리전에 클러스터를 생성하도록 설정되어 있습니다. 다음 GitHub 를 확인하고 필요에 따라 변경하십시오.
$ git clone https://github.com/loxilb-io/demo-examples
$ cd demo-examples/terraform/eks-inclb
$ terraform init
$ terraform apply
LocalZone 으로 클러스터 확장 (선택 사항)
This cluster can also span across AWS local-region as well. If you want to setup LoxiLB in the local zone then local-az in your region needs to be enabled(e.g. "us-east-1-atl-2a" is a local zone in "us-east-1" region). The terraform script in this blog does not create a NodeGroup in the local zone. However one can follow other examples such as the one found here.
이 클러스터는 AWS Local Region 에서도 확장할 수 있습니다. Local Zone 에 LoxiLB를 설정하려면 해당 Region 의 로컬 가용 영역(local-az)을 활성화해야 합니다 (예: 'us-east-1' region 의 Local Zone 인 'us-east-1-atl-2a'). 이 블로그의 Terraform 스크립트는 Local Zone 에 Node Group을 생성하지 않습니다. 그러나 여기에서 찾을 수 있는 다른 예제를 참조할 수 있습니다.
EKS 클러스터 상태 확인하기
처음에 생성한 클러스터로 돌아가 보겠습니다. 이 시점에서 클러스터와 해당 노드의 상태를 확인할 수 있습니다. :
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-192-168-68-85.ec2.internal Ready <none> 84m v1.31.0-eks-a737599
ip-192-168-73-205.ec2.internal Ready <none> 71m v1.31.0-eks-a737599
ip-192-168-81-126.ec2.internal Ready <none> 71m v1.31.0-eks-a737599
ip-192-168-85-237.ec2.internal Ready <none> 125m v1.31.0-eks-a737599
ip-192-168-90-199.ec2.internal Ready <none> 84m v1.31.0-eks-a737599
LoxiLB CRD 생성하기
$ kubectl apply -f https://raw.githubusercontent.com/loxilb-io/kube-loxilb/refs/heads/main/manifest/crds/loxilb-url-crd.yaml
LoxiLB 인클러스터 배포
$ kubectl apply -f yaml/loxilb.yaml
daemonset.apps/loxilb-lb created
service/loxilb-lb-service created
이 작업은 인스턴스 메타데이터를 가져와 Kubernetes CRD를 채우기 위해 InitContainer를 사용하는 점을 제외하면 매우 간단합니다.
kube-loxilb 컴포넌트(LoxiLB의 오퍼레이터) 배포하기
$ kubectl apply -f yaml/kube-loxilb.yaml
serviceaccount/kube-loxilb created
clusterrole.rbac.authorization.k8s.io/kube-loxilb created
clusterrolebinding.rbac.authorization.k8s.io/kube-loxilb created
deployment.apps/kube-loxilb created
EKS에서 LoxiLB CRD 기반 노드 공인 IP 등록 확인하기
이제 LoxiLB는 loxi CRD를 통해 Kubernetes에 노드의 공인 IP를 업데이트했을 것입니다. 아래에서 이를 확인할 수 있습니다:
$ kubectl describe loxiurl | grep "Loxi URL"
Loxi URL: 54.234.13.xxx
Loxi URL: 34.229.17.xxx
External-DNS/Route53 설정
external-DNS가 Route53과 통신할 수 있도록 하기 위해 다음 단계를 따라야 합니다.
IAM 권한 설정
IAM 권한을 설정하여 ExternalDNS가 Route53 DNS 레코드를 업데이트할 수 있도록 하는 정책을 생성합니다. route53_policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets"
],
"Resource": [
"arn:aws:route53:::hostedzone/*"
]
},
{
"Effect": "Allow",
"Action": [
"route53:ListHostedZones",
"route53:ListResourceRecordSets",
"route53:ListTagsForResource"
],
"Resource": [
"*"
]
}
]
}
다음 명령어를 사용하여 AWS CLI로 정책을 생성하세요:
$ aws iam create-policy --policy-name "AllowExternalDNSUpdates" --policy-document file://route53_policy.json
{
"Policy": {
"PolicyName": "AllowExternalDNSUpdates",
"PolicyId": "ANPA4CF3XA2FPM25QT3TB",
"Arn": "arn:aws:iam::829322364554:policy/AllowExternalDNSUpdates",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2024-10-17T07:14:35+00:00",
"UpdateDate": "2024-10-17T07:14:35+00:00"
}
}
$ export POLICY_ARN=$(aws iam list-policies \
--query 'Policies[?PolicyName==`AllowExternalDNSUpdates`].Arn' --output text)
서비스 계정에 바인딩된 IAM 역할 생성하기
$ eksctl create iamserviceaccount \
--cluster demo \
--region us-east-1 \
--name "external-dns" \
--namespace "default" \
--attach-policy-arn $POLICY_ARN \
--approve
먼저, 다음 명령어를 사용하여 클러스터에서 RBAC가 활성화되어 있는지 확인해야 합니다:
$ kubectl api-versions | grep rbac.authorization.k8s.io
rbac.authorization.k8s.io/v1
RBAC가 활성화되어 있으면, EKS 역할 ARN을 가져옵니다:
$ kubectl describe sa external-dns
Name: external-dns
Namespace: default
Labels: app.kubernetes.io/managed-by=eksctl
Annotations: eks.amazonaws.com/role-arn: arn:aws:iam::829322364554:role/eksctl-eks-loxilb-lz-cluster-addon-iamserviceaccou-Role1-hHpB9SHbHTUu
Image pull secrets: <none>
Mountable secrets: <none>
Tokens: <none>
Events: <none>
그런 다음, 역할 ARN을 대체한 후 yaml/external-dns-with-rbac.yaml 파일의 매니페스트 파일을 사용하여 ExternalDNS를 배포합니다.
RBAC가 활성화되지 않은 경우:
그런 경우, 매니페스트 파일 yaml/external-dns-with-no-rbac.yaml을 사용해야 합니다.
externalDNS 배포 생성하기
$ kubectl apply yaml/external-dns-xxx.yaml
externalDNS 배포 확인하기
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
external-dns 1/1 1 1 13h
테스트 !!!
다음 YAML 파일을 사용하여 테스트 nginx 파드를 생성합니다:
apiVersion: v1
kind: Service
metadata:
name: nginx-lb1
annotations:
external-dns.alpha.kubernetes.io/hostname: www.multi-xxx-domain.com
loxilb.io/usepodnetwork : "yes"
spec:
externalTrafficPolicy: Local
loadBalancerClass: loxilb.io/loxilb
selector:
what: nginx-test
ports:
- port: 80
targetPort: 80
type: LoadBalancer
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-test
labels:
what: nginx-test
spec:
nodeSelector:
node: wlznode02
containers:
- name: nginx-test
image: nginx
imagePullPolicy: Always
ports:
- containerPort: 80
여기서 몇 가지 주석(annotation)을 확인해야 합니다.
external-dns.alpha.kubernetes.io/hostname : 이 주석(annotation)은 외부 DNS가 서비스가 Ready 상태일 때만 세부 정보를 가져오도록 사용됩니다.
loxilb.io/usepodnetwork : 이 주석(annotation)은 LoxiLB가 이전에 설명한 대로 PodIP를 사용하여 직접 파드에 접근하도록 지시합니다.
배포를 실행합니다 :
$ kubectl apply -f yaml/nginx.yaml
service/nginx-lb1 created
pod/nginx-test created
트래픽을 허용하기 위해 클러스터 보안 그룹을 수정해야 합니다 (이 작업은 Terraform에서 처리되지 않습니다). AWS 콘솔에서: EKS -> 클러스터 -> < 이름 > -> 네트워킹 -> ClusterSecurityGroup.
생성된 K8s 서비스를 확인해봅시다:
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 49m
nginx-lb1 LoadBalancer 10.100.144.82 34.229.17.XX,52.90.160.XX 80:31800/TCP 28m
이제 LoxiLB가 스케줄링된 모든 노드의 공인 IP를 나열할 수 있습니다. 각 외부 IP를 통해 접근할 수 있으며, Active-Active HA 설정을 위해 자동 장애 조치(Auto-Fail Over)로 구성된 도메인 이름을 사용할 수도 있습니다.
도메인 이름으로 접근 테스트하기
$ curl http://www.multi-xxx-domain.com
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
공인 IP로 접근 테스트하기
$ curl http://34.229.17.XX
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
성능
성능 테스트를 위해 위와 동일한 설정을 사용했습니다. 추가로, LoxiLB와 워커 노드와 동일한 영역/서브넷에 EC2 호스트를 배치하고 일련의 테스트를 실행했습니다. 우리는 LoxiLB의 성능을 EKS/Kubernetes가 제공하는 NodePort와 비교하여 측정했습니다. NodePort는 (실제 운영 환경 옵션은 아니지만) kube-proxy를 통해 Kubernetes 클러스터 내부에서 사용할 수 있어 비교를 위한 최상의 기준이 될 것으로 보았습니다.
위 차트에서 볼 수 있듯이, 거의 모든 테스트에서 LoxiLB 기반 워크로드의 성능이 우수하거나 동일하게 나타났습니다. LoxiLB는 요청당 처리 속도와 요청의 전체 지연 시간에서 탁월한 성능을 보였으며, 이는 다양한 애플리케이션에 매우 중요합니다.
결론
본 블로그에서 우리는 AWS region / Local Zone 에 Auto-scaled 노드 그룹 내에 배포된 LoxiLB가 Route 53과 통합되어 저지연, 고성능 애플리케이션에 견고하고 확장 가능한 솔루션을 제공하는 방법을 배웠습니다. 이러한 설정은 원활한 트래픽 분배와 동적 확장을 보장하여 인프라가 변동하는 워크로드를 효율적으로 처리할 수 있도록 합니다. Route 53과의 통합은 지능형 라우팅과 글로벌 DNS 관리를 가능하게 하여 애플리케이션의 가용성과 성능을 더욱 향상시킵니다.
또한, AWS 로컬 존을 활용하여 엔드 유저와의 근접성을 확보하고 LoxiLB의 효율적인 로드 밸런싱 기능을 통해, 이 아키텍처는 현대의 까다로운 애플리케이션에 대해 향상된 응답성, 자동 확장을 통한 비용 최적화, 그리고 높은 복원력을 갖춘 인프라를 제공합니다.
크레딧
이 게시물에 대해 협력해 주시고 아낌없는 지원과 소중한 피드백을 제공해 주신 AWS의 Saravanan Shanmugan님께 특별히 감사드립니다. Amazon Web Services에서 혁신적인 솔루션을 이끄는 하이브리드 클라우드 및 네트워킹 전문가로서, 그의 통찰력과 전문 지식 덕분에 가능했습니다.
Comments