[AWS] Lattice(@GatewayAPI)

xgro·2024년 10월 8일
1

AWS

목록 보기
19/19
post-thumbnail
post-custom-banner

📌 Summary

  • VPC Lattice와 Gateway API를 통해 Kubernetes의 네트워크 설정을 간소화하고 세밀한 접근 제어를 가능하게 합니다.

  • 멀티 클러스터 지원과 함께 서비스 간 독립성을 향상시키며, 보안 정책도 일관되게 관리할 수 있습니다.

  • 서비스 메쉬 기능 대체와 비용 효율성을 통해 EKS 환경에서 네트워크 복잡성을 줄이고 운영 효율성을 높입니다.


📌 GatewayAPI 전환의 장점

kubernetes Docs - ingress
v1.28버전의 공식문서부터 ingress가 Frozen 된다고 명시되어있습니다.

EKS를 운영하는 입장에서 GatewayAPIVPC Lattice로 전환하면 명확하게 좋아지는 부분은 다음과 같습니다.

관리 복잡성의 감소
기존 ALB Controller 기반의 구조에서는 여러 개의 ALB와 Ingress를 관리해야 하는 경우가 많아, 설정과 유지보수가 복잡해질 수 있습니다. VPC LatticeGateway API를 사용하면 이러한복잡성을 줄일 수 있습니다.

네트워크 정책을 간단하게 정의하고 중앙에서 관리할 수 있어, 운영 작업이 더욱 단순해집니다.

세밀한 접근 제어
기존의 보안 그룹(SG) 기반 접근 제어는 IP와 포트에 초점을 맞추어 설정됩니다. 그러나 VPC Lattice를 사용하면 IAM 정책을 통해 애플리케이션 레벨에서 접근 권한을 제어할 수 있어, 더욱 세밀하고 유연한 권한 관리를 할 수 있습니다.

예를 들어, 특정 서비스가 다른 서비스에 접근할 수 있는 권한을 명확히 정의할 수 있으며, 네트워크 변경 없이도 손쉽게 권한을 관리할 수 있습니다.

서비스 간 독립성 향상
GatewayAPI를 통해 서비스 간의 트래픽을 유연하게 제어할 수 있어, 특정 서비스의 변경이 다른 서비스에 미치는 영향을 최소화할 수 있습니다.

이를 통해 각 서비스가 독립적으로 운영될 수 있으며, 문제 발생 시 빠르게 격리하고 해결할 수 있는 장점이 있습니다.


📌 Resources

👉 Step 00. GatewayAPI

최근 Kubernetes의 네트워크 설정 방식에 큰 변화가 있었습니다.

Kubernetes 공식 문서에 따르면, v1.28 버전부터 Ingress"Frozen" 상태로 지정되었으며, 이는 더 이상 Ingress 리소스에 대한 새로운 기능 추가나 개선이 이루어지지 않는다는 것을 의미합니다. 대신 GatewayAPI가 차세대 네트워크 설정 방식으로 부상하고 있습니다.

제가 GatewayAPI에 대해 글을 쓰기로 한 이유는 이러한 변화에 발맞춰 최신 기술 동향을 이해하고, Kubernetes 환경에서 네트워크 설정을 보다 효율적으로 관리할 수 있는 방법을 공유하기 위해서입니다. GatewayAPI는 기존의 Ingress가 가지는 한계를 보완하고, 역할 기반의 확장성과 표현력을 제공하여 복잡한 네트워크 요구 사항을 충족시킬 수 있습니다.

특히 AWS EKS 환경에서 VPC Lattice와 결합하여 GatewayAPI를 활용하면, 서비스 간 통신을 간소화하고 보안 정책을 일관되게 적용할 수 있습니다. 이를 통해 마이크로서비스 아키텍처에서 흔히 발생하는 네트워크 복잡성을 줄이고, 운영 효율성을 높일 수 있다고 판단하여 이번 글에서 자세히 다루고자 합니다.

✅ GatewayAPI 소개

GatewayAPI는 확장 가능하고 역할 지향적이며 프로토콜 인식 구성 메커니즘을 제공하여, 네트워크 서비스를 더욱 유연하고 강력하게 관리할 수 있게 해줍니다.

인프라 제공자, 클러스터 운영자, 애플리케이션 개발자 등 다양한 역할에 맞게 설계되어 있어 조직 내 여러 팀이 협업하기에 용이합니다.


✅ Design principles

GatewayAPI의 디자인과 아키텍처는 다음과 같은 원칙에 의해 형성되었습니다:

