본문 바로가기

카테고리 없음

[aws] 고가용성 Multi AZs EKS 구성하기 - 맨땅에 헤딩

https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-concepts.html

들어가며

서버를 구성할 때 DR(Disaster Recovery), 고가용성의 목적으로 여러 IDC 에 분산하여 서버를 배치하는 모습을 많이 볼 수 있습니다.

휴먼 에러로 인한 경우가 많지만, 특정 IDC 가 있는 지역에 지진, 화재 같은 자연재해나 outage 정전으로 IDC 전체가 정상적으로 가동될 수 없는 경우들이 종종 있습니다.

AWS 에서 서버를 제대로 구축해본 경험이 없어서, AWS EKS 서비스를 통해 고가용성 Multi IDC(AZ) k8s cluster 를 어떻게 구성할 수 있는지 필요한 기본 개념들부터 살펴보면서 알아보고자 합니다.

 

IDC 가 날아간 사례

https://dgtlinfra.com/data-center-fires/

고가용성 전에 고려 사항

  • First question, what’s the requirement?
  • Is there a budget?
  • What’s the balance of reads and writes to the database?
  • Is there an RTO?
  • have you considered Aurora Postgres?

ref) https://repost.aws/ko/questions/QUyN1UMa3XS9KXlLwAMNtCWw/which-is-better-multi-az-db-cluster-or-multi-az-db-instance-for-amazon-rds-for-postgresql

 

DR, 고가용성도 좋지만, 무조건 모든 서버를 Multi IDC 로 구성하는 것은 좋지 않을 수 있습니다.

당연히 비용이 더 많이 들 수 있고 관리하기에도 복잡할 수 있습니다. 굳이 서비스에 필수적이지 않고 어느정도 fault 가 용인되는 기능이라면 circuitbreaker 같은 장치를 통해 핵심 서비스만 지키고 부가기능은 downtime 을 감수하고 다른 DR 전략을 세우는 것도 방법이 될 수 있습니다.

AWS에서 최소한의 비용으로 구현하는 멀티리전 DR 자동화 구성 https://www.youtube.com/watch?v=5xyU7sA2Ajg

AWS Multi Region, AZ(Available Zone)

https://www.flashgrid.io/news/multi-az-vs-multi-region-in-the-cloud/

 

AWS 에서 IDC 의 개념은 Region, AZ(Avaliable Zone) 으로 나눠볼 수 있습니다.

us-west-1 (미국 서부 캘리포니아), ap-northeast-2 (아시아 태평양 서울) 와 같은 하나의 Region 은 여러개의 Availavle Zone 으로 구성되어 있습니다. ap-northeast-2 (아시아 태평양 서울)의 경우, [apne2-az1 | apne2-az2 | apne2-az3 | apne2-az4] 4개의 AZ 가 있습니다.

각 AZ 는 서로 지리적으로, 논리적으로 독립적으로 하나의 IDC 로 볼 수 있습니다. 재해로 하나의 Region 에 있는 모든 AZ 전체가 down 되는 경우는, 아직 AWS, Azure, GCP 클라우드 서비스에 발생한 적은 없다고 합니다.

물론, configure, software 오류로 전체 Region 가 서비스 불가했던 사례는 있다고 합니다. (Amazon S3 Service Disruption in the Northern Virginia (US-EAST-1) Region)

 

글로벌 서비스로 Multi-Region 을 통해 지리적으로 가까운 서버에서 서빙하는 등의 요구사항이 아닌 DR 목적으로만 본다면 Multi-AZ 로도 대부분의 목적은 달성할 수 있다고 보여집니다.

https://www.flashgrid.io/news/multi-az-vs-multi-region-in-the-cloud/

 

또한, 같은 Region 안에서 AZ 들 끼리의 Latency 는 거의 제로에 가깝지만, Region 간의 통신은 100 ms 미만의 Latency 를 가집니다.

https://support.flashgrid.io/hc/en-us/articles/9393270661015-Selecting-Availability-Zones-to-minimize-latency-between-database-nodes-AWS (Oracle RAC clusters Multi AZ Network Latency)

 

