a story

[10] EKS Gateway API와 Amazon VPC Lattice 본문

EKS

[10] EKS Gateway API와 Amazon VPC Lattice

한명 2025. 4. 26. 03:31

이번 포스트에서는 Amazon VPC Lattice for Amazon EKS라는 주제로 학습한 내용을 작성해 보겠습니다.

먼저 쿠버네티스 환경의 네트워크 변화 과정을 살펴보고 기존 기술의 한계점을 바탕으로 Gateway API의 등장 배경을 알아보겠습니다.

Amazon EKS에서는 Gateway API의 구현체로 Amazon VPC Lattice를 사용합니다. EKS에서 Amazon VPC Lattice를 활용해 앞서 설명한 복잡한 쿠버네티스 네트워크 환경의 한계점을 어떻게 극복하는지 살펴보겠습니다.

 

목차

  1. 쿠버네티스 환경의 네트워크 변화
  2. Gateway API
  3. Amazon VPC Lattice
  4. Amazon VPC Lattice - Simple Client to Server Communication 실습

 

1. 쿠버네티스 환경의 네트워크 변화

쿠버네티스 환경의 네트워크 환경은 마이크로서비스 아키텍처의 발전과 함께 진화해 왔습니다.

 

1.1. 단일 쿠버네티스 클러스터의 네트워킹

단일 쿠버네티스 클러스터에서는 쿠버네티스 Service 리소스와 클러스터 내부 DNS 서비스인 CoreDNS를 통해 내부 서비스 간 통신을 구현하였고, 또한 Ingress 리소스를 통해서 외부 통신을 네이티브 하게 구현하였습니다.

이를 위해서 아래와 같은 방식을 사용하였습니다.

  • Service 리소스로 노출
    • ClusterIP, NodePort, Loadbalancer 타입의 서비스 구현
  • Ingress 리소스 활용
    • 경로 기반 라우팅으로 서비스 구조화
    • SSL/TLS Termination 기능으로 보안 강화

초기 단계에서는 대부분 Core 리소스를 통해 클러스터 내부 통신을 가능하게 하고, 또한 서비스를 외부 노출하는 데 중점을 두었습니다.

 

1.2. Service Mesh

단일 애플리케이션의 컨테이너화에서 진화해 각 서비스별 마이크로서비스가 점점 늘어나면서 서비스 간 연결이 복잡해게 됩니다. 이에 따른 네트워크 복잡성이 증가하고, 서비스의 공통 기능(Circuit Break, Retry, 타임아웃, 보안, 가시성 등)에 대한 요구사항이 생기게 됩니다.

서비스 메시는 이러한 요구사항을 구현한 기술로, 주요 구현체로는 Istio, Linkerd, Consul 등이 있습니다.

 

서비스 메시는 네트워크 레벨에서 서비스 간 통신을 추상화하고 통제하기 위해 아래와 같은 주요 기능을 제공합니다.

  • 트래픽 관리: 요청 라우팅, 트래픽 분할, Retry/타임아웃, Circuit Break 등을 통해 서비스 간 통신 흐름을 제어
  • 보안: mTLS를 통한 암호화 및 인증, 세밀한 접근 제어로 서비스 간 신뢰 보장
  • 가시성: 메트릭, 로그, 트레이싱을 통해 서비스 간 통신을 실시간 모니터링
  • 정책 및 제어: Rate limiting(서비스당 요청 수 제한), 접근 정책 등으로 네트워크 사용을 통제하고 보호

서비스 메시의 동작 방식은 Envoy와 같은 Proxy 컨테이너를 사이드카로 배치하고, 컨트롤 영역에서 정의한 설정을 바탕으로 데이터 영역인 Proxy 컨테이너가 애플리케이션 컨테이너의 진입점으로써 통신을 제어합니다.

 

아래는 Istio의 Service Mesh에 대한 설명으로, Proxy 사이드가 통신을 처리하게 됩니다.

출처: https://istio.io/latest/about/service-mesh/

 

