| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- EC2
- 테라폼 캐시
- EBS 최적화
- docker -i -t
- MFA 인증
- Authenticator
- 테라폼 자동완성
- docker 상태
- Mac Terraform
- 볼륨추가
- xfs_quota
- ebs 마운트
- AWS EBS
- 컨테이너 터미널 로그아웃
- /etc/fstab 설정
- 볼륨 연결
- /etc/fstab 뜻
- Terrafrom
- 컨테이너 터미널
- AWS
- epxress-generator
- 테라폼 맥
- 디스크 성능테스트
- 테라폼 설치
- ebs 재부팅
- MFA 분실
- 리눅스
- 리눅스 시간대
- 텔레메트리란
- EBS
- Today
- Total
I got IT
EKS on VPC Lattice 본문
※ 해당 글은 가시다님의 AEWS 스터디 내용을 참고하고 스터디 협력자 이신 AWS 최영락 님의 도움으로 워크샵 실습을 내용을 토대로 작성하였습니다.
들어가며
서비스 디스커버리와 서비스 메시의 대두
Service Discovery

애플리케이션이 진화하고, 조직이 발전하면서 서비스들이 독자적인 VPC 및 Kubernetes 클러스터에 운영되기 시작하면서 클러스터 운영자들은 이런 VPC 간 / 클러스터 간의 애플리케이션 네트워킹에 대해서 고민하게 되었습니다.
애플리케이션 끼리 통신을 하기 위해선 가장 먼저 내가 통신하고 싶은 서비스 혹은 마이크로 서비스가 어디에 있는지를 아는 것이 선행 되어야 합니다.