AWS EKS 의 경우, 여러 Region 에 걸친 EKS Cluster 는 지원하지 않으므로, 각 Region 마다 Cluster 를 만들고 이들을 Global Accelerator, Aurora Global Database 등 좀 더 추가적인 기능을 사용해서 Cluster 를 묶어 서비스를 제공할 수 밖에 없을 것입니다.

 

AWS EKS 기본 아키텍처

https://cwal.tistory.com/33

 

EKS 는 aws 에서 제공하는 Kubernetes 컨트롤 플레인을 설치, 운영 및 유지 관리할 필요가 없는 관리형 서비스입니다. 따라서 Master Node 들은 aws 에서 관리하며 사용자는 이에 접근할 수도 없습니다.

 

https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-concepts.html

Amazon EKS runs and scales the Kubernetes control plane across multiple AWS Availability Zones to ensure high availability. Amazon EKS automatically scales control plane instances based on load, detects and replaces unhealthy control plane instances, and automatically patches the control plane. After you initiate a version update, Amazon EKS updates your control plane for you, maintaining high availability of the control plane during the update. This control plane consists of at least two API server instances and three etcd instances that run across three Availability Zones within an AWS Region.

ref) https://docs.aws.amazon.com/eks/latest/userguide/disaster-recovery-resiliency.html

 

AWS 는 EKS 의 control pane (API server, etcd) 들을 여러 AZ 에 걸쳐 구성하여 고가용성을 제공하고, load 에 따라 자동으로 스케일 업/다운이 되도록 설계하였고 버전 업도 해준다고 합니다.

 

Every managed node is provisioned as part of an Amazon EC2 Auto Scaling group that's managed for you by Amazon EKS. Every resource including the instances and Auto Scaling groups runs within your AWS account. Each node group runs across multiple Availability Zones that you define.

ref) https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html

 

Worker node 의 경우, managed node groups 을 이용하면 자동으로 여러 AZ 에 걸쳐 node 를 생성해줍니다. 따라서, 기본 구성들을 잘 사용하면 Multi AZ Cluster 를 바로 구성할 수 있게 됩니다.

 

EKS Quick start

이제, EKS 공식문서에 있는 튜토리얼을 따라해보면서, 실제 EKS 구성에 대해 좀 더 알아보도록 하겠습니다.

https://docs.aws.amazon.com/eks/latest/userguide/quickstart.html

 

Quickstart: Deploy a web app and store data - Amazon EKS

If you receive an Error: checking STS access in the response, make sure that you're using the correct user identity for the current shell session. You may also need to specify a named profile (for example, --profile clusteradmin) or get a new security toke

docs.aws.amazon.com

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: web-quickstart
  region: region-code

managedNodeGroups:
  - name: eks-mng
    instanceType: t3.medium
    desiredCapacity: 2

iam:
  withOIDC: true
  serviceAccounts:
  - metadata:
      name: aws-load-balancer-controller
      namespace: kube-system
    wellKnownPolicies:
      awsLoadBalancerController: true

addons:
  - name: aws-ebs-csi-driver
    wellKnownPolicies: # Adds an IAM service account
      ebsCSIController: true
      
cloudWatch:
 clusterLogging:
   enableTypes: ["*"]
   logRetentionInDays: 30

 

위 eksctl cluster template 을 통해 튜토리얼에서 생성하는 component 들은 아래와 같습니다.

 

VPC Configuration

VPC 는 가상 네트워크 영역으로, 클라우드 환경에서 독립된 네트워크 환경을 만들고 리소스들을 위치시킬 수 있습니다. 이는 클라우드 서비스 사용자가 직접 데이터 센터를 만들고 네트워크를 구성하는 것과 같은 효과를 가져갈 수 있게 합니다.

 