서비스 메시의 구성 요소는 컨트롤 영역데이터 영역으로 나뉘며 아래와 같은 역할을 합니다.

  • 데이터 영역
    • 사이드카가 요청을 가로챔 → 요청을 별도의 네트워크 연결로 캡슐화 → 소스 Proxy 와 대상 Proxy 간에 안전하고 암호화된 채널을 설정
    • 서킷 브레이킹, 요청 재시도와 같은 기능을 구현하여 복원력을 높이고 서비스 성능 저하를 방지
  • 제어 영역
    • 서비스 메시 내의 모든 서비스를 추적하는 서비스 레지스트리 기능 수행
    • 신규 서비스에 대한 자동 검색 기능 및 비활성 서비스 제거 기능 수행
    • 지표, 로그, 분산 추적 정보와 같은 텔레메트리 데이터의 수집 및 집계

 

1.3. 기존 쿠버네티스 환경 네트워크 한계점

애플리케이션이 점차 진화함에 따라 하나의 클러스터가 확장되어 멀티 쿠버네티스 클러스터가 사용될 수도 있습니다.

또한 조직별로 담당하는 서비스가 달라지고, 이로 인해 다른 VPC와 쿠버네티스 클러스터를 운영하기 시작하면서, 서로 다른 VPC나 멀티 클러스터 간 애플리케이션의 통신이 문제가 되기도 합니다.

 

또한, 클라우드 환경에서 점차 마이크로 서비스가 확장되고 인프라 구성이 복잡해짐에 따라 아래와 같은 요구사항도 생겨났습니다.

  • 다양한 팀 간의 책임 분리(인프라 담당자, 애플리케이션 개발자, DevOps 엔지니어 등)가 필요해졌습니다.
  • 여러 VPC 또는 멀티 클러스터 환경에 걸친 리소스들을 일관되게 관리해야 했습니다.
  • 다양한 컴퓨팅 형태(인스턴스, 컨테이너, 서버리스 등)를 통합적으로 관리할 수 있는 네트워킹 레이어가 필요했습니다.

 

이러한 환경의 변화와 더불어 Ingress나 Service Mesh 또한 한계점이 있습니다.

 

Ingress의 한계

Ingress 리소스는 HTTP, HTTPS와 같은 L7 트래픽에 최적화 되어있고, gRPC 및 TCP, UDP와 같은 비 L7 프로토콜에 대한 라우팅 기능은 제공이 어려운 한계점이 있습니다.

 

또한 Ingress에서는 각 구현체별로 제공하는 기능에 차이가 있고 각 제품별 표준화된 기능을 제공하기 어렵습니다. 이로 인해 Ingress의 고급 기능(인증, 속도 제한 정책, 고급 트래픽 관리 등)은 각 제품 별(Nginx, HAProxy 등) 사용자 정의 어노테이션을 통해서 구현을 하는 방식을 사용했습니다.

이로 인해서 점차 Annotation이 복잡해지고 표준화가 어려워지며, 또한 한 구현체에서 다른 구현체로서의 이식성에 한계가 존재했습니다.

 

여기서 각 구현체가 제공하는 기능을 Ingress를 생성하는 개발자가 직접 작성을 하게되는 데, 이로인해 인프라 영역의 일부 설정을 개발담당자가 확인해야 하는 점도 불편함이 있습니다.

 

Service Mesh의 한계

서비스 메시는 주로 East-West 트래픽(서비스 간 내부 통신)에 초점을 맞추어 설계되어, North-South 트래픽(외부-내부 통신)에 대한 기능이 제한적이었습니다.

 

또한 구분된 VPC에 EKS 클러스터가 배치되는 경우, 이들을 연결하기 위해서는 VPC Peering 나 TGW(Tranist Gateway)가 필요하게 되어, 복잡한 설정과 네트워크 리소스들 점점 늘어나게 됩니다.

더불어 팀이나 서비스별로 구분된 AWS 계정을 사용할 경우, 각각 교차 계정 액세스 설정이 필요하게 되는데, 이 또한 권한 관리의 어려움으로 남게 됩니다.

 