역할 지향(Role-oriented): GatewayAPI의 종류는 쿠버네티스 서비스 네트워킹을 관리하는 조직 역할에 맞춰 모델링되었습니다.

  • 인프라 제공자(Infrastructure Provider): 여러 독립된 클러스터가 여러 테넌트를 서비스할 수 있도록 하는 인프라를 관리합니다. 예: 클라우드 제공자.
  • 클러스터 운영자(Cluster Operator): 클러스터를 관리하며 정책, 네트워크 접근, 애플리케이션 권한 등에 대해 책임을 집니다.
  • 애플리케이션 개발자(Application Developer): 클러스터 내에서 애플리케이션을 관리하며, 주로 애플리케이션 레벨의 설정 및 서비스 구성에 관심이 있습니다.
    이식성(Portable): GatewayAPI 사양은 커스텀 리소스로 정의되며 여러 구현체에서 지원됩니다.

표현력(Expressive): GatewayAPI 종류는 헤더 기반 매칭, 트래픽 가중치 등과 같은 일반적인 트래픽 라우팅 사용 사례에 대한 기능을 지원하며, 이는 기존 Ingress에서 커스텀 애노테이션을 사용해야만 가능했던 기능들이 포함됩니다.

확장성(Extensible): Gateway는 다양한 API 계층에서 커스텀 리소스를 연결할 수 있도록 하여 API 구조 내 적절한 위치에서 세밀한 사용자 정의가 가능하도록 합니다.


✅ Resource Model

Gateway API는 세 가지 안정적인 API 종류를 가지고 있습니다.

  • GatewayClass: 공통된 설정을 가진 게이트웨이 집합을 정의하며, 해당 클래스를 구현하는 컨트롤러에 의해 관리됩니다.

  • Gateway: 트래픽 처리 인프라(예: 클라우드 로드 밸런서)의 인스턴스를 정의합니다.

  • HTTPRoute: 게이트웨이 리스너에서 백엔드 네트워크 엔드포인트의 표현으로 트래픽을 매핑하기 위한 HTTP 전용 규칙을 정의합니다. 이러한 엔드포인트는 종종 서비스(Service)로 표현됩니다.


✅ Request flow

다음은 Gateway와 HTTPRoute를 사용하여 HTTP 트래픽을 서비스로 라우팅하는 간단한 예시입니다.

Gateway와 HTTPRoute를 사용하여 HTTP 트래픽이 서비스로 라우팅되는 것을 보여주는 다이어그램이 있다고 가정합니다.

이 예시에서, 리버스 프록시로 구현된 Gateway의 요청 흐름은 다음과 같습니다.

  1. 클라이언트는 http://www.example.com URL을 위한 HTTP 요청을 준비하기 시작합니다.
  2. 클라이언트의 DNS 리졸버가 대상 이름을 조회하고 Gateway에 연결된 하나 이상의 IP 주소로 매핑되는 정보를 얻습니다.
  3. 클라이언트는 Gateway IP 주소로 요청을 보냅니다. 리버스 프록시는 HTTP 요청을 수신하고 Host 헤더를 사용하여 Gateway와 연결된 HTTPRoute에서 유도된 구성과 일치시킵니다.
  4. 선택적으로, 리버스 프록시는 HTTPRoute의 일치 규칙을 기반으로 요청 헤더 또는 경로 매칭을 수행할 수 있습니다.
  5. 선택적으로, 리버스 프록시는 요청을 수정할 수 있습니다. 예를 들어, HTTPRoute의 필터 규칙을 기반으로 헤더를 추가하거나 제거할 수 있습니다.
  6. 마지막으로, 리버스 프록시는 요청을 하나 이상의 백엔드로 전달합니다.

👉 Step 01. AWS Lattice

✅ AWS Lattice 소개

VPC Lattice는 AWS에서 제공하는 네트워크 서비스로, 서비스 간 통신을 보다 쉽게 설정하고 관리할 수 있게 해줍니다.

AWS Lattice를 처음 접하는 분들을 위해, VPC Lattice는 서비스 간의 네트워크 통신을 단순화하고 일관된 네트워크 정책을 유지하는 데 도움을 줍니다.

이는 서버리스, 컨테이너 기반 워크로드 등 다양한 형태의 애플리케이션이 복잡한 네트워크 환경에서 원활하게 통신할 수 있도록 지원합니다.

Relationship between VPC Lattice and Kubernetes
concept - https://www.gateway-api-controller.eks.aws.dev/latest/concepts/overview/