서브넷을 구성하면 VPC 안에서 논리적으로 구분된 대역들을 구성할 수 있으며, 서브넷은 또 Public 과 Private 으로 나뉘게 됩니다. Public subnet 은 인터넷 게이트웨이를 통해서 외부 인터넷에 연결될 수 있는 공간이며, Private 는 VPC 안에서만 접근 가능한 공간입니다. Private 대역이 보안에 유리하므로 보통 백엔드 서버들을 위치시킬 수 있습니다.

 

Private 에 있는 서버라도 인터넷에 접근해 외부 API 를 호출하거나 리소스를 받아가야할 필요가 있을 수도 있는데, 이때는 NAT 게이트웨이를 사용합니다. NAT 게이트웨이는 Private 에 위치한 리소스가 외부 인터넷에 연결할 수는 있지만, 외부에서는 이 Private 리소스에 연결을 시작할 수 없도록 합니다. NAT 게이트웨이는 Public 에 위치하여, Private 에서 외부로 향하는 요청을 받아 중개해줍니다.

 

EKS default VPC 은 아래와 같습니다. AWS 에서 권장하는 구성이 아래와 같이 Private, Public 서브넷을 가진 구성입니다.

https://aws.amazon.com/ko/blogs/containers/de-mystifying-cluster-networking-for-amazon-eks-worker-nodes/

 

앞서 아키텍처에서 살펴보았듯이, k8s control plane 은 aws 에서 관리하며, 우리가 생성한 Worker node 는 생성된 VPC 내에 위치해 있습니다. Worker node 에서 외부에 있는 control plane 과 통신하기 위해서는 API server 에 연결된 ENI 가 필요합니다. ENI(Elastic Network Interface) 는 Private, Public IP 주소, Mac 주소, 보안그룹 등을 가진 네트워크 카드로 컴퓨터의 랜카드와 같은 기능을 한다고 볼 수 있습니다. ENI 를 인스턴스에 연결하면 다른 네트워크 리소스와 통신할 수 있게 합니다. VPC 내부의 ENI 와 API server 를 연결했으므로, 이제 Worker node 는 API server 와 통신할 수 있게 됩니다. 사용자는 kubectl 같은 명령어를 인터넷을 통해 바로 control plane 으로 요청할 수 있습니다.

https://aws.amazon.com/ko/blogs/containers/de-mystifying-cluster-networking-for-amazon-eks-worker-nodes/

 

Instance type

t3.medium EC2 인스턴스를 Worker node 로 생성합니다.

Authentication

EKS 에서 alb ingress 를 생성하면 AWS 에서 LB 를 생성합니다. AWS 의 해당 리소스를 생성할 수 있는 권한이 있는지 AWS 는 체크해야합니다. 이러한 이유로 k8s 와 AWS 서비스 사이에 인증, 권한 메커니즘이 필요합니다. AWS 에서는 IAM 이라는 AWS 리소스에 엑세스할 수 있는 지 등의 권한 관리 체계를 가지고 있고, k8s 에는 Pod 가 API server 에 요청할 수 있는 권한을 부여할 수 있는 ServiceAccount 라는 개념이 있습니다.

 

이 둘을 연결하면 서로 다른 k8s, aws 권한 메커니즘이 연결될 수 있습니다. 이처럼 ServiceAccount를 사용하여 pod의 권한을 IAM Role로 제어할 수 있도록 하는 기능을 IRSA(IAM Role for Service Account) 라고 부릅니다.

 

OIDC 는 OAuth2.0 기반의 인증 프로토콜로 k8s 에서 사용하는 인증 방식입니다. ServiceAccount 에서 IAM 에 인증을 받아오는 방법으로 이 프로토콜을 사용하고 있습니다. 따라서 관련된 iam.withOIDC 와 같은 설정을 해주어야 합니다.

 

여기서는 aws-load-balancer-controller 에 권한을 부여했는데 이유는, aws-load-balancer-controller 가 Ingress 생성되는 것을 보고 aws 에 LB 생성을 요청해야하기 때문입니다.

https://aws.amazon.com/ko/blogs/containers/diving-into-iam-roles-for-service-accounts/

Data Persistence