서비스 메시는 사이드카 Proxy 배포가 기본적으로 필요해, 멀티 VPC 클라우드 환경에서 네트워크 복잡도가 증가하였습니다. 이로 인해 멀티 클러스터와 멀티 서비스 메시의 수많은 프록시 운영과 관리의 어려움이 증가하였습니다.

 

 

2. Gateway API

이러한 쿠버네티스 환경의 진화 속에서 Gateway API가 해결하는 문제는 아래와 같습니다.

  • 역할 기반 설계: 인프라 관리자, 클러스터 운영자, 애플리케이션 개발자에 대해서 역할 기반으로 리소스를 관리할 수 있게 됩니다.
  • 범용성: HTTP, HTTPS, gRPC 등 다양한 프로토콜을 지원하고 확장성 있게 설계되었습니다.
  • 표준화: Kubernetes Ingress와 같이 Portable 한 표준 API가 되도록 설계되었습니다.
  • 확장성: 멀티 클러스터 환경 및 다양한 VPC 간의 원활한 네트워크 통합이 가능하도록 설계되었습니다. (다만, 이는 Gateway API의 일반적인 특성이라기보다는 이후 살펴볼 Amazon VPC Lattice의 특성에 가깝습니다)

 

쿠버네티스의 Gateway API는 아래와 같은 리소스로 구성됩니다. 이를 통해서 Ingress에 비해서 각 리소스를 담당하는 역할들을 분리할 수 있게 되었습니다.

출처: https://gateway-api.sigs.k8s.io/

 

Ingress 리소스는 네트워크 설정, 인증, 인증서 등 중요한 인프라 설정까지도 개발자가 Ingress 안에서 작성해야 하고, 기반 인프라로 제공되는 Ingress Controller에서 제공하는 기능을 파악해 Ingress에서 어노테이션으로 처리해야 하는 부담이 있었습니다.

 

반면 Gateway API는 계층적 구조를 통해 인프라 관리자는 GatewayClass와 Gateway를 관리하며 인프라 수준의리소스를 관리하고, 애플리케이션 개발자는 다양한 Route를 통해 자신의 애플리케이션에 대한 세부 라우팅 규칙을 독립적으로 정의할 수 있습니다.

 

 

Gateway API도 다른 Kubernetes 컴포넌트와 마찬가지로 Controller를 통해 동작합니다. 여러 벤더 별 Gateway API Controller 구현체를 제공하고 있으며 AWS에서는 AWS Gateway API Controller를 제공하고 있습니다.

이때 AWS Gateway API Controller는 Amazon VPC Lattice를 구현체로 가집니다. 다음 절에서 Amazon VPC Lattice에 대해서 살펴보겠습니다.

 

 

3. Amazon VPC Lattice

Amazon VPC Lattice가 해결하는 문제는 서로 다른 VPC 간의 네트워크 연결을 간소화하고 보안 및 모니터링을 제공하는 데 있습니다.

Amazon VPC Lattice가 제공하는 주요 기능과 장점은 아래와 같습니다.

  • 복잡한 네트워크 구성을 단순화해서 쉽게 사용할 수 있습니다.
  • 여러 VPC, EC2 인스턴스, 컨테이너, 서버리스로 구성한 애플리케이션의 네트워크 구성을 중앙 집중화 할 수 있습니다.
  • 별도의 사이드카 프록시를 구성할 필요가 없습니다.
  • IAM 및 SigV4를 통해 각 애플리케이션으로의 보안 구성을 손쉽게 적용할 수 있습니다.
  • CloudWatch, S3, Kinesis Data Firehose를 통해 쉽게 로깅, 트래픽 패턴 분석 등을 수행할 수 있습니다.

 

아래 그림과 같이 서로 다른 VPC에서 생성된 서비스를 VPC Lattice의 Service Network 레이어에서 추상화여 서로 다른 VPC에서 연결이 가능하도록 합니다. 그림의 우측에 설명된 것과 같이, 서로 다른 AWS 계정의 VPC도 연결이 가능합니다. 또한 이렇게 추상화된 서비스의 대상(Target)은 EC2, ECS, EKS, Lambda 까지 확장됩니다.

 