쿠버네티스 사용자로서, VPC Lattice API를 사용하여 매우 쿠버네티스 친화적인 경험을 할 수 있습니다.
VPC Lattice 객체가 쿠버네티스 Gateway API 객체와 어떻게 연결되는지를 보여줍니다.

  • VPC Lattice 객체는 Kubernetes GatewayClass를 통해 Gateway, HTTPRoute와 같은 쿠버네티스 리소스와 연동됩니다.
  • HTTPRoute는 VPC Lattice의 서비스 정책을 따르며, 이를 통해 특정 쿠버네티스 서비스로 트래픽이 전달됩니다.

이 구조는 쿠버네티스 환경에서 VPC Lattice 리소스를 자연스럽게 사용할 수 있도록 도와줍니다.

VPC Lattice에는 각기 다른 수준의 제어와 관련된 다양한 역할이 있습니다.

쿠버네티스 Gateway API 문법을 사용하여 Gateway, HTTPRoute, 서비스를 생성하지만, 쿠버네티스는 이러한 항목들의 세부 정보를 VPC Lattice로부터 가져옵니다.

인프라 제공자: VPC Lattice를 GatewayClass로 식별하기 위해 쿠버네티스 GatewayClass를 생성합니다.

클러스터 운영자: 쿠버네티스 Gateway를 생성하며, 여기에는 VPC Lattice로부터 서비스 게이트웨이, 서비스 네트워크 및 관련 서비스 정책에 대한 정보를 가져옵니다.

애플리케이션 개발자: HTTPRoute 객체를 생성하여 쿠버네티스 서비스로 연결합니다. 이 서비스는 특정 파드로 트래픽을 라우팅합니다.

이 모든 과정은 관련된 VPC Lattice 서비스(및 관련 정책), 타겟 그룹(Target Groups), 타겟을 확인함으로써 이루어집니다.

또한, 같은 VPC Lattice 서비스(HTTPRoute)로부터 트래픽을 받는 다양한 클러스터/VPC에 걸쳐 분산된 서로 다른 타겟 그룹을 가질 수 있다는 점도 유의해야 합니다.


✅ VPC Lattice의 구성 요소

서비스 네트워크(Service Network)

서비스 네트워크는 Lattice의 핵심적인 구성 요소로, 여러 개의 서비스를 하나의 논리적인 네트워크 내에서 연결하고 관리합니다.

서비스 네트워크는 마이크로서비스 아키텍처에서 각 서비스가 개별적으로 존재하면서도, 서로 통신할 수 있도록 통합된 관리 환경을 제공합니다. 이를 통해 네트워크 설정을 표준화하고 보안을 강화하여, 운영팀이 마이크로서비스 간의 연결을 보다 간편하게 관리할 수 있습니다.

서비스 네트워크를 사용하면 서비스들이 네트워크 내에서 직접 연결되어, 추가적인 설정 없이도 상호 통신이 가능하게 됩니다. 이를 통해 서비스 확장 및 배포가 쉬워지고, 보안 정책을 일관되게 적용할 수 있어 운영의 복잡성을 줄일 수 있습니다.

서비스(Service)

서비스는 Lattice에서 개별적인 애플리케이션이나 마이크로서비스를 의미합니다.

AWS Lattice는 이러한 서비스를 등록하고 관리함으로써, 각 서비스가 다른 서비스들과 안정적으로 통신할 수 있는 기반을 제공합니다. 서비스를 정의할 때는 URL 또는 다른 엔드포인트 정보를 포함해 트래픽을 전달받을 수 있는 대상에 대한 정보를 설정하게 됩니다.

서비스는 서비스 네트워크 내에 포함되어 관리되며, 이를 통해 자동화된 로드 밸런싱과 접근 제어 기능을 활용할 수 있습니다. 각 서비스에 대한 트래픽 관리와 모니터링이 간편해지며, 다양한 서비스들이 서로 의존적일 때 발생할 수 있는 문제들을 줄여줍니다.

타겟그룹(Target Group)

타겟그룹은 트래픽을 실제로 전달받아 처리할 인스턴스나 컨테이너들의 집합을 정의하는 구성 요소입니다.

AWS Lattice에서 타겟그룹은 서비스가 트래픽을 전달할 대상을 정의하는 역할을 합니다. 예를 들어, 하나의 서비스가 여러 개의 애플리케이션 인스턴스에서 운영되고 있다면, 이러한 인스턴스들을 하나의 타겟그룹으로 묶어 관리할 수 있습니다.

타겟그룹을 설정함으로써, Lattice는 트래픽을 적절히 분배하고 각 인스턴스의 상태를 모니터링하여 가용성을 유지합니다. 이를 통해 서비스의 확장성(scalability)과 가용성(availability)을 보장할 수 있으며, 장애가 발생한 인스턴스를 자동으로 제외하는 등의 기능을 통해 안정성을 높일 수 있습니다.