AWS EBS CSI 드라이버도 추가해줍니다. 이는 EBS 를 k8s 의 임시 볼륨이나 Persistent 볼륨으로 사용할 수 있게 해줍니다.

External App Access

AWS 로드 밸런서 컨트롤러(LBC) 을 설치하고 Application Load Balancer(ALB) 를 동적으로 배포합니다. 관련해서는 아래에서 좀 더 살펴보겠습니다.

실습

클러스터 생성

위 cluster-config.yaml 로 eksctl 명령어를 통해 EKS 클러스터를 생성해보겠습니다.

eksctl create cluster -f cluster-config.yaml
...
2024-09-18 18:51:51 [✔]  EKS cluster "web-quickstart" in "ap-northeast-2" region is ready

 

앞서 살펴본 것과 같이 EKS default VPC 가 자동으로 아래와 같이 생성되었습니다.

 

각 AZ 별로 Public, Private 서브넷이 생성되었고, 그에 따른 라우팅 테이블과 NAT Gateway 도 생성됩니다.

Public 서브넷과 연결된 라우팅 테이블을 보면 192.168.0.0/16 은 생성된 VPC 내부 네트워크로 VPC 내부에서 서로 통신할 수 있도록 합니다. 0.0.0.0/0 은 인터넷 게이트웨이로 연결되어 외부와 통신할 수 있습니다.

 

Private 서브넷과 연결된 라우팅 테이블은 local 부분은 Public 과 같고 외부로 향하는 요청이 NAT Gateway 로 연결된 것을 볼 수 있습니다.

 

cluster-config.yaml 에 managedNodeGroup 개수를 2개로 설정하였고 EC2 항목을 보면 서로 다른 AZ 에 2개의 node 가 배치된 것을 확인할 수 있습니다. 두 인스턴스는 각 AZ 의 Public 서브넷에 생성되었습니다.

AWS Load Balancer Controller(LBC)를 사용하여 외부 액세스 설정

클러스터 내부의 애플리케이션 Pod 에 접근하기 위해서는 Elastic Load Balancers(ELB) 가 필요합니다. AWS 로드 밸런서 컨트롤러(LBC) 는 API server 를 통해 Ingress, service event 를 보면서 AWS 리소스 프로비저닝이 필요한 경우, 해당 리소스가 AWS 에 생성할 수 있도록 합니다. LBC 를 통해 생성할 수 있는 ELB 는 아래 두 가지입니다.

  • LoadBalancer type 의 service 를 생성하여 NLB (4L) LB 생성
  • Ingress alb 생성하여 ALB(7L) 생성

NLB 를 생성하면 NLB → Service → Pod, ALB 를 생성하면 ALB → Ingress → Service → Pod 흐름으로 요청이 전달됩니다.

 

참고로, AWS 에 종속적이지 않고 좀 더 유연한 라우팅 기능(URL rewrite 등)을 사용하기 위해 Nginx Ingress Controller 를 사용할 수도 있습니다. 이때는 NLB 를 생성하여 NLB → Nginx ingress controller → Service → Pod 흐름으로 구성할 수도 있습니다.

먼저 아래 명령어로 환경변수를 세팅해줍니다.

export CLUSTER_REGION=ap-northeast-2
export CLUSTER_VPC=$(aws eks describe-cluster --name web-quickstart --region ap-northeast-2 --query "cluster.resourcesVpcConfig.vpcId" --output text)

echo $CLUSTER_VPC
vpc-0f752fb85

 

LBC 는 helm 차트로 설치할 수 있습니다.

// Amazon EKS 차트 repo를 Helm에 추가
helm repo add eks https://aws.github.io/eks-charts
// 최신 차트를 사용하기 위해 repo 업데이트
helm repo update eks
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
    --namespace kube-system \
    --set clusterName=web-quickstart \
    --set serviceAccount.create=false \
    --set region=${CLUSTER_REGION} \
    --set vpcId=${CLUSTER_VPC} \
    --set serviceAccount.name=aws-load-balancer-controller
    