출처: https://aws.amazon.com/ko/blogs/korea/simplify-service-to-service-connectivity-security-and-monitoring-with-amazon-vpc-lattice-now-generally-available/

 

Amazon VPC Lattice는 EKS를 위한 전용 서비스가 아니기 때문에, 구성요소는 조금 복잡할 수 있습니다. 다만 EKS의 Gateway API Controller를 통해 EKS의 Gateway API의 리소스를 생성하면 Amazon VPC Lattice의 각 구성요소가 생성/구성된다고 보시면 됩니다.

VPC Lattice의 구성요소에 대해서 간략히 아래와 같이 정리할 수 있습니다.

 

Service Network

서비스 네트워크는 논리적인 서비스의 경계입니다. 여러 서비스를 논리적으로 그룹화하고 이들 간의 통신을 관리합니다. 하나 이상의 VPC를 서비스 네트워크에 연결하여 해당 네트워크 내의 서비스 간 통신을 가능하게 합니다.

동일한 서비스 네트워크 연결된 VPC에서 클라이언트와 서비스는 권한이 부여된 경우 서로 통신할 수 있습니다.

 

출처: https://www.gateway-api-controller.eks.aws.dev/latest/concepts/overview/#service-directory-networks-policies-and-gateways

 

Service

VPC Lattice 서비스는 인스턴스, 컨테이너, 서버리스 환경에 구성되는 애플리케이션 단위를 의미합니다. 쿠버네티스의 서비스와 같이 각 대상에서 구성된 애플리케이션이 서비스 네트워크에서 VPC Lattice 서비스로 노출되는 것으로 이해할 수 있습니다.

 

출처: https://www.gateway-api-controller.eks.aws.dev/latest/concepts/overview/#service-directory-networks-policies-and-gateways

 

Service Directory

서비스 디렉터리는 모든 VPC Lattice 서비스를 중앙에서 검색하고 관리할 수 있는 카탈로그입니다. 개발자와 운영팀이 사용 가능한 서비스를 쉽게 찾고 접근할 수 있도록 지원합니다.

 

Auth Policy

Auth Policy는 VPC Lattice 서비스에 대한 액세스를 제어하는 IAM 기반 정책입니다. 이를 통해 특정 IAM 보안 주체나 역할이 VPC Lattice 서비스에 접근할 수 있는지 여부를 세밀하게 제어할 수 있습니다.

 

 

AWS Gateway API Controller는 Gateway API에 의해 정의된 사용자 지정 리소스를 확장하여 Kubernetes API를 사용하여 VPC Lattice 리소스를 생성합니다. 이 Controller가 클러스터에 설치되면 Controller는 Gateway API의 리소스(Gateway 및 Route)의 생성을 감시하고 적절한 Amazon VPC Lattice 오브젝트를 프로비저닝 합니다.

 

이를 통해 사용자는 커스텀 코드를 작성하거나 사이드카 Proxy를 관리할 필요 없이 Kubernetes API를 사용하여 VPC Lattice Service, VPC Lattice Service Network 및 Target Group을 구성할 수 있습니다.

 

아래와 같이 Gateway API 리소스를 생성하면 Amazon VPC Lattice의 각 구성 요소가 구성됩니다.

출처: https://aws.amazon.com/ko/blogs/containers/introducing-aws-gateway-api-controller-for-amazon-vpc-lattice-an-implementation-of-kubernetes-gateway-api/

 

 

이제 다음 장에서 Amazon VPC Lattice를 실습해 보겠습니다.

 

 

4. Simple Client to Server Communication 실습

해당 실습은 아래 문서를 바탕으로 실습하였습니다.

https://aws-ia.github.io/terraform-aws-eks-blueprints/patterns/network/client-server-communication/

 