✅ VPC Lattice의 장점

간소화된 네트워크 설정
VPC Lattice는 복잡한 네트워크 구성을 간소화하여, 서비스 간의 연결을 쉽게 설정할 수 있도록 돕습니다. 네트워크 연결, 보안 그룹 설정, 라우팅 규칙 등을 개별적으로 관리하는 대신, Lattice를 통해 중앙에서 일관되게 설정할 수 있습니다.

보안 관리의 향상
IAM과의 통합을 통해 각 서비스 간의 통신을 세밀하게 제어할 수 있으며, 네트워크 레벨이 아닌 애플리케이션 레벨에서 접근 제어를 가능하게 합니다. 이를 통해 보안 정책을 더욱 일관되게 적용하고, 접근 권한을 세밀하게 관리할 수 있습니다.

멀티 클러스터 지원
VPC Lattice는 여러 VPC와 여러 클러스터 간의 통합을 지원합니다. 이로 인해 다양한 AWS 리전이나 VPC에 분산되어 있는 애플리케이션들도 통합된 네트워크 정책을 통해 쉽게 통신할 수 있습니다. 이는 멀티 클러스터 환경에서의 운영 복잡성을 크게 줄여줍니다.

서비스 메쉬 기능 대체
VPC Lattice는 Istio와 같은 전통적인 서비스 메쉬와 유사한 기능을 제공하지만, 이를 AWS에서 완전 관리형으로 제공하기 때문에 설정 및 운영의 복잡성을 줄여줍니다. 서비스 메쉬를 위한 별도의 인프라 설정 없이, AWS의 네이티브 기능을 사용해 동일한 효과를 얻을 수 있습니다.


✅ Cost

VPC Lattice의 비용은 기본적으로 사용한 트래픽 양과 각종 서비스 연결에 따라 달라집니다.

주요 비용 요소는 다음과 같습니다.

시간당 요금
서비스에 대해 시간당 0.025 USD가 발생하며, 여러 서비스가 연결된 경우 이를 모두 합산하여 계산합니다. 이는 서비스의 연결 유지 및 네트워크 구성에 대한 비용입니다.

데이터 전송 비용
서비스 간의 데이터 전송량에 따라 GB당 0.025 USD의 비용이 발생합니다. 이는 VPC 간의 데이터 전송과 유사한 방식으로 계산됩니다.

요청 비용
시간당 요청 수에 따라 비용이 발생합니다. 첫 30만 건의 요청은 무료로 제공되며, 이후 요청에 대해서는 100만 건당 0.10 USD가 부과됩니다.


예를 들어, 20개의 서비스를 운영한다고 가정하여 VPC Lattice의 비용을 계산해보겠습니다.

시간당 요금
서비스당 0.025 USD, 20개의 서비스이므로 시간당 요금은:

20 × 0.025 = 0.50 USD

한 달(730시간) 기준 요금:

0.50 × 730 = 365 USD

데이터 전송 비용
각 서비스가 월 100GB의 데이터를 처리한다고 가정할 때, GB당 0.025 USD의 요금이 부과되며 20개의 서비스에 대해

20 × 100GB × 0.025 = 50 USD

요청 요금
각 서비스가 시간당 20만 건의 요청을 처리하며, 이는 AWS 프리 티어 한도(시간당 30만 건 이내) 이내이므로 요청 요금은 발생하지 않습니다.

총 월간 비용

365 + 50 = 415 USD


✅ VPC Lattice와 ALB의 비용 비교 분석

두 요금 예시표를 기준으로 VPC Lattice와 ALB의 비용 차이를 비교해보겠습니다.

VPC Lattice와 ALB의 비용 구조는 근본적으로 다르며, 각자의 장단점이 있습니다. 아래는 서비스 수가 증가할 때 비용이 어떻게 변화하는지 비교한 분석입니다.

초기 설정 및 관리 비용

ALB는 시간당 기본 요금이 낮을 수 있지만, 서비스가 늘어날수록 LCU 비용이 증가합니다. 특히, 여러 서비스가 하나의 ALB를 공유하게 되면 LCU의 계산 요소(새 연결 수, 활성 연결 수, 처리된 바이트 등)로 인해 요금이 크게 증가할 수 있습니다.

VPC Lattice는 고정된 시간당 요금과 간단한 데이터 전송 요금이 부과됩니다. 서비스의 수가 많아질수록 고정 요금의 혜택이 증가하며, 관리의 일관성이 높아집니다.