NAME: aws-load-balancer-controller
LAST DEPLOYED: Sat Sep 28 20:03:23 2024
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
AWS Load Balancer controller installed!

 

LBC Pod 가 생성된 것을 확인해볼 수 있습니다.

샘플 애플리케이션 배포

튜토리얼에 나오는 2048 샘플 애플리케이션을 배포해보겠습니다.

kubectl create namespace game-2048 --save-config

kubectl apply -n game-2048 -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.8.0/docs/examples/2048/2048_full.yaml

namespace/game-2048 configured
deployment.apps/deployment-2048 created
service/service-2048 created
ingress.networking.k8s.io/ingress-2048 created

 

배포된 형상은 아래와 같습니다.

---
apiVersion: v1
kind: Namespace
metadata:
  name: game-2048
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: game-2048
  name: deployment-2048
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: app-2048
  replicas: 5
  template:
    metadata:
      labels:
        app.kubernetes.io/name: app-2048
    spec:
      containers:
      - image: public.ecr.aws/l6m2t8p7/docker-2048:latest
        imagePullPolicy: Always
        name: app-2048
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  namespace: game-2048
  name: service-2048
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  type: NodePort
  selector:
    app.kubernetes.io/name: app-2048
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: game-2048
  name: ingress-2048
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
spec:
  ingressClassName: alb
  rules:
    - http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: service-2048
              port:
                number: 80

 

Ingress 가 생성되었으므로 ALB 도 생성되었습니다.

 

Ingress annotation 을 한번 살펴보면,

  • scheme: internet-facing or internal
    • 인터넷을 통해 접근 가능한지 아니면 내부에서만 접근 가능한지 여부
  • target-type: ip or instance
    • instance 일 경우, 트래픽을 kube-proxy 통해 Pod 로 가는 방식이고 ip 는 LB 에서 바로 Pod 로 트래픽을 보내서 kube-proxy 을 거치는 네트워크 홉을 없앤 방식입니다.

https://www.eksworkshop.com/docs/fundamentals/exposing/loadbalancer/ip-mode

 

추가적으로, Ingress 를 생성할 때마다 ALB 를 생성하는 것은 비효율적일 수 있습니다. ingressGroup(group.name) 애노테이션도 추가할 수 있는데, 이는 여러 Ingress 를 묶어 하나의 ALB 에서 처리할 수 있도록 합니다.

ALB

 

Ingress 가 생기고 ALB 가 만들어지면서 node EC2 에 보안그룹이 추가되었습니다.

node 보안그룹

 

로드밸런서의 보안규칙에도 해당 보안그룹이 추가되었는데요. 해당 보안규칙을 삭제하면 트래픽이 node 로 갈 수 없고 이는 ALB 생성 시에 자동으로 추가됩니다.

ALB 보안그룹

Multi AZ DB

위 튜토리얼에서는 AWS EBS CSI 드라이버를 통해 EBS 를 k8s volume 으로 사용하여 데이터를 저장합니다.

DB 를 사용해서 데이터의 영속성을 관리한다면 어떻게 할 수 있을까요?

한 AZ 전체 장애를 대비한다면, DB 와 같은 리소스도 여러 AZ 에서 배포되고 관리되어야 할 것입니다.

AWS RDS 를 통해 DB 를 Multi AZ 로 배포하고 한 AZ 의 장애를 가정하고 한번 테스트해보겠습니다.

먼저, RDS 배포 옵션은 아래와 같이 세가지가 있습니다.

단일 인스턴스

단일 인스턴스는 말 그대로 하나의 DB 인스턴스만 구성하는 방법입니다.

다중 AZ DB 인스턴스

 

다중 AZ DB 인스턴스는 다른 AZ 에 하나의 대기 DB 인스턴스를 배포하는 방법입니다.