하지만 쿠버네티스 환경에서는 파드의 IP가 유동적이므로 이를 서비스 라는 상위 스키마를 통해 접근 가능하도록 해주는 것이 Service Discovery의 개념입니다.
Service Discovery 패턴
- Service Discovery 패턴
- 클라이언트 사이드
- 클라이언트가 직접 서비스 레지스트리를 쿼리하여 서비스 위치를 찾는 방식(예: Netflix Eureka, Spring Cloud
- 클라이언트 사이드

- 서버 사이드
- 로드 밸런서가 서비스 레지스트리를 쿼리하고 클라이언트 요청을 적절한 서비스로 라우팅

서비스 메시
Kubernetes는 기본적으로 Service Discovery, DNS 기반 로드밸런싱, Liveness/Readiness Probe
등 강력한 기능을 제공하지만, 서비스 간 보안, 트래픽 라우팅, 장애 복구, 관찰성과 같은 고급 통신 제어 기능은 기본적으로 제공하지 않습니다.
서비스 메시는 다음과 같은 기능을 제공하고 Kubernetes 환경에서 마이크로서비스 간 통신을 안전하고 효율적으로 운영하기 위해 서비스 메시가 필요합니다.
✅ 1. mTLS 기반의 서비스 간 암호화 및 인증
- Zero Trust 보안 원칙에 따라 서비스 간 통신을 기본적으로 암호화하고,
- 서비스 ID 기반의 상호 인증(mTLS)을 제공
✅ 2. 정책 기반 트래픽 제어 (A/B 테스트, Canary 등)
- 트래픽을 버전, 요청 속성, 사용자 조건에 따라 유연하게 라우팅
- 안전한 배포 전략 구현 가능
✅ 3. 강력한 관찰성 (Observability)
- 각 서비스 간 요청/응답의 메트릭, 로그, 트레이싱을 자동 수집
- 별도의 로깅/모니터링 구현 없이도 서비스 간 성능과 오류 추적
✅ 4. 자동 재시도, 타임아웃, Circuit Breaker
- 네트워크 장애나 서비스 일시적 문제에 대응하기 위한 탄력적인 통신 제어 가능
✅ 5. 통합된 통신 정책 관리
- RBAC, Rate limit, ACL 등 네트워크 관련 정책을 중앙에서 일관되게 관리
서비스 메시의 동작원리

컨테이너 애플리케이션 앞에 AWS AppMesh, Istio, Linkerd 등의 사이드카 프록시 컨테이너를 배치합니다.
이를 통해 컨테이너 애플리케이션으로 들어오고 나가는 모든 트래픽은 프록시 컨테이너를 통해 라우팅 되도록 합니다.
해당 프록시 컨테이너는 다음과 같은 역할을 수행합니다.
- 데이터 영역
- 사이드카가 요청을 가로챔 → 요청을 별도의 네트워크 연결로 캡슐화 → 소스 프록시와 대상 프록시 간에 안전하고 암호화된 채널을 설정
- 서비스 간 로우 레벨 메시징을 처리
- 서킷 브레이킹, 요청 재시도와 같은 기능을 구현하여 복원력을 높이고 서비스 성능 저하를 방지
- 제어 영역
- 메시 내의 모든 서비스를 추적하는 서비스 레지스트리 기능 수행
- 신규 서비스 자동 검색 기능 및 비활성 서비스 제거 기능 수행
- 지표, 로그, 분산 추적 정보와 같은 텔레메트리 데이터의 수집 및 집계
Service Discovery와 Service Mesh의 한계점
Service Discovery 및 Ingress의 한계
- 제한된 라우팅 기능:
- 호스트 및 경로 기반 라우팅만 지원하며, 헤더나 메서드 기반의 정교한 라우팅은 불가능했습니다.
- HTTP, HTTPS와 같은 L7 트래픽에 최적화 되어있어 gRPC 및 TPC, UDP와 같은 비 L7 프로토콜에 대한 라우팅 기능이 제한적이었습니다.
- 고급 기능(인증, 속도 제한 정책, 고급 트래픽 관리 등)을 사용하려면 벤더별(AWS, NGINX, HAProxy 등) 사용자 정의 어노테이션이 필요하여 이식성과 표준화에 한계가 존재했습니다.
Service Mesh의 한계
- 주로 East-West 트래픽(서비스 간 내부 통신)에 초점을 맞추어 설계되어 North-South 트래픽(외부-내부 통신)에 대한 기능이 제한적이였습니다.
- Amazon EKS의 경우, VPC Peering 및 TGW가 필요 → 점점 늘어나는 설정들과 네트워크 리소스들
- 여러 AWS 계정을 사용할 경우, 각각 교차 계정 액세스 설정이 필요 → 권한 관리의 어려움
- 사이드카 프록시 배포가 필수적이며, 멀티 VPC 클라우드 환경에서 네트워크 복잡도가 증가하였습니다. (멀티 클러스터, 멀티 메시의 수많은 프록시 운영 및 관리의 어려움)
또한, 클라우드 환경에서 점차 마이크로 서비스가 확장되고 인프라 구성이 복잡해짐에 따라 아래와 같은 요구사항도 생겨났습니다.
- 다양한 팀 간의 책임 분리(인프라 담당자, 애플리케이션 개발자, DevOps 엔지니어 등)가 필요해졌습니다. (RBAC)
- 여러 VPC 또는 멀티 클러스터 환경에 걸친 리소스들을 일관되게 관리해야 했습니다.
- 다양한 컴퓨팅 형태(인스턴스, 컨테이너, 서버리스 등)를 통합적으로 관리할 수 있는 네트워킹 레이어가 필요했습니다.
Gateway API의 등장 🔗
이러한 한계를 극복하기 위해 SIG-NETWORK 커뮤니티에서 Gateway API가 고안되었습니다. Gateway API는 다음과 같은 목표를 가지고 설계되었습니다.
이러한 한계를 극복하기 위해 SIG-NETWORK 커뮤니티에서 Gateway API가 고안되었습니다. Gateway API는 다음과 같은 목표를 가지고 설계되었습니다.
- 역할 기반 설계: 인프라 관리자, 클러스터 운영자, 애플리케이션 개발자 각각의 요구사항을 반영할 수 있도록 설계되었습니다.
- 범용성: HTTP, HTTPS, gRPC 등 다양한 프로토콜을 지원하고 확장성 있게 설계되었습니다.
- 표준화: Kubernetes Ingress와 같이 포터블한 표준 API가 되도록 설계되었습니다.
- 확장성: 멀티 클러스터 환경 및 다양한 VPC 간의 원활한 네트워크 통합이 가능하도록 설계되었습니다.
Gateway API의 주요 구성요소

- 공통 구성을 가진 게이트웨이 집합을 정의하며, 이 클래스를 구현하는 컨트롤러에 의해 관리됩니다.
- 게이트웨이는 각기 다른 컨트롤러에 의해 다양한 구성으로 구현될 수 있습니다. 게이트웨이는 반드시 해당 클래스를 구현하는 컨트롤러의 이름을 포함하는 GatewayClass를 참조해야 합니다.
- 외부 트래픽을 수신하고 내부 서비스로 라우팅하는 진입점을 정의합니다.
- 하나 이상의 Route 리소스와 연결될 수 있습니다.
- 트래픽을 특정 서비스로 매핑하는 프로토콜 별 규칙을 정의합니다.
- HTTPRoute, TLSRoute, TCPRoute, UDPRoute, GRPCRoute 등이 있습니다.
- Gateway 리소스에 연결되어 트래픽을 대상 서비스로 전달합니다.
이 계층적 구조를 통해 인프라 관리자는 GatewayClass와 Gateway를 관리하며 전체 인프라의 일관성을 유지하고, 애플리케이션 개발자는 다양한 Route를 통해 자신의 애플리케이션에 대한 세부 라우팅 규칙을 독립적으로 정의할 수 있습니다.
AWS는 이러한 계층적 구조를 Amazon VPC Lattice와 통합하여 제공함으로써, 클라우드 네이티브 환경에서의 네트워킹 요구사항을 효과적으로 충족시킵니다.
Gateway API Controller
Gateway API도 다른 Kubernetes 컴포넌트와 마찬가지로 Controller를 통해 동작합니다. 여러 벤더 별 Gateway API Controller 구현체를 참조하고 싶다면 여기를 확인해보세요. AWS에서는 AWS Gateway API Controller를 제공하고 있습니다. 🔗

Amazon VPC Lattice

Amazon VPC Lattice 는 AWS에서 제공하는 완전관리형 애플리케이션 네트워킹 서비스로, 다양한 컴퓨팅 환경에서 애플리케이션 서비스를 연결, 보호 및 모니터링하는 통합 솔루션입니다. VPC Lattice는 단일 VPC 내에서는 물론, 계정 간 여러 VPC에 걸쳐 서비스를 연결하는 데 활용할 수 있습니다.
현대적 애플리케이션은 마이크로서비스 아키텍처를 통해 여러 개의 소규모 모듈형 서비스로 분할되어 개발되는 추세입니다. 이러한 접근 방식은 개발 속도와 확장성 측면에서 많은 이점을 제공하지만, 다양한 마이크로서비스 간의 효율적인 연결과 관리에 대한 새로운 네트워킹 문제를 야기합니다. Amazon VPC Lattice는 이러한 과제를 해결하기 위해 네트워크 액세스, 트래픽 관리, 모니터링에 대한 일관된 정책을 정의하여 EC2 인스턴스, EKS 컨테이너, Lambda 서버리스 함수 등 다양한 컴퓨팅 서비스 간에 간단하고 표준화된 연결 방식을 제공합니다.
Amazon VPC Lattice 주요 구성 요소

Service
Service는 특정 작업이나 기능을 수행하는 독립적으로 배포가능한 소프트웨어 단위입니다. 구성 요소는 일반적인 ELB 구성과 비슷합니다.
- 리스너 : 리스너에서는 Service가 트래픽을 받아들일 포트와 프로포콜을 정의합니다. 지원되는 프로토콜은 HTTP/1.1, HTTP/2, gRPC이며, TLS가 활성화된 Service의 경우 HTTPS도 포함됩니다.
- 규칙 : 리스너의 기본 구성 요소로, 요청을 대상 그룹의 대상들로 전달합니다. 각 규칙은 우선 순위, 하나 이상의 작업, 그리고 리스너가 클라이언트 요청을 라우팅하는 기준이 되는 하나 이상의 조건으로 구성됩니다.
- 대상 그룹 : 애플리케이션이나 서비스를 실행하는 리소스들의 집합으로, 이를 대상 이라고도 합니다. 대상은 EC2 인스턴스, IP주소, Lambda 함수, 또는 Kubernetes Pod가 될 수 있습니다

VPC Latiice 서비스 특징
- 고유한 VPC Lattice 도메인 네임 제공
- 리스너를 통해 들어오는 연결 처리
- 특정 경로나 헤더 값에 기반한 라우팅 규칙 정의
- EC2, ECS, Lambda 등 다양한 AWS 컴퓨팅 서비스를 대상으로 설정 가능
- 상태 확인을 통한 트래픽 안정성 보장
Service Network
Service Network는 VPC Lattice의 핵심 구성 요소로, 여러 서비스를 논리적으로 그룹화하고 이들 간의 통신을 관리합니다. 하나 이상의 VPC를 Service Network에 연결하여 해당 네트워크 내의 서비스 간 통신을 가능하게 합니다.

Service Network의 특징
- 여러 VPC와 서비스를 단일 네트워크로 통합
- 계정 간, 리전 간 서비스 연결 지원
- 중앙 집중식 액세스 제어 및 모니터링 제공
- VPC 연결을 통한 Service Network 내 서비스에 대한 접근 관리
Auth Policy
Auth Policy는 VPC Lattice 서비스에 대한 액세스를 제어하는 IAM 기반 정책입니다. 이를 통해 특정 IAM 보안 주체나 역할이 서비스에 접근할 수 있는지 여부를 세밀하게 제어할 수 있습니다.

Auth Policy의 주요 기능
- IAM 기반의 세분화된 접근 제어
- 서비스 레벨 또는 서비스 네트워크 레벨에서 적용 가능
- HTTP 메소드, 경로, 헤더 등을 기준으로 조건부 액세스 규칙 설정
- AWS 리소스 간의 안전한 통신 보장
Service Directory
Service Directory는 모든 VPC Lattice 서비스를 중앙에서 검색하고 관리할 수 있는 카탈로그입니다. 개발자와 운영팀이 사용 가능한 서비스를 쉽게 찾고 접근할 수 있도록 지원합니다.

Service Directory의 주요 기능
- 사용 가능한 모든 서비스의 중앙 집중식 카탈로그 제공
- 서비스 메타데이터 및 설명 관리
- 서비스 검색 및 필터링 기능
- 접근 가능한 서비스에 대한 가시성 제공
Amzon VPC Lattice 장점
위와 같은 주요 컴포넌트의 기능과 상호작용으로 구현 가능한 VPC Lattice의 장점은 다음과 같습니다.
- 여러 VPC, EC2 인스턴스, 컨테이너, 서버리스로 구성한 애플리케이션의 네트워크 구성을 중앙 집중화 할 수 있습니다.
- 별도의 사이드카 프록시를 구성할 필요가 없습니다. (+ 완전 관리형 서비스)
- 복잡한 네트워크 구성을 단순화 해서 쉽게 사용할 수 있습니다.
- IAM 및 SigV4를 통해 각 애플리케이션으로의 보안 구성을 손쉽게 적용 할 수 있습니다.
- CloudWatch, S3, Kinesis Data Firehose를 통해 쉽게 로깅, 트래픽 패턴 분석 등을 수행할 수 있습니다.
VPC Lattice의 장점을 다양한 사용사례로 확인해 봅니다.
1️⃣ 단일 리전의 애플리케이션 간 연결

2️⃣ 온프레미스에서 AWS에 배포된 애플리케이션으로 접근하는 경우

3️⃣ 여러 AWS 리전에 걸친 애플리케이션 간의 연결

4️⃣ 다중 계정 간 애플리케이션의 연결

※ 참고자료
- Amazon VPC Lattice Docs : https://docs.aws.amazon.com/ko_kr/vpc-lattice/latest/ug/what-is-vpc-lattice.html
- Amazon VPC Lattice Workshop : https://catalog.workshops.aws/handsonwithvpclattice/ko-KR
- https://docs.aws.amazon.com/ko_kr/vpc-lattice/latest/ug/how-it-works.html
- https://aws.amazon.com/ko/blogs/korea/simplify-service-to-service-connectivity-security-and-monitoring-with-amazon-vpc-lattice-now-generally-available/
- https://aws.amazon.com/ko/blogs/tech/amazon-vpc-vattice-modernize-and-simplify-your-enterprise-network-architectures/
- https://aws.amazon.com/blogs/containers/application-networking-with-amazon-vpc-lattice-and-amazon-eks/
- https://youtu.be/fRjD1JI0H5w?si=jtLssGaVfu8hnNUY
AWS Gateway API Controller

AWS Gateway API Controller는 Gateway API에 의해 정의된 사용자 지정 리소스(CRD)를 확장하여 Kubernetes API를 사용하여 VPC Lattice 리소스를 생성합니다.
Controller가 클러스터에 설치되면 Controller는 Gateway API의 리소스(Gateway 및 Route)의 생성을 감시하고 적절한 Amazon VPC Lattice 오브젝트를 프로비저닝 합니다.
이를 통해 사용자는 커스텀 코드를 작성하거나 사이드카 프록시를 관리할 필요 없이 Kubernetes API를 사용하여 VPC Lattice Service, VPC Lattice Service Network 및 Target Group을 구성할 수 있습니다.
AWS Gateway API Controller는 Amazon VPC Lattice와 통합되어 다음 작업을 수행할 수 있습니다.
- VPC 및 계정 전반에 걸친 서비스 간 네트워크 연결을 원활하게 처리합니다.
- 여러 Kubernetes 클러스터에 걸쳐 있는 VPC Lattice Service를 검색합니다.
- 서비스 간 통신의 보안을 구성하기 위한 깊이 있는 방어 전략을 구현합니다.
- 서비스 간 요청/응답 트래픽을 관찰합니다.
AWS Gateway API Controller는 오픈소스 프로젝트이며, Amazon의 완전한 지원을 받고있습니다.
Gateway API 구성 요소와 VPC Lattice 오브젝트 간 매핑 관계

AWS Gateway API Controller는 Kubernetes의 Gateway API 리소스(GatewayClass, Gateway, HTTPRoute 등)를 이용하여 Amazon EKS에 배포된 서비스들을 AWS VPC Lattice의 네트워크 리소스(Service Network, Target Group 등)로 자동 변환하고 동기화합니다.
즉 k8s 환경에서 AWS 네트워크 관련 모든 리소스를 통합 관리 해주는 컨트롤러 플러그인 개념으로 볼 수 있습니다.
⚠️ Amazon EKS에서 VPC Lattice로 Gateway API 사용 Prequisite
- 쿠버네티스 1.28 이상 필요: 공식 문서에서 v1.28부터 기존 Ingress가 Frozen 상태로 전환되었으며, Gateway API를 통한 현대화 아키텍처 구현이 권장됩니다.
- AWS Gateway API Controller 설치: VPC Lattice 리소스와 쿠버네티스 API 객체 간 매핑을 처리하는 컨트롤러 배포 필요합니다.
- AWS Gateway API Controller 설치 및 구성 방법에 대해서는 이 문서를 참조하시기 바랍니다.
EKS on VPC Lattice 실습
이제 실제로 VPC Lattice 네트워크에서 실행되는 EKS 를 배포해보고 어떠한 방식으로 통신이 구현되는 지 확인해보는 실습을 진행해보겠습니다.
해당 실습은 AWS 공식 자료인 Amazon EKS Blueprints for Terraform 모듈을 사용하며 실습 과정의 원본은 다음 블로그를 참고 바랍니다. 🔗
Simple Client to Server communication
실습 환경은 EKS Blueprints for Terraform 테라폼 코드로 구축합니다. 🔗
💡 실습 환경 준비
실습 아키텍처

실습은 간단하게 VPC Lattice를 통해 VPC 간 통신을 테스트 해봅니다.
Terraform 코드 준비 및 프로비저닝
1. 아래 명령을 통해 실습용 코드를 clone 해주세요. 이 프로젝트의 디렉터리는 실습하기 편한 곳으로 설정해줍니다.
git clone https://github.com/aws-ia/terraform-aws-eks-blueprints.git
2. 터미널을 통해 terraform-aws-eks-blueprints 프로젝트의 /patterns/vpc-lattice/client-server-communication 디렉터리로 이동합니다.
cd terraform-aws-eks-blueprints/patterns/vpc-lattice/client-server-communication
다양한 모듈을 통해 손쉽게 CICD 도구 및 add-on을 설치합니다.

또한 EKS 워크로드의 애플리케이션은 Helm 차트를 통해 배포됨을 확인할 수 있습니다.


3. main.tf 파일 내의 29번째 라인에서 region 값을 ap-northeast-2로 수정합니다.

- 아래 명령을 순차적으로 실행하여 실습 인프라를 프로비저닝 합니다.
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

Client VPC와 애플리케이션이 기동되는 서버의 VPC를 생성합니다. 그리고 서버 VPC의 서비스를 호출할 때 Route53의 Private Hosted zone의 도메인을 통해 호출 되므로 이를 생성합니다.
해당 hosted zone은 client vpc에 생성됩니다.

private hosted zone임에도 타 VPC통신이 가능함은 VPC Lattice 서비스를 사용하기 때문입니다.
조금 더 자세히 말하자면 이는 VPC lattice에 클라이언트VPC와 서버 VPC가 서비스 네트워크로 등록되었기 때문입니다.

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
클라이언트 EC2와 해당 EC2에 SSM 연결을 위한 SG, VPCEndpoint를 생성합니다.
terraform apply -target="module.eks" -auto-approve
terraform apply -target="module.addons" -auto-approve
서버의 인프라(EKS)를 생성합니다. EKS 클러스터는 15~20분 가량 소요됩니다.
terraform apply -auto-approve
그 외 리소스 (helm, vpc lattice, 데모 애플리케이션 등)을 생성합니다.
5. 모든 인프라가 프로비저닝 완료되었으면 아래 명령을 수행하여 kubectl config 설정을 완료해줍니다.
aws eks update-kubeconfig --name client-server-communication --alias client-server-communication --region ap-northeast-2
- 아래 명령을 수행하여 Amazon EKS 엔드포인트 요청이 정상적으로 수신되는지 확인합니다.
kubectl get po -A

구성된 워크로드 확인
VPC 구성 확인

EKS 포드 구성 확인

노드 확인
kubectl get nodes

Client 서버 SSH 접속
클라이언트에서 서버로 요청을 수행하기위해 클라이언트 서버로 접속합니다.


client 애플리케이션에서 cluster 애플리케이션으로 http 요청 전송
client에서 cluster의 server pod로 요청이 잘 수행되는지 명령을 수행해보겠습니다. 이 과정에서 VPC Lattice로 구성된 서비스 네트워크를 사용해봅니다.
다음과 같이 한 쪽에는 client의 터미널을, 다른 한 쪽에는 kubectl 명령을 수행할 터미널을 준비합니다.

아래 kubectl 명령을 통해 server pod의 애플리케이션 로그를 실시간으로 모니터링 하겠습니다.
kubectl logs -f deployment/server -n apps --all-containers=true --since=1m
client의 터미널에서는 아래 명령을 수행하여 네트워크 통신 테스트를 수행합니다.
curl -i http://server.example.com
다음과 같이 클라이언트의 요청이 서버의 애플리케이션 로그에서 확인되는것을 볼 수 있습니다.

클라이언트는 자신의 hosted zone 에 등록된 도메인을 호출했는데 (http://server.example.com) 서버로 연결이 되는것을 볼 수 있습니다.
nslookup 을 통해 해당 도메인을 확인해봅니다.
nslookup server.example.com

위 cname을 자세히 살펴봅니다. ‘vpc-lattice-svcs’ 라는 서브 도메인을 살펴볼 수 있습니다. 이는 VPC lattice의 cname으로 해당 도메인이 등록되었기 때문에 연결이 구현된 것임을 확인할 수 있습니다.
Amazon VPC Lattice 확인

Amazon VPC Lattice Target Group 확인
VPC Lattice Service의 세부 항목 중, Routing 섹션을 클릭하면 아래와 같은 Listener 규칙과 함께 대상 그룹을 확인할 수 있습니다. 대상 그룹의 세부 내용을 보기 위해서 아래 그림과 같이 Listener rules > Action > Forward to 순서로 찾아 대상 그룹을 클릭합니다.

아래는 대상 그룹 상세 페이지 입니다. 여기의 Registered targets 섹션을 보면 IP address와 Port 번호를 통해 VPC Lattice Service로의 라우팅 대상을 안내하고 있습니다.

아래 kubectl 명령을 수행하면, 해당 IP address와 일치하는 server pod의 IP 목록을 조회할 수 있습니다.
kubectl get po -n apps -o wide

이어서 아래 명령을 수행하면, server pod에서 사용하는 service의 정보 및 Port 번호를 조회할 수 있습니다.
kubectl get svc -n apps

이를 통해 VPC Lattice로 구성된 DNS 엔드포인트는 EKS 클러스터 내의 server pod로 라우팅 된다는 것을 알 수 있습니다.
AWS Gateway API Controller의 동작 체크
이렇게 VPC Lattice를 통해 EKS 클러스터 내의 server pod로 라우팅 할 수 있는 환경을 구성하기 위해서는 EKS 클러스터 내에 GatewayClass, Gateway, Route 리소스를 생성해야 합니다.
AWS Gateway API Controller는 생성된 GatewayClass, Gateway, Route 리소스를 참조하여 필요한 VPC Lattice 네트워크 환경을 구성하게 됩니다.
아래 kubectl 명령을 수행하여, AWS Gateway API Controller의 로그를 lattice.log라는 파일로 저장합니다.
kubectl logs deployment/aws-gateway-api-controller-aws-gateway-controller-chart -n aws-application-networking-system --all-containers=true > lattice.log
아래 로그의 내용처럼 EKS 클러스터 내에 GatewayClass, Gateway, Route에 대한 오브젝트가 추가되면 AWS Gateway API Controller에서 이를 감지하여 조정(reconcile)합니다.


이러한 로그의 해석은 다음과 같습니다.
- 로그를 보면,
server라는 이름의 service와my-services라는 이름의 gateway의 생성을 감지하여, reconcile 작업을 수행하는 것을 확인할 수 있습니다. - 이어서
server-apps라는 이름(HTTPRoute의 metadata.name 및 metadata.namespace를 사용)으로 구성된 Route 대상에 라우팅 하기 위해server.example.com이라는 사용자 지정 도메인 이름을 세팅하고, VPC Lattice Service를 구성합니다. - 그리고 VPC Lattice Service에 대해 Listener rule을 생성하고 HTTPRoute 매니페스트 내용에 맞춰 PathPrefix를 구성하고, backendRefs에 대한 대상 그룹을 생성합니다.
- 대상 그룹에는 Service를 참조하여 라우팅 대상 Pod의 IP 주소 및 Port 번호를 세팅합니다.
이러한 내용은 terraform-aws-eks-blueprints/patterns/vpc-lattice/client-server-communication/charts/demo-application 경로에서 확인할 수 있습니다.
apiVersion: gateway.networking.k8s.io/v1beta1
kind: GatewayClass
metadata:
name: amazon-vpc-lattice
spec:
controllerName: application-networking.k8s.aws/gateway-api-controller
---
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
---
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: /
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: server
labels:
app: server
spec:
replicas: 2
selector:
matchLabels:
app: server
template:
metadata:
labels:
app: server
spec:
containers:
- name: server
image: public.ecr.aws/x2j8p8w7/http-server:latest
env:
- name: PodName
value: "server pod"
---
apiVersion: v1
kind: Service
metadata:
name: server
spec:
selector:
app: server
ports:
- protocol: TCP
port: 8090
targetPort: 8090
이렇게 AWS Gateway API Controller가 GatewayClass, Gateway, Route 리소스를 참조하여 VPC Lattice 네트워크 환경을 구성하여 정상적으로 통신이 가능한 환경을 구성했다는 것을 확인할 수 있습니다.
실습 리소스 정리
terraform destroy -target="module.client_vpc" -auto-approve
terraform destroy -target="module.cluster_vpc" -auto-approve
terraform destroy -target=aws_route53_zone.primary -auto-approve
terraform destroy -target="module.client_sg" -auto-approve
terraform destroy -target="module.endpoint_sg" -auto-approve
terraform destroy -target="module.client" -auto-approve
terraform destroy -target="module.vpc_endpoints" -auto-approve
terraform destroy -target="module.eks" -auto-approve
terraform destroy -target="module.addons" -auto-approve
terraform destroy -auto-approve
Multi Cluster secure communication
이번 실습에서는 Amazon EKS Blueprints for Terraform : Amazon VPC Lattice - Multi-cluster secure communication을 활용합니다.
이번 섹션에서는 조금 더 심화 과정으로, 멀티 클러스터 환경 간에서 Amazon VPC Lattice를 활용한 안전한 통신 방법에 대해 실습을 진행합니다.
실습 아키텍처

이 패턴에서는 Amazon VPC Lattice와 IAM authorization을 사용하여 서로 다른 VPC에 있는 두 EKS 클러스터 간의 안전한 멀티 클러스터 통신 방식을 보여줍니다.
- 이 솔루션에서는 Service Discovery가 어떻게 이루어지는지를 설명하고, VPC Lattice가 겹치는 CIDR을 가진 EKS 클러스터 간 통신을 어떻게 용이하게 하는지 강조합니다.
- 이를 통해 프라이빗 NAT 게이트웨이와 Transit Gateway와 같은 네트워킹 구조가 필요하지 않도록 하는 방법을 소개합니다.
- 클러스터 간 통신을 안전하게 수행하기 위해, 인증서 관리자(ACM)에서 발행하고 AWS Private CA에서 지원하는 TLS 인증서로 보호되는 Amazon Route53 Private Hosted Zone을 사용하여 Amazon VPC Lattice를 통해 설정됩니다.
- 이를 위해 Kyverno를 사용하여 Envoy SigV4 proxy 컨테이너를 Pod에 추가하고, 여기에 PCA를 주입합니다.
주요 컴포넌트
인프라 구성
- 두 개의 VPC: VPC cluster 1과 VPC cluster 2가 독립적으로 구성
- 두 개의 EKS 클러스터: 각 VPC에 EKS Cluster 1과 EKS Cluster 2 배포
- VPC Lattice: 두 VPC 간의 서비스 통신을 위한 중앙 관리형 연결 서비스
애플리케이션 구성
- EKS Cluster 1 애플리케이션:
- App1 Service가 Pod로 배포됨
- Envoy sidecar 프록시를 통한 서비스 메시 구성
- HTTP Route를 통한 외부 트래픽 라우팅
- EKS Cluster 2 애플리케이션:
- App2 Service가 Pod로 배포됨
- 마찬가지로 Envoy sidecar 프록시와 HTTP Route 구성
정책 및 보안
- Kyverno: 각 클러스터에 적용된 정책 관리 도구로 사이드카 주입 등을 관리
- IAM Auth Policy: 두 클러스터 간의 인증 및 권한 정책 설정
- Private Certificate Authority: 중앙 인증서 관리
- Certificate Manager: *.example.com 도메인을 위한 인증서 관리
네트워킹
- AWS Gateway API Controller: 각 클러스터의 API 트래픽 제어
- DNS 구성:
- ExternalDNS를 통한 DNS 레코드 관리
demo-cluster1.example.com및demo-cluster2.example.com으로 각 클러스터 서비스 노출- Amazon Route 53을 통한 도메인 관리
주요 흐름 및 프로세스
- VPC Lattice를 통해 HTTPS 트래픽이 두 클러스터 간에 라우팅 됨
- 각 클러스터의 IAM Auth Policy가 접근 권한을 제어
- Pod Identity 기능을 통해 Envoy SigV4 proxy 컨테이너에 ACM에 대한 권한 및 VPC Lattice service invoke 권한 부여
- AWS Gateway API Controller가 각 클러스터의 인그레스 트래픽을 관리
- ExternalDNS가 자동으로 DNS 레코드를 생성하여 서비스 디스커버리 지원
environment 프로비저닝
실습에서의 주요 인프라를 확인해봅니다.

environment 환경에서는 실습에 필요한 사전 환경(Route53, VPC Lattice, IAM Role, ACM 등)을 프로비저닝 합니다.

자세한 내용은 아래 코드를 파악하여 확인해보겠습니다.
main.tf
provider "aws" {
region = local.region
}
locals {
name = "vpc-lattice"
region = "us-west-2" # 이 부분을 ap-northeast-2로 수정
domain = var.custom_domain_name
tags = {
Blueprint = local.name
GithubRepo = "github.com/aws-ia/terraform-aws-eks-blueprints"
}
}
...
Amazon Route53의 Private Hosted Zone을 구성하는 명세입니다.
Private Hosted Zone을 만들기 위해 필요한 Example VPC라는 이름의 더미 VPC를 만들고 있습니다.
#-------------------------------
# Create Private Hosted Zone
#-------------------------------
resource "aws_route53_zone" "private_zone" {
name = local.domain
vpc {
vpc_id = aws_vpc.example.id
}
#we will add vpc association in other terraform stack, prevent this one to revert this
lifecycle {
ignore_changes = [
vpc,
]
}
force_destroy = true
tags = local.tags
}
#dummy VPC that will not be used, but needed to create private hosted zone
resource "aws_vpc" "example" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "Example VPC"
}
}
...
VPC Lattice Service 및 ACM을 위한 IAM Role을 만들고, 필요한 Polic를 attach 합니다.
################################################################################
# Create IAM role to talk to VPC Lattice services and get Certificate from Manager
################################################################################
data "aws_iam_policy_document" "eks_assume" {
statement {
effect = "Allow"
principals {
type = "Service"
identifiers = ["pods.eks.amazonaws.com"]
}
actions = ["sts:AssumeRole", "sts:TagSession"]
}
}
resource "aws_iam_role" "vpc_lattice_role" {
name = "${local.name}-sigv4-client"
description = "IAM role for aws-sigv4-client VPC Lattice access"
assume_role_policy = data.aws_iam_policy_document.eks_assume.json
}
resource "aws_iam_role_policy_attachment" "vpc_lattice_invoke_access" {
role = aws_iam_role.vpc_lattice_role.name
policy_arn = "arn:aws:iam::aws:policy/VPCLatticeServicesInvokeAccess"
}
resource "aws_iam_role_policy_attachment" "private_ca_read_only" {
role = aws_iam_role.vpc_lattice_role.name
policy_arn = "arn:aws:iam::aws:policy/AWSCertificateManagerPrivateCAReadOnly"
}
...
pca.tf
#-------------------------------
# Associates a certificate with an AWS Certificate Manager Private Certificate Authority (ACM PCA Certificate Authority).
# An ACM PCA Certificate Authority is unable to issue certificates until it has a certificate associated with it.
# A root level ACM PCA Certificate Authority is able to self-sign its own root certificate.
#-------------------------------
# # https://docs.aws.amazon.com/acm-pca/latest/userguide/pca-rbp.html
resource "aws_acmpca_certificate_authority" "this" {
enabled = true
type = "ROOT"
certificate_authority_configuration {
key_algorithm = "RSA_4096"
signing_algorithm = "SHA512WITHRSA"
subject {
common_name = var.custom_domain_name
organization = var.organization
}
}
permanent_deletion_time_in_days = 7
tags = local.tags
}
resource "aws_acmpca_certificate" "this" {
certificate_authority_arn = aws_acmpca_certificate_authority.this.arn
certificate_signing_request = aws_acmpca_certificate_authority.this.certificate_signing_request
signing_algorithm = "SHA512WITHRSA"
template_arn = "arn:aws:acm-pca:::template/RootCACertificate/V1"
validity {
type = "YEARS"
value = 10
}
}
resource "aws_acmpca_certificate_authority_certificate" "this" {
certificate_authority_arn = aws_acmpca_certificate_authority.this.arn
certificate = aws_acmpca_certificate.this.certificate
certificate_chain = aws_acmpca_certificate.this.certificate_chain
}
...
#-------------------------------
# Create certificate in AWS Certificate Manager
#-------------------------------
resource "aws_acm_certificate" "private_domain_cert" {
domain_name = var.custom_domain_name
#validation_method = "DNS"
subject_alternative_names = [
"*.${var.custom_domain_name}"
]
options {
certificate_transparency_logging_preference = "DISABLED"
}
certificate_authority_arn = aws_acmpca_certificate_authority.this.arn
tags = local.tags
}
...
인프라 프로비저닝을 위해 아래 내용을 진행합니다.
1. 아래 명령을 수행하여 cross-cluster-pod-communication/environment/ 디렉터리로 이동합니다.
cd terraform-aws-eks-blueprints/patterns/vpc-lattice/cross-cluster-pod-communication/environment/
2. main.tf 파일을 열고, 7번째 라인의 region을 ap-northeast-2로 수정합니다.