서비스 수VPC Lattice 월간 비용 (USD)ALB 월간 비용 (USD)
20415216 - 416
50약 1,037.50540 - 1,040
100약 2,0751,080 - 3,000+

위 표는 서비스 수가 20개, 50개, 100개일 때 VPC Lattice와 ALB의 월간 비용을 비교한 것입니다. VPC Lattice는 단일 비용 구조와 효율적인 관리 측면에서 장점을 가지며, 특히 많은 수의 서비스를 운영할 경우 ALB 대비 비용 절감 효과가 더욱 두드러질 수 있습니다.

20개의 서비스를 운영한다고 가정하여 VPC Lattice와 ALB의 비용을 다시 비교하겠습니다.

VPC Lattice 사용 시

시간당 요금: 서비스당 0.025 USD, 20개의 서비스이므로 시간당 요금은:

20 × 0.025 = 0.50 USD**

한 달(730시간) 기준 요금:

0.50 × 730 = 365 USD**

데이터 전송 비용: 각 서비스가 월 100GB의 데이터를 처리한다고 가정할 때, GB당 0.025 USD의 요금이 부과되며 20개의 서비스에 대해:

20 × 100GB × 0.025 = 50 USD**

요청 요금: 각 서비스가 시간당 20만 건의 요청을 처리하며, 이는 AWS 프리 티어 한도(시간당 30만 건 이내) 이내이므로 요청 요금은 발생하지 않습니다.

총 월간 비용:

365 + 50 = 415 USD

ALB 사용 시

ALB 기본 요금: 시간당 0.0225 USD, 20개의 서비스에 대해 한 개의 ALB로 운영한다고 가정할 때, 한 달(730시간) 기준 요금:

0.0225 × 730 = 16.425 USD

LCU 비용: ALB는 LCU 기반의 요금이 추가됩니다. 20개의 서비스를 운영하며 각 서비스가 시간당 20만 건의 요청을 처리한다고 가정하면, 여러 차원에서 LCU 비용이 발생합니다. 예를 들어,

새 연결 수, 활성 연결 수, 처리된 데이터 양 등을 고려하여 LCU 비용이 계산되며, 보수적으로 월간 약 200-400 USD 정도의 추가 비용이 발생할 수 있습니다.

총 월간 비용(대략적인 추정):

16.425 + 200 (추정 LCU 비용) = 216.425 USD

비용 비교 결론

VPC Lattice: 415 USD/월
ALB: 약 216 - 416 USD/월

VPC Lattice는 비용이 더 들 수 있지만, 관리 복잡성을 줄이고 서비스 간의 독립성, 보안 제어, 네이티브 AWS 통합의 이점 등을 제공하여 운영 효율성을 높일 수 있습니다.

따라서 단순 비용뿐만 아니라, 네트워크 정책 관리의 간소화와 장기적인 유지보수 효율성을 고려해 전환 여부를 결정하는 것이 좋습니다.


✅ 멀티 클러스터 지원 및 확장성

VPC Lattice는 멀티 클러스터 환경에서도 일관된 네트워크 정책을 적용할 수 있습니다.

예를 들어, 여러 EKS 클러스터가 서로 다른 VPC에 있더라도 VPC Lattice를 이용하면 쉽게 연결할 수 있습니다. 이를 통해 멀티 클러스터 환경에서의 일관성 있는 네트워크 정책 유지와 운영 간소화가 가능합니다. 확장성을 고려한 네트워크 인프라 관리가 가능하며, 클러스터가 증가하더라도 동일한 정책을 손쉽게 확장 적용할 수 있습니다.

멀티 클러스터 지원
VPC Lattice는 멀티 클러스터 환경에서도 일관된 네트워크 정책을 적용할 수 있습니다. 예를 들어, 여러 EKS 클러스터가 서로 다른 VPC에 있더라도 VPC Lattice를 이용하면 쉽게 연결할 수 있습니다.

서비스 메쉬와 유사한 기능
VPC Lattice는 서비스 메쉬와 유사한 기능을 제공하며, 다양한 네트워크 도메인에 걸쳐 서비스 간 통신을 가능하게 합니다. Istio와 같은 전통적인 서비스 메쉬를 사용하지 않아도 트래픽 관리와 보안 정책을 일관되게 적용할 수 있습니다. 이로 인해 복잡한 크로스 클러스터 통신도 쉽게 관리할 수 있습니다.

ServiceExport
AWS Gateway API Controller에서 ServiceExport는 서비스의 다중 클러스터 트래픽 설정을 가능하게 합니다. 클러스터는 ServiceImport 리소스를 사용하여 내보낸 서비스를 가져올 수 있습니다.