이 Standby replica 는 읽기 전용으로는 사용할 수 없고, Primary 에 장애가 발생했을 때 자동으로 대신 Primary 로 승격되는 DB 입니다. 장애조치는 보통 60~120초 소요된다고 합니다. 장애조치 메커니즘은 DB 인스턴스를 가리키는 DNS 레코드를 Standby replica 를 바라보게 변경하는 방식으로 진행되며, 따라서 애플리케이션에서 DNS cache 를 하는 경우 TTL 을 장애 조치된 DB DNS 레코드를 바라볼 수 있도록 적절한 값으로 설정해주어야 합니다.

다중 AZ DB 클러스터

https://aws.amazon.com/ko/blogs/aws/amazon-rds-multi-az-db-cluster/

 

읽을 수 있는 복제 DB 인스턴스가 2개 있는 Amazon RDS의 반동기식 고가용성 배포 모드입니다. 다중 AZ DB 인스턴스는 커밋 전에 replica 로 부터 승인을 받아야 커밋을 할 수 있는데 반해, 반동기식이라는 것은 커밋 전에 두개의 replica 중 하나의 replica 로부터만 승인을 받았다면 커밋을 진행하는 방식입니다. 해당 배포 방식은 다중 AZ DB 인스턴스보다 2배 빠른 transaction commit latency 와 35초 이내의 자동 failover 를 가진다고 합니다.

failover 실습

다중 AZ DB 클러스터 옵션으로 MySQL RDS 를 배포합니다. 비용은 단일 DB 인스턴스보다 다중 AZ DB 인스턴스가 두배 가량이고 다중 AZ DB 클러스터는 세배까지는 아니지만 비용이 더 올라갑니다.

세개의 DB 인스턴스가 생성되었고 각각 서로 다른 AZ 에 위치해 있는 것을 확인할 수 있습니다. 이제 샘플앱을 따로 만들어서 한 AZ 의 DB, Pod 가 장애여도 애플리케이션이 서빙되는지 확인해보겠습니다.

 

여기서 사용한 샘플앱은 http 요청으로 간단하게 현재 Pod 가 위치해있는 AZ 와 DB 가 정상 작동하는지 확인하기 위해 접근 시간을 저장하고 다시 읽어 같이 반환하도록 했습니다.

 

DB Cluster 를 장애조치하고 AZ 에 있는 노드도 중지해보도록 하겠습니다.

 

약 30초 가량의 다운타임 후 다시 응답이 잘 오는 것을 볼 수 있습니다.

데이터베이스 탭을 보면 다른 Standby DB 인스턴스로 Primary 가 변경된 것도 확인할 수 있습니다.

 

ap-northeast-2a AZ 에 있는 노드도 재부팅해서 장애와 유사한 상황을 만들어 보도록 하겠습니다.

해당 ap-northeast-2a 에 있는 Pod 들은 비정상이되고 요청도 살아있는 AZ 로만 보내지는 것을 볼 수 있습니다.

 

10초씩 총 세번의 504 Gateway Time-out 이 난 후에 정상인 AZ 로 요청이 전달되는 것을 볼 수 있습니다.

504 Gateway Time-out 은 10초 뒤에 발생하는데 이는 ALB 의 idle timeout(연결 유휴 제한 시간) 을 10초(default: 1분)로 설정했기 때문입니다. 연결 유휴 제한 시간은 로드 밸런서가 연결을 닫기 전에 클라이언트 또는 대상 연결이 유휴 상태를 유지할 수 있는 시간으로, 현재 실험에서는 노드를 아예 재부팅 했으므로 요청에 대한 응답이 안와도 10초 동안은 기다리다가 Timeout 내게 됩니다.

의문..

왜 3번인지는 아직 명확하게 밝혀내지는 못했습니다. 더불어 Pod 에 readnessProbe 도 타이트하게 걸었는데(ReadinessGates 도 추가) 왜 그보다 오래 걸리는지, 현재 환경 및 실험 방법에서는 적용되지 않는 건지 좀 더 확인이 필요할 것 같습니다.

부록