3. 아래 명령을 수행하여 environment의 인프라를 프로비저닝 합니다.
terraform init
terraform apply --auto-approve
cluster 프로비저닝
이어서 cluster 환경에서는 실습에 사용할 두 개의 EKS 클러스터 및 데모 애플리케이션을 구성합니다.
1. 아래 명령을 수행하여 cross-cluster-pod-communication/cluster/ 디렉터리로 이동합니다.
cd ../cluster/
2. main.tf 파일을 열고, 31번째 라인의 region을 ap-northeast-2로 수정합니다.

3. 이어서 아래 명령을 통해 첫번째 EKS 클러스터를 배포합니다.
./deploy.sh cluster1
# 배포 완료 후, 아래 명령으로 kubectl config 설정을 완료합니다.
eval `terraform output -raw configure_kubectl`
#!/bin/bash
set -uo pipefail
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
ROOTDIR="$(cd ${SCRIPTDIR}/../..; pwd )"
[[ -n "${DEBUG:-}" ]] && set -x
if [[ $# -eq 0 ]] ; then
echo "No arguments supplied"
echo "Usage: destroy.sh <environment>"
echo "Example: destroy.sh cluster1"
exit 1
fi
env=$1
echo "Deploying $env" # with "workspaces/${env}.tfvars" ..."
if terraform workspace list | grep -q $env; then
echo "Workspace $env already exists."
else
terraform workspace new $env
fi
terraform workspace select $env
terraform workspace list
terraform init
#terraform apply -var-file="workspaces/${env}.tfvars"
terraform apply --auto-approve
4. 이어서 아래 명령을 통해 두번째 EKS 클러스터를 배포합니다.
./deploy.sh cluster2
# 배포 완료 후, 아래 명령으로 kubectl config 설정을 완료합니다.
eval `terraform output -raw configure_kubectl`
VPC Lattice 리소스 확인
위 과정을 통해 실습 환경이 모두 구성되고 vpc lattice 리소스를 살펴봅니다.
VPC 콘솔 > PrivateLink and Lattice > Service networks 순으로 콘솔을 이동하면 아래와 같이 VPC Lattice Service network 콘솔로 이동할 수 있습니다.


- lattice 서비스 목록에서 각 서비스가 커스텀 도메인명(예:
demo-cluster1.example.com)에 매핑되어 노출된 것을 확인할 수 있습니다. - 각 서비스는 Route53 Private Hosted Zone과 연결되어 있으며,PCA(Private Certificate Authority)를 활용한 인증서가 적용되어 있습니다
Route53 Private Hosted Zone 리소스 확인
도메인(예: example.com)에 대한 Private Hosted Zone이 생성되어 있고,각 클러스터의 VPC와 연동되어 있습니다. 해당 영역 내 서비스의 DNS 레코드는 자동으로 관리됩니다

AWS Certificate Manager(ACM) 및 PCA 연동
ACM에 PCA 기반의 커스텀 도메인 인증서와 와일드카드 인증서가 등록되어 있습니다. 이를 통해 각 서비스의 HTTPS 트래픽에 대해 암호화 및 인증이 적용됩니다

위와 같은 VPC lattice Gateway 및 service를 통해 클러스터간 통신이 가능하고 ACM이 적용되어 TLS통신을 할 수 있게되는 것입니다.
통신 테스트 및 동작방식 확인
이제 두 클러스터 간 연결성을 확인하기 위해 아래의 명령을 실행해보겠습니다.
kubectl --context eks-cluster1 \
exec -ti -n apps deployments/demo-cluster1-v1 -c demo-cluster1-v1 \
-- curl demo-cluster2.example.com
이 명령은 eks-cluster1의 데모 애플리케이션에서 eks-cluster2의 데모 애플리케이션으로 간단한 요청을 전송합니다.
예상되는 응답은 아래와 같습니다.
Requsting to Pod(demo-cluster2-v1-578bcfbc7-8vhxl): Hello from demo-cluster2-v1
실제로 VPC Lattice, ACM 인증서, Envoy 프록시, IAM 인증, HTTPRoute 정책이 모두 정상 작동하여 클러스터 간 통신이 허용됩니다.

동일 클러스터 내 통신(권한 거부 케이스)
이번에는 eks-cluster1의 데모 앱에서 동일 클러스터(eks-cluster1)의 서비스로 요청합니다.
kubectl --context eks-cluster1 \
exec -ti -n apps deployments/demo-cluster1-v1 -c demo-cluster1-v1 \
-- curl demo-cluster1.example.com
그럼 아래와 같은 에러 메시지가 나타납니다.
AccessDeniedException: User: arn:aws:sts::12345678910:assumed-role/vpc-lattice-sigv4-client/eks-... is not authorized to perform: vpc-lattice-svcs:Invoke on resource: ...
이는 IAMAuthPolicy에 따라 eks-cluster2에서 들어오는 요청만 허용하고, 동일 클러스터 요청(eks-cluster1 → eks-cluster1)은 차단되기 때문입니다.
이렇게 에러가 발생하는 이유는, eks-cluster1의 IAMAuthPolicy에서 eks-cluster2 으로만 호출 가능하도록 했기 때문입니다.
IAM Auth policy와 keyvenro
위에서 요청이 차단된 이유에 대해서는 다음과 같이 pod-identity의 iam 정책을 조회해보면 확인할 수 있습니다.
아래 명령을 실행해보겠습니다.
kubectl --context eks-cluster1 \
get IAMAuthPolicy -n apps demo-cluster1-iam-auth-policy \
-o json | jq ".spec.policy | fromjson"
그럼 아래와 같은 응답 결과를 확인할 수 있습니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::12345678910:root"
},
"Action": "vpc-lattice-svcs:Invoke",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:PrincipalTag/eks-cluster-name": "eks-cluster2",
"aws:PrincipalTag/kubernetes-namespace": "apps"
}
}
}
]
}
해당 정책문은 다음 내용과 같이 해석됩니다.
VPC Lattice Serivce를 invoke하는 액션 중에서 클러스터 명(eks-cluster-name)이 eks-cluster2 여야하고, 네임스페이스가 apps일 때에만 Invoke를 허용한다.
따라서 eks-cluster1 → eks-cluster2 의 통신은 정책에 의해 차단되는 것입니다.
해당 iam auth policy가 적용되는 구조를 살펴보면 다음과 같습니다.
다음 명령어를 통해 eks-cluster-1에 적용된 iam auth policy를 확인합니다.
kubectl describe IAMAuthPolicy demo-cluster1-iam-auth-policy -n apps
다음과 같이 정책이 apps 네임스페이스의 demo-cluster1 HTTPRoute에 적용되어 있음을 알 수 있습니다.