내부적으로 ServiceExport를 생성하면 독립적인 VPC Lattice 타겟 그룹이 생성됩니다. ServiceImport가 없어도 타겟 그룹 생성만 필요한 경우 ServiceExport를 생성하는 것이 유용할 수 있습니다. 예를 들어, 쿠버네티스 외부의 VPC Lattice 설정에서 타겟 그룹을 사용하는 경우입니다.

ServiceExport는 쿠버네티스 다중 클러스터 서비스 API의 구현체가 아니며, AWS Gateway API Controller는 Gateway API 통합을 위해 자체 리소스를 사용합니다.

제한 사항

  • 내보낸 서비스는 HTTPRoute에서만 사용할 수 있습니다. GRPCRoute는 현재 지원되지 않습니다.

  • 서비스당 하나의 ServiceExport만 지원됩니다. 각 포트를 나타내는 여러 내보내기가 필요하다면, 여러 Service-ServiceExport 쌍을 생성해야 합니다.

example

apiVersion: application-networking.k8s.aws/v1alpha1
kind: ServiceExport
metadata:
  name: service-1
  annotations:
    application-networking.k8s.aws/port: "9200"
spec: {}

ServiceImport
ServiceImport는 클러스터 외부의 서비스를 참조하는 리소스로, 다른 클러스터에서 정의된 ServiceExport 리소스와 연결됩니다.

Service와 마찬가지로 ServiceImport도 HTTPRoute의 백엔드 참조로 사용할 수 있습니다. 클러스터 자체의 서비스와 함께 (다른 클러스터에서 가져온 ServiceImport와 함께) 여러 VPC와 클러스터에 트래픽을 분배할 수 있습니다.

ServiceImport는 쿠버네티스 다중 클러스터 서비스 API의 구현이 아니며, AWS Gateway API Controller는 Gateway API 통합을 위해 자체 리소스를 사용합니다.

제한 사항

ServiceImport는 ServiceExport와 같은 제한 사항을 공유합니다.
컨트롤러는 HTTPRoute를 통한 ServiceImport만 지원하며, 직접 트래픽을 전송하는 것은 지원되지 않습니다.
BackendRef가 ServiceImport를 가리키는 포트는 무시됩니다. 대신 ServiceExport의 포트 애노테이션을 사용하세요.

Annotation

application-networking.k8s.aws/aws-eks-cluster-name (선택 사항): 지정된 경우, 컨트롤러는 해당 클러스터에서 내보낸 타겟 그룹만 찾습니다.
application-networking.k8s.aws/aws-vpc (선택 사항): 지정된 경우, 컨트롤러는 제공된 VPC ID와 일치하는 클러스터에서 내보낸 타겟 그룹만 찾습니다.

example
The following yaml imports service-1 exported from the designated cluster.

apiVersion: application-networking.k8s.aws/v1alpha1
kind: ServiceImport
metadata:
  name: service-1
  annotations:
    application-networking.k8s.aws/aws-eks-cluster-name: "service-1-owner-cluster"
    application-networking.k8s.aws/aws-vpc: "service-1-owner-vpc-id"
spec: {}

The following example HTTPRoute directs traffic to the above ServiceImport.

apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: my-route
spec:
  parentRefs:
    - name: my-gateway
      sectionName: http
  rules:
    - backendRefs:
        - name: service-1
          kind: ServiceImport



📚 EKS 실습

📙 클러스터 생성 및 컨트롤러 설치


Create a cluster

# 환경변수
# export AWS_REGION=<cluster_region>
# export CLUSTER_NAME=<cluster_name>
# (optional) export PROFILE=<profile>
export AWS_REGION=ap-northeast-2
export CLUSTER_NAME=mylab


# 클러스터 생성
eksctl create cluster --name $CLUSTER_NAME --region $AWS_REGION

# 클러스터 보안 그룹
CLUSTER_SG=$(aws eks describe-cluster --name $CLUSTER_NAME --output json| jq -r '.cluster.resourcesVpcConfig.clusterSecurityGroupId')

Set up IAM permissions

# recommended-inline-policy.json 다운로드
curl https://raw.githubusercontent.com/aws/aws-application-networking-k8s/main/files/controller-installation/recommended-inline-policy.json  -o recommended-inline-policy.json

# iam 생성
aws iam create-policy \
    --policy-name VPCLatticeControllerIAMPolicy \
    --policy-document file://recommended-inline-policy.json

# Arn
export VPCLatticeControllerIAMPolicyArn=$(aws iam list-policies --query 'Policies[?PolicyName==`VPCLatticeControllerIAMPolicy`].Arn' --output text)