AZ 간의 통신에 추가적인 네트워크 비용이 발생합니다. Multi AZ 구성을 하면 같은 AZ 에 있는 Pod 나 리소스에 요청을 해도 되는 것을 굳이 다른 AZ 로 요청을 전송해 불필요한 비용을 초래할 수 있습니다. 이를 Cross-AZ 라고 하며 Topology Aware Hint 기능을 사용하여 Cross-AZ 통신을 줄일 수 있습니다.

Cluster IP를 이용하여 Client Pod에서 Server Pod로 패킷 전송 시 Topology Aware Hint 기능을 적용하지 않는다면 kube-proxy가 설정한 iptables 규칙은 임의의 Server Pod로 패킷을 전송하여 Cross-AZ 통신이 발생하게 됩니다. Topology Aware Hint 기능을 사용한다면 kube-proxy에 의해 iptables 규칙이 자신과 동일한 AZ에 위치하고 있는 Pod에게만 패킷을 전송하도록 설정하기 때문에 Cross-AZ 통신이 발생하지 않습니다.

ref) https://aws.amazon.com/ko/blogs/tech/amazon-eks-reduce-cross-az-traffic-costs-with-topology-aware-hints/

https://aws.amazon.com/ko/blogs/tech/amazon-eks-reduce-cross-az-traffic-costs-with-topology-aware-hints/

apiVersion: v1
kind: Service
metadata:
  name: service
  annotations:
    service.kubernetes.io/topology-aware-hints: auto
...

 

NodePort 를 이용할 경우에도 동일한 문제가 발생할 수 있습니다. 앞서 Ingress 의 targetType 은 Instance 로 한다면, NodePort 를 통해 트래픽이 들어가고 kube-proxy 에서 임의의 AZ 에 있는 Pod 요청이 전달되어 Cross-AZ 통신이 발생할 수 있습니다. 이때도 Topology Aware Hint 를 사용하면 Cross-AZ 통신 문제를 방지할 수 있습니다.

https://aws.amazon.com/ko/blogs/tech/amazon-eks-reduce-cross-az-traffic-costs-with-topology-aware-hints/

 

reference

https://docs.aws.amazon.com/eks/latest/userguide

https://medium.com/wafflestudio/setup-k8s-cluster-with-aws-eks-in-snu-cse-dev-wafflestudio-1-91d620e66276

https://inpa.tistory.com/entry/AWS-%F0%9F%93%9A-RDS-%EC%8B%A4%EC%A0%84-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-Multi-AZ-Read-Replica

https://dgtlinfra.com/data-center-fires/

https://cwal.tistory.com/33

https://aws.amazon.com/ko/message/41926/

https://repost.aws/ko/questions/QUyN1UMa3XS9KXlLwAMNtCWw/which-is-better-multi-az-db-cluster-or-multi-az-db-instance-for-amazon-rds-for-postgresql

https://www.youtube.com/watch?v=5xyU7sA2Ajg

https://www.flashgrid.io/news/multi-az-vs-multi-region-in-the-cloud/

https://disaster-recovery.workshop.aws/en/services/containers/eks/eks-cluster-multi-region.html

https://aws.amazon.com/ko/blogs/database/part-1-scale-applications-using-multi-region-amazon-eks-and-amazon-aurora-global-database/

https://medium.com/@extio/kubernetes-authentication-with-oidc-simplifying-identity-management-c56ede8f2dec

https://kim-dragon.tistory.com/279

https://velog.io/@yenicall/AWS-VPC의-개념

https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.8/guide/ingress/annotations

https://www.eksworkshop.com/docs/fundamentals/exposing/loadbalancer/ip-mode

https://medium.com/@yakuphanbilgic3/demystifying-kubernetes-ingress-alb-vs-nginx-56db64962e93

https://nauco.tistory.com/89

https://aws.amazon.com/ko/blogs/containers/de-mystifying-cluster-networking-for-amazon-eks-worker-nodes/

https://aws.amazon.com/ko/blogs/tech/amazon-eks-reduce-cross-az-traffic-costs-with-topology-aware-hints/

https://aws.amazon.com/ko/blogs/database/amazon-rds-multi-az-with-two-readable-standbys-under-the-hood/