Kyverno의 역할
해당 실습에서는 Kyverno의 ClusterPolicy를 사용하여 데모 애플리케이션 Pod에 iptables 규칙과 envoy 사이드카 프록시를 주입했습니다:
- iptables 규칙은 애플리케이션에서 envoy 프록시로 트래픽을 라우팅합니다(소스 프로세스 gid가 0인 경우 규칙이 적용되지 않으므로 애플리케이션에 다른 gid를 제공합니다: runAsGroup: 1000).
- envoy 프록시는 시작 시 Private CA 인증서를 검색하여 시작 스크립트를 통해 VPC lattice 서비스를 신뢰하도록 설치합니다:
위와 같은 kyevenro 정책으로 인해 Pod의 트래픽이 iptables 규칙에 따라 Envoy로 리디렉션 되며
Envoy 프록시가 TLS, SigV4로 서명 및 인증서 검증 후 VPC Lattice 서비스를 호출하게 됩니다. 이때
IAMAuthPolicy에 따라 인가된 트래픽만 허용하도록 접근제어가 적용되어있습니다. Kyverno로 위와 같은 네트워크 통신을 애플리케이션과 Envoy에 적용하며 정책 자동화를 관리할 수 있습니다.
아래 명령을 수행하여 envoy 프록시 컨테이너가 뜰 때 실행하는 스크립트를 참조합니다.
kubectl --context eks-cluster1 \
exec -it deploy/demo-cluster1-v1 -c envoy-sigv4 -n apps \
-- cat /usr/local/bin/launch_envoy.sh
출력 결과는 아래와 같습니다.
#!/bin/sh
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0
cat /etc/envoy/envoy.yaml.in | envsubst \$AWS_REGION,\$JWT_AUDIENCE,\$JWT_JWKS,\$JWT_ISSUER,\$JWKS_HOST,\$APP_DOMAIN > /etc/envoy/envoy.yaml
aws acm-pca get-certificate-authority-certificate --certificate-authority-arn $CA_ARN --region $AWS_REGION --output text > /etc/pki/ca-trust/source/anchors/internal.pem
update-ca-trust extract
cat /etc/envoy/envoy.yaml
/usr/local/bin/envoy --base-id 1 -l trace -c /etc/envoy/envoy.yaml
envoy.yaml.in
static_resources:
listeners:
- name: http_connect
address:
socket_address:
protocol: TCP
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains:
- "*"
routes:
- match:
prefix: '/'
route:
cluster: outbound_proxy
# Ignore traffic to /health and respond with a 200
http_filters:
- name: envoy.filters.http.dynamic_forward_proxy
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.dynamic_forward_proxy.v3.FilterConfig
dns_cache_config:
name: dynamic_forward_proxy_cache_config
dns_lookup_family: V4_ONLY
typed_dns_resolver_config:
name: envoy.network.dns_resolver.cares
typed_config:
"@type": type.googleapis.com/envoy.extensions.network.dns_resolver.cares.v3.CaresDnsResolverConfig
use_resolvers_as_fallback: true
resolvers:
- socket_address:
address: "127.0.0.1"
port_value: 53
dns_resolver_options:
use_tcp_for_dns_lookups: true
no_default_search_domain: true
# SigV4 signing configuration
- name: envoy.filters.http.aws_request_signing
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.aws_request_signing.v3.AwsRequestSigning
service_name: vpc-lattice-svcs
region: ${AWS_REGION}
use_unsigned_payload: true
match_excluded_headers:
- prefix: x-envoy
- prefix: x-forwarded
- exact: x-amzn-trace-id
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: outbound_proxy
lb_policy: CLUSTER_PROVIDED
cluster_type:
name: envoy.clusters.dynamic_forward_proxy
typed_config:
"@type": type.googleapis.com/envoy.extensions.clusters.dynamic_forward_proxy.v3.ClusterConfig
dns_cache_config:
name: dynamic_forward_proxy_cache_config
dns_lookup_family: V4_ONLY
typed_dns_resolver_config:
name: envoy.network.dns_resolver.cares
typed_config:
"@type": type.googleapis.com/envoy.extensions.network.dns_resolver.cares.v3.CaresDnsResolverConfig
use_resolvers_as_fallback: true
resolvers:
- socket_address:
address: "127.0.0.1"
port_value: 53
dns_resolver_options:
use_tcp_for_dns_lookups: true
no_default_search_domain: true
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
common_tls_context:
validation_context:
trusted_ca:
filename: /etc/ssl/certs/ca-bundle.crt
이 YAML 파일은 Envoy 프록시의 구성을 정의하며, 특히 AWS VPC Lattice 서비스와의 안전한 통신을 위해 설계되었습니다
- name: http_connect: 리스너의 이름을 정의
- address: 모든 네트워크 인터페이스(0.0.0.0)의 8080 포트에서 TCP 연결을 수신함
filters 항목
- 모든 도메인(*)에 대한 HTTP 요청을 처리
- 모든 경로(/)로 시작하는 요청을 outbound_proxy 클러스터로 라우팅
동적 포워드 프록시 필터 (http_filters)
- 요청 중 호스트 이름을 동적으로 확인하는 필터
- IPv4 주소만 사용하도록 구성됨
- 로컬 DNS 리졸버(127.0.0.1:53)를 사용
AWS SigV4 서명 필터
- AWS Signature Version 4(SigV4) 알고리즘을 사용하여 요청에 서명
- VPC Lattice 서비스(vpc-lattice-svcs)로 가는 요청에 서명
- 환경 변수 ${AWS_REGION}을 통해 AWS 리전 지정
- 특정 헤더는 서명 프로세스에서 제외됨
라우터 필터
- 구성된 라우트에 따라 요청을 업스트림 클러스터로 전달하는 필수 필터
클러스터 구성
- outbound_proxy 클러스터는 동적 포워드 프록시로 동작
- 동적으로 호스트를 발견하고 연결 관리
TLS 설정
- 업스트림 서비스(VPC Lattice)와 통신할 때 TLS를 사용
- 시스템의 CA 인증서 번들을 사용하여 서버 인증서 검증
실습 리소스 정리
다음 명령어를 통해 실습에서 생성한 리소스를 정리합니다.
클러스터 정리
cd /workshop/terraform-aws-eks-blueprints/patterns/vpc-lattice/cross-cluster-pod-communication/cluster/
./destroy.sh cluster2
./destroy.sh cluster1
environment 환경 정리
SN=$(aws vpc-lattice list-service-networks --query 'items[?name==`lattice-gateway`].id' --output text)
if [ -n "$SN" ]; then
aws vpc-lattice delete-service-network --service-network-id "$SN"
fi
cd /workshop/terraform-aws-eks-blueprints/patterns/vpc-lattice/cross-cluster-pod-communication/environment/
terraform destroy -auto-approve
마치며
이번 포스팅에서는 EKS 클러스터를 AWS VPC Lattice에 연동하여 구성하고, 이를 통해 VPC Lattice의 핵심 개념과 기능을 실습해보았습니다.
VPC Lattice를 통해 네트워크 복잡도를 줄이고, 서비스 간 통신을 더욱 간편하고 안전하게 관리할 수 있는 방법을 확인할 수 있었습니다.
특히 VPC Lattice의 주요 특징은 다음과 같았습니다:
- 서비스 기반 통신: IP나 서브넷이 아니라 ‘서비스’ 단위로 네트워크를 구성할 수 있습니다.
- 간편한 서비스 연결: 복잡한 VPC Peering, Transit Gateway 구성이 필요 없습니다.
- IAM 기반 권한 제어: 서비스 간 접근 제어를 네트워크 레벨이 아닌 IAM 정책으로 세밀하게 설정할 수 있습니다.
- 내장된 로드밸런싱 및 보안 기능: ALB/NGW 없이 트래픽 제어와 보안 기능을 제공합니다.
또한 EKS에 VPC Lattice를 연동하여 사용할 때 얻을 수 있는 네트워크 관점의 장점은 다음과 같습니다:
- VPC 경계를 넘는 통신이 쉬워진다: 복잡한 보안 그룹/라우팅 테이블 관리 없이, 서비스 이름 기반으로 통신이 가능해졌습니다.
- EKS 서비스 간 통신이 표준화된다: Kubernetes 내부/외부 통신을 Lattice 기반으로 일관되게 관리할 수 있어 네트워크 아키텍처가 단순해집니다.
- 트래픽 가시성과 통제력이 향상된다: 서비스 간 호출 흐름을 관찰하고 제어할 수 있어, 운영/보안 측면 모두 강화할 수 있습니다.
이처럼 VPC Lattice는 마이크로서비스 환경에서 네트워크를 보다 간단하고 유연하게 운영할 수 있도록 돕는 강력한 도구임을 실습을 통해 체감할 수 있었습니다.
앞으로 복잡한 K8S 네트워크 구성도 이러한 VPC Lattice 같은 서비스를 통해 심플해지고 간편해 진다면 마이크로서비스에 대한 구축/운영 진입장벽도 많이 낮아질 것 같습니다.