# (aws-application-networking-system) namespace 생성
kubectl apply -f https://raw.githubusercontent.com/aws/aws-application-networking-k8s/main/files/controller-installation/deploy-namesystem.yaml


Set up the Pod Identities Agent

# pod-identity
aws eks create-addon --cluster-name $CLUSTER_NAME --addon-name eks-pod-identity-agent --addon-version v1.0.0-eksbuild.1

# 확인
kubectl get pods -n kube-system | grep 'eks-pod-identity-agent'

서비스 어카운트 생성 및 연결

# Create a Service Account.
cat >gateway-api-controller-service-account.yaml <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
    name: gateway-api-controller
    namespace: aws-application-networking-system
EOF
kubectl apply -f gateway-api-controller-service-account.yaml

# Create a trust policy file for the IAM role.
cat >trust-relationship.json <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowEksAuthToAssumeRoleForPodIdentity",
            "Effect": "Allow",
            "Principal": {
                "Service": "pods.eks.amazonaws.com"
            },
            "Action": [
                "sts:AssumeRole",
                "sts:TagSession"
            ]
        }
    ]
}
EOF

# Create the role.
aws iam create-role --role-name VPCLatticeControllerIAMRole --assume-role-policy-document file://trust-relationship.json --description "IAM Role for AWS Gateway API Controller for VPC Lattice"
aws iam attach-role-policy --role-name VPCLatticeControllerIAMRole --policy-arn=$VPCLatticeControllerIAMPolicyArn
export VPCLatticeControllerIAMRoleArn=$(aws iam list-roles --query 'Roles[?RoleName==`VPCLatticeControllerIAMRole`].Arn' --output text)

# Create the association
aws eks create-pod-identity-association --cluster-name $CLUSTER_NAME --role-arn $VPCLatticeControllerIAMRoleArn --namespace aws-application-networking-system --service-account gateway-api-controller


Install the Controller

# login to ECR
aws ecr-public get-login-password --region us-east-1 | helm registry login --username AWS --password-stdin public.ecr.aws
# Run helm with either install or upgrade
helm install gateway-api-controller \
    oci://public.ecr.aws/aws-application-networking-k8s/aws-gateway-controller-chart \
    --version=v1.0.6 \
    --set=serviceAccount.create=false \
    --namespace aws-application-networking-system \
    --set=log.level=info # use "debug" for debug level logs

# Create the amazon-vpc-lattice GatewayClass
kubectl apply -f https://raw.githubusercontent.com/aws/aws-application-networking-k8s/main/files/controller-installation/gatewayclass.yaml



📕 Single Cluster

prequisite

# Clone the AWS Gateway API Controller repository.
git clone https://github.com/aws/aws-application-networking-k8s.git
cd aws-application-networking-k8s

# Set the AWS Region of your cluster.
export AWS_REGION=<cluster_region>

쿠버네티스 클러스터 내에서 서비스 간 통신을 설정

# AWS Gateway API Controller needs a VPC Lattice service network to operate.
aws ecr-public get-login-password --region $AWS_REGION | helm registry login --username AWS --password-stdin public.ecr.aws
helm upgrade gateway-api-controller \
oci://public.ecr.aws/aws-application-networking-k8s/aws-gateway-controller-chart \
--version=v1.0.6 \
--reuse-values \
--namespace aws-application-networking-system \
--set=defaultServiceNetwork=my-hotel


# Create the Kubernetes Gateway my-hotel:
kubectl apply -f files/examples/my-hotel-gateway.yaml

# Verify that my-hotel Gateway
kubectl get gateway
---
NAME       CLASS                ADDRESS   PROGRAMMED   AGE
my-hotel   amazon-vpc-lattice               True      7d12h


# Create the Kubernetes HTTPRoute rates that can has path matches routing to the parking service and review service:
kubectl apply -f files/examples/parking.yaml
kubectl apply -f files/examples/review.yaml
kubectl apply -f files/examples/rate-route-path.yaml


# Create another Kubernetes HTTPRoute inventory:
kubectl apply -f files/examples/inventory-ver1.yaml
kubectl apply -f files/examples/inventory-route.yaml


# Find out HTTPRoute's DNS name from HTTPRoute status
kubectl get httproute
---
NAME        HOSTNAMES   AGE
inventory               51s
rates                   6m11s


# Check VPC Lattice generated DNS address for HTTPRoute inventory and rates (this could take up to one minute to populate):
kubectl get httproute inventory -o yaml
---
...
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
	annotations:
    	application-networking.k8s.aws/lattice-assigned-domain-name: inventory-default-xxxxxx.xxxxx.vpc-lattice-svcs.ap-northeast-2.on.aws