본 실습은 Client 역할을 하는 EC2 인스턴스를 위한 Client VPC와 서버로써 서비스를 제공하는 EKS VPC를 배포합니다. EKS에 배포된 애플리케이션은 Gateway API를 통해 Amazon VPC Lattice로 클라이언트에 노출됩니다. 또한 EKS에 배포된 External DNS add-on을 통해 Amazon Route53으로 노출된 서비스에 대한 도메인 이름을 구성합니다.

 

출처: https://aws-ia.github.io/terraform-aws-eks-blueprints/patterns/network/client-server-communication/

 

실습 환경은 Amazon EKS Blueprints for Terraform에서 제공하여 Terraform이 실행 가능한 환경에서 진행합니다.

아래와 같이 terraform 코드를 준비하고, terraform 프로비저닝을 준비합니다.

git clone https://github.com/aws-ia/terraform-aws-eks-blueprints.git
cd terraform-aws-eks-blueprints/patterns/vpc-lattice/client-server-communication

 

해당 코드는 기본적으로 us-west-2를 기준으로 작성되어 있으므로, 필요한 경우 main.tf에서 region 값을 변경하시면 됩니다.

 26
 27 locals {
 28   name   = basename(path.cwd)
 29   region = "ap-northeast-2" # 수정
 30
 31   cluster_vpc_cidr = "10.0.0.0/16"
 32   client_vpc_cidr  = "10.1.0.0/16"
 33   azs              = slice(data.aws_availability_zones.available.names, 0, 3)
 34

 

terraform을 초기화하고 배포합니다.

terraform init

terraform apply -target="module.client_vpc" -auto-approve
terraform apply -target="module.cluster_vpc" -auto-approve
terraform apply -target=aws_route53_zone.primary -auto-approve

terraform apply -target="module.client_sg" -auto-approve
terraform apply -target="module.endpoint_sg" -auto-approve

terraform apply -target="module.client" -auto-approve
terraform apply -target="module.vpc_endpoints" -auto-approve

terraform apply -target="module.eks" -auto-approve
terraform apply -target="module.addons" -auto-approve

terraform apply -auto-approve

 

Terraform을 통해 배포된 실습 환경은 Client VPC와 Client용의 EC2, EKS VPC와 서버 애플리케이션이 실행되는 EKS, 그리고 VPC Lattice의 서비스 네트워크까지 사전에 구성을 진행합니다.

 

또한 Helm 프로바이더를 통해서 필요한 애플리케이션 또한 EKS에 배포하도록 되어 있습니다.

~/terraform-aws-eks-blueprints/patterns/vpc-lattice/client-server-communication# tree
.
├── README.md
├── assets
│   └── diagram.png
├── charts
│   └── demo-application
│       ├── Chart.yaml
│       └── templates
│           ├── deployment.yaml
│           ├── gateway-class.yaml
│           ├── gateway.yaml
│           ├── httproute.yaml
│           └── service.yaml
├── client.tf
├── eks.tf
├── lattice.tf
├── main.tf
├── outputs.tf
├── variables.tf
└── versions.tf

 

그러하므로, 실제로 배포를 하는 과정 자체보다는 생성된 리소스를 바탕으로 설명을 이어 나가겠습니다.

배포가 완료되면 아래와 같이 kubeconfig을 설정합니다.

aws eks update-kubeconfig --name client-server-communication --alias client-server-communication --region ap-northeast-2

 

이후 생성된 클러스터에서 생성된 노드와 파드를 확인하겠습니다.

kubectl get no -owide
NAME                                             STATUS   ROLES    AGE   VERSION               INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                       KERNEL-VERSION                    CONTAINER-RUNTIME
ip-10-0-13-51.ap-northeast-2.compute.internal    Ready    <none>   22m   v1.30.9-eks-5d632ec   10.0.13.51    <none>        Amazon Linux 2023.7.20250414   6.1.132-147.221.amzn2023.x86_64   containerd://1.7.27
ip-10-0-29-200.ap-northeast-2.compute.internal   Ready    <none>   22m   v1.30.9-eks-5d632ec   10.0.29.200   <none>        Amazon Linux 2023.7.20250414   6.1.132-147.221.amzn2023.x86_64   containerd://1.7.27
ip-10-0-32-36.ap-northeast-2.compute.internal    Ready    <none>   22m   v1.30.9-eks-5d632ec   10.0.32.36    <none>        Amazon Linux 2023.7.20250414   6.1.132-147.221.amzn2023.x86_64   containerd://1.7.27

kubectl get po -A
NAMESPACE                           NAME                                                              READY   STATUS    RESTARTS   AGE
apps                                server-6d44dd47-pbp9w                                             1/1     Running   0          117s
apps                                server-6d44dd47-qf2t5                                             1/1     Running   0          117s
aws-application-networking-system   aws-gateway-api-controller-aws-gateway-controller-chart-796rfqv   1/1     Running   0          7m14s
aws-application-networking-system   aws-gateway-api-controller-aws-gateway-controller-chart-79hqg6c   1/1     Running   0          7m14s
external-dns                        external-dns-555c676b8-hx7wk                                      1/1     Running   0          7m12s
kube-system                         aws-node-47vct                                                    2/2     Running   0          17m
kube-system                         aws-node-5tqg5                                                    2/2     Running   0          17m
kube-system                         aws-node-lthxz                                                    2/2     Running   0          17m
kube-system                         coredns-5b9dfbf96-v94zg                                           1/1     Running   0          21m
kube-system                         coredns-5b9dfbf96-w2jkd                                           1/1     Running   0          21m
kube-system                         kube-proxy-jnnjs                                                  1/1     Running   0          17m
kube-system                         kube-proxy-pfmfx                                                  1/1     Running   0          17m
kube-system                         kube-proxy-vk4ff                                                  1/1     Running   0          17m

 

실행 중인 파드를 보면 addon으로 External DNS와 AWS Gateway API Controller가 배포된 것을 확인할 수 있습니다. 또한 샘플 애플리케이션이 server 디플로이먼트가 apps 네임스페이스 실행 중입니다.

 

이번 주제의 중점인 VPC를 살펴보면 아래와 같이 2개의 VPC가 생성되었습니다.

 

terraform의 main.tf에서 이들의 IP대역이 정의되어 있습니다.

locals {
  name   = basename(path.cwd)
  region = "ap-northeast-2"

  cluster_vpc_cidr = "10.0.0.0/16"
  client_vpc_cidr  = "10.1.0.0/16"
  azs              = slice(data.aws_availability_zones.available.names, 0, 3)

  tags = {
    Blueprint  = local.name
    GithubRepo = "github.com/aws-ia/terraform-aws-eks-blueprints"
  }
}

 

VPC의 PrivateLink and Lattice에서 Service Network를 살펴보면 my-service라는 서비스 네트워크가 생성되어 있습니다.

 

my-services에서 VPC associations를 살펴보면 생성된 Client VPC와 Cluster VPC가 연계된 것을 확인할 수 있습니다.

 

이는 terraform 코드 중 lattices.tf에 정의된 내용으로, VPC에서 Amazon VPC Lattice를 사용하려면 사전에 VPC Lattice의 서비스 네트워크와 VPC의 연결이 필요한 것을 알 수 있습니다.

resource "aws_vpclattice_service_network" "this" {
  name      = "my-services"
  auth_type = "NONE"

  tags = local.tags
}

resource "aws_vpclattice_service_network_vpc_association" "cluster_vpc" {
  vpc_identifier             = module.cluster_vpc.vpc_id
  service_network_identifier = aws_vpclattice_service_network.this.id
}

resource "aws_vpclattice_service_network_vpc_association" "client_vpc" {
  vpc_identifier             = module.client_vpc.vpc_id
  service_network_identifier = aws_vpclattice_service_network.this.id
}

resource "time_sleep" "wait_for_lattice_resources" {
  depends_on = [helm_release.demo_application]

  create_duration = "120s"
}

 

이 Lattice의 서비스 네트워크는 Gateway API의 Gateway 리소스에 해당합니다.

apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
  name: my-services
  namespace: apps
spec:
  gatewayClassName: amazon-vpc-lattice
  listeners:
    - name: http
      protocol: HTTP
      port: 80

 

그리고 VPC의 PrivateLink and Lattice에서 Lattice services를 살펴보면 생성된 Lattice 서비스를 확인할 수 있습니다.

 

앞선 Gateway API와 VPC Lattice 컴포넌트 연계를 살펴볼 때, Route에 해당하는 것을 알 수 있습니다.

apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: server
  namespace: apps
spec:
  hostnames:
    - server.example.com
  parentRefs:
    - name: my-services
      sectionName: http
  rules:
    - backendRefs:
        - name: server
          kind: Service
          port: 8090
      matches:
        - path:
            type: PathPrefix
            value: /

 

실제 VPC 서비스를 진입하여 Routing을 살펴보면 아래의 정보를 확인할 수 있습니다.

 

트래픽이 Forward 되는 Target Group을 살펴보면, 아래와 같이 대상을 확인할 수 있습니다.

 

쿠버네티스의 생성된 서비스의 엔드포인트가 Target으로 등록된 것을 알 수 있습니다.

kubectl describe svc -n apps
Name:              server
Namespace:         apps
Labels:            app.kubernetes.io/managed-by=Helm
Annotations:       meta.helm.sh/release-name: demo-application
                   meta.helm.sh/release-namespace: apps
Selector:          app=server
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                172.20.245.38
IPs:               172.20.245.38
Port:              <unset>  8090/TCP
TargetPort:        8090/TCP
Endpoints:         10.0.12.82:8090,10.0.27.112:8090
Session Affinity:  None
Events:            <none>

 

생성된 Gateway API의 리소스를 살펴보겠습니다.

kubectl get gatewayclass
NAME                 CONTROLLER                                              ACCEPTED   AGE
amazon-vpc-lattice   application-networking.k8s.aws/gateway-api-controller   True       32m

kubectl get gateway -n apps
NAME          CLASS                ADDRESS   PROGRAMMED   AGE
my-services   amazon-vpc-lattice             True         31m

kubectl get httproute -n apps
NAME     HOSTNAMES                AGE
server   ["server.example.com"]   32m

 

 

이제 생성된 EC2를 통해서 직접 EKS에서 생성한 Gateway 서비스로 호출을 해보겠습니다.

EC2는 Session Manager를 통해서 접근하기 위해서 Instance에서 Connect>Session Manager로 접속합니다. EC2는 Client VPC에 생성된 것을 알 수 있습니다.

sh-4.2$ hostname
ip-10-1-8-29.ap-northeast-2.compute.internal
sh-4.2$ ip -br -c a
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             10.1.8.29/20 fe80::1a:91ff:fee8:e4b1/64

 

EC2가 위치한 VPC 또한 VPC Lattice의 서비스 네트워크에 연결되어 있으므로, 아래와 같이 연결이 가능합니다.

sh-4.2$ nslookup server.example.com
Server:         10.1.0.2
Address:        10.1.0.2#53

Non-authoritative answer:
server.example.com      canonical name = server-apps-0af7ca50d301362d4.7d67968.vpc-lattice-svcs.ap-northeast-2.on.aws.
Name:   server-apps-0af7ca50d301362d4.7d67968.vpc-lattice-svcs.ap-northeast-2.on.aws
Address: 169.254.171.0
Name:   server-apps-0af7ca50d301362d4.7d67968.vpc-lattice-svcs.ap-northeast-2.on.aws
Address: fd00:ec2:80::a9fe:ab00

sh-4.2$ curl -i http://server.example.com
HTTP/1.1 200 OK
date: Fri, 25 Apr 2025 17:59:25 GMT
content-length: 52
content-type: text/plain; charset=utf-8

Requsting to Pod(server-6d44dd47-qf2t5): server pod
sh-4.2$ curl -i http://server.example.com
HTTP/1.1 200 OK
date: Fri, 25 Apr 2025 17:59:42 GMT
content-length: 52
content-type: text/plain; charset=utf-8

 

접근 테스트를 하면서 server 측 로그를 살펴보면 lattice를 통해 연결된 로그가 남는 것을 알 수 있습니다. 아래를 보면 XFF에 Client IP가 EC2의 IP인 것을 알 수 있습니다.

kubectl logs -f deployment/server -n apps --all-containers=true --since=1m
...
2025/04/25 17:59:44 Receiving %!(EXTRA *http.Request=&{GET / HTTP/1.1 1 1 map[Accept:[*/*] User-Agent:[curl/8.3.0] X-Amzn-Lattice-Network:[SourceVpcArn=arn:aws:ec2:ap-northeast-2:430118812536:vpc/vpc-0462a13d1bd5329ce] X-Amzn-Lattice-Target:[ServiceArn=arn:aws:vpc-lattice:ap-northeast-2:430118812536:service/svc-0af7ca50d301362d4; ServiceNetworkArn=arn:aws:vpc-lattice:ap-northeast-2:430118812536:servicenetwork/sn-0939f55c8c47c81f1; TargetGroupArn=arn:aws:vpc-lattice:ap-northeast-2:430118812536:targetgroup/tg-029eaf68f9bcc9c9f] X-Amzn-Source-Vpc:[vpc-0462a13d1bd5329ce] X-Forwarded-For:[10.1.8.29]] {} <nil> 0 [] false server.example.com map[] map[] <nil> map[] 169.254.171.193:1684 / <nil> <nil> <nil> 0xc000448040})

 

실습을 마무리하고 리소스를 정리하도록 하겠습니다. 참고로 Route53에 생성된 Private zone은 레코드가 있는 경우 삭제가 이뤄지지 않습니다. EKS에 생성된 오브젝트들을 먼저 삭제하고, 이후에 terraform으로 AWS 리소스를 삭제하시기 바랍니다.

terraform destroy -target="module.addons" -auto-approve
terraform destroy -target="module.eks" -auto-approve

terraform destroy -target="module.vpc_endpoints" -auto-approve
terraform destroy -target="module.client" -auto-approve

terraform destroy -target="module.endpoint_sg" -auto-approve
terraform destroy -target="module.client_sg" -auto-approve

terraform destroy -target=aws_route53_zone.primary -auto-approve
terraform destroy -target="module.cluster_vpc" -auto-approve
terraform destroy -target="module.client_vpc" -auto-approve

terraform destroy -auto-approve

 

 

마무리

이번 포스트를 통해서 Amazon VPC Lattice라는 비교적 신규 기능을 체험해 볼 수 있었습니다. 복잡해지는 VPC 구성에서 Peering이나 Transit Gateway가 없이도 Amazon VPC Lattice를 통해서 간결한 통신이 가능해질 것으로 보입니다.

또한 EKS의 Gateway API Controller는 Amazon VPC Lattice를 구현체로 사용하게 되어, Amazon VPC Lattice이 제공하는 장점을 EKS에서도 그대로 사용할 수 있습니다. 이로써 멀티 클러스터 간의 서비스 연결에 도움을 받을 수 있을 것입니다.

 

본 포스팅은 12주간 진행되었던 AEWS(Amazon EKS Workshop Study) 3기를 진행하면서 작성하였습니다.

Amazon EKS의 각 요소들을 살펴보고 또한 다양한 신규 기능과 쿠버네티스 에코시스템을 두루 살펴볼 수 있는 좋은 기회였습니다.

 

그럼 긴 여정을 마무리하고 다음 포스트로 다시 찾아뵙겠습니다.

728x90

'EKS' 카테고리의 다른 글

[9] EKS GPU 리소스 활용  (0) 2025.04.20
[8] EKS Upgrade  (0) 2025.04.02
[7] EKS Fargate  (0) 2025.03.23
[6] EKS의 Security - EKS 인증/인가와 Pod IAM 권한 할당  (0) 2025.03.16
[5-2] EKS의 오토스케일링 Part2  (0) 2025.03.07