...


kubectl get httproute rates -o yaml
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
	annotations:
        application-networking.k8s.aws/lattice-assigned-domain-name: rates-default-xxxxxx.xxxxxxxxx.vpc-lattice-svcs.ap-northeast-2.on.aws
...

# If the previous step returns the expected response, store VPC Lattice assigned DNS names to variables.
ratesFQDN=$(kubectl get httproute rates -o json | jq -r '.metadata.annotations."application-networking.k8s.aws/lattice-assigned-domain-name"')
inventoryFQDN=$(kubectl get httproute inventory -o json | jq -r '.metadata.annotations."application-networking.k8s.aws/lattice-assigned-domain-name"')


# FQDN 확인
echo "$ratesFQDN \n$inventoryFQDN"

서비스간 연결 확인

inventory-ver1에서 parkingreview services로 요청을 확인하고 응답을 정상적으로 수신하는지 확인합니다.

kubectl exec deploy/inventory-ver1 -- curl -s $ratesFQDN/parking $ratesFQDN/review
---
Requsting to Pod(parking-xxxxx): parking handler pod
Requsting to Pod(review-xxxxxx): review handler pod

parking에서 inventory-ver1 service로의 연결을 확인할 수 있습니다.

kubectl exec deploy/parking -- curl -s $inventoryFQDN
---
Requsting to Pod(inventory-xxx): Inventory-ver1 handler pod

gatewayClass를 통해 lattice가 동적으로 생성되는것을 확인할 수 있습니다.


📘 Clean UP

Delete resources in the Single cluster walkthrough.

export AWS_REGION=ap-northeast-2
export CLUSTER_NAME=mylab


# Delete VPC Lattice services and applications in cluster
kubectl config use-context $CLUSTER_NAME
kubectl delete -f files/examples/inventory-route.yaml
kubectl delete -f files/examples/inventory-ver1.yaml
kubectl delete -f files/examples/rate-route-path.yaml
kubectl delete -f files/examples/parking.yaml
kubectl delete -f files/examples/review.yaml
kubectl delete -f files/examples/my-hotel-gateway.yaml


# Delete the service network association (this could take up to one minute):
CLUSTER_VPC_ID=$(aws eks describe-cluster --name $CLUSTER_NAME | jq -r .cluster.resourcesVpcConfig.vpcId)
SERVICE_NETWORK_ASSOCIATION_IDENTIFIER=$(aws vpc-lattice list-service-network-vpc-associations --vpc-id $CLUSTER_VPC_ID --query "items[?serviceNetworkName=="\'my-hotel\'"].id" | jq -r '.[]')
aws vpc-lattice delete-service-network-vpc-association  --service-network-vpc-association-identifier $SERVICE_NETWORK_ASSOCIATION_IDENTIFIER


# Cleanup VPC Lattice Resources
helm uninstall gateway-api-controller --namespace aws-application-networking-system 


# Ensure the service network my-hotel is deleted:
aws vpc-lattice list-service-networks


# Cleanup the clusters
# Delete cluster
eksctl delete cluster --name=$CLUSTER_NAME
k config delete-context $CLUSTER_NAME



📌 Conclusion

이번 글에서는 Kubernetes 환경에서 Gateway API와 VPC Lattice를 활용하여 네트워크 설정을 최적화하는 방법에 대해 알아보았습니다.

기존 Ingress의 한계를 넘어서는 Gateway API의 기능과, AWS에서 제공하는 VPC Lattice의 장점을 결합하면 네트워크 관리의 복잡성을 크게 줄일 수 있습니다. 이를 통해 서비스 간의 독립성을 향상시키고, 세밀한 보안 정책을 적용하여 안정적인 클러스터 운영이 가능합니다.

Gateway API를 도입함으로써 최신 Kubernetes 네트워크 설정 방식을 따르고, 향후에도 지속적인 업데이트와 지원을 받을 수 있습니다. 또한 VPC Lattice와의 연계를 통해 멀티 클러스터 환경에서도 일관된 네트워크 정책을 적용할 수 있어, 확장성과 운영 효율성을 동시에 달성할 수 있습니다.



🔗 Reference

profile
안녕하세요! DevOps 엔지니어 이재찬입니다. 블로그에 대한 피드백은 언제나 환영합니다! 기술, 개발, 운영에 관한 다양한 주제로 함께 나누며, 더 나은 협업과 효율적인 개발 환경을 만드는 과정에 대해 인사이트를 나누고 싶습니다. 함께 여행하는 기분으로, 즐겁게 읽어주시면 감사하겠습니다! 🚀
post-custom-banner

0개의 댓글