AWS 기술 블로그
AWS 로드 밸런스 컨트롤러의 Ingress 공유 및 대상 그룹 바인딩 자세히 살펴보기
본 게시물은 AWS Container Blog에 게시된 “A deeper look at Ingress Sharing and Target Group Binding in AWS Load Balancer Controller” by Elamaran Shanmugam, Ratnopam Chakrabarti, Re Alvarez-Parmar, and Praseeda Sathaye을 한국어 번역 및 편집하였습니다.
소개
AWS 로드 밸런서 컨트롤러는 애플리케이션 로드 밸런서(ALB) 및 네트워크 로드 밸런서(NLB)를 쿠버네티스 워크로드와 통합하는 쿠버네티스 컨트롤러입니다. 쿠버네티스 API(애플리케이션 프로그래밍 인터페이스)를 사용하여 로드 밸런서를 구성하고 관리할 수 있습니다. 고객들의 피드백을 바탕으로, 추가 설명이 필요한 두 가지 AWS 로드 밸런서 컨트롤러 기능을 확인했습니다. 이 게시물에서는 Ingress Grouping을 사용하여 비용을 절감하고 대상 그룹 바인딩을 사용하여 기존 로드 밸런서를 통합하는 방법을 설명합니다.
쿠버네티스는 클러스터 외부의 클라이언트에 로드밸런스 또는 Ingress 리소스 유형의 쿠버네티스 서비스를 노출하는 두 가지 방법이 있습니다. 두 방법 모두 내부적으로 AWS 엘라스틱 로드 밸런싱을 사용합니다. NLB(네트워크 로드 밸런서)는 많은 양의 트래픽을 처리하도록 설계되었으며 계층 4 (전송 제어 프로토콜(TCP) 및 사용자 데이터그램 프로토콜(UDP)) 트래픽을 처리하도록 최적화되었습니다. 또한 ALB(애플리케이션 로드 밸런서)는 웹 트래픽을 처리하도록 설계되었으며 계층 7 (HTTP 및 HTTPS) 트래픽을 처리하도록 최적화되었습니다. AWS 로드 밸런서 컨트롤러는 클러스터에 워크로드를 배포할 때 ALB 및 NLB의 수명 주기 및 구성 관리를 자동화합니다.
쿠버네티스 Ingress 와 애플리케이션 로드 밸런서
쿠버네티스에서 Ingress는 클러스터의 서비스에 액세스할 수 있도록 부하가 분산된 외부 IP 주소를 제공하는 API 객체입니다. 계층 7 (HTTP/HTTPS) 리버스 프록시 역할을 하며 요청된 호스트 및 URL 경로를 기반으로 트래픽을 다른 서비스로 라우팅할 수 있습니다. AWS 로드 밸런서 컨트롤러는 Ingress를 생성할 때마다 사용자를 대신하여 ALB를 프로비저닝하고 구성합니다.
마이크로서비스 아키텍처에서는 단일 쿠버네티스 클러스터 내에 여러 서비스를 배포하는 것이 일반적입니다. 서비스마다 외부 액세스, 라우팅 규칙, 보안 소켓 계층 (SSL) /전송 계층 보안 (TLS) 종료 등에 대한 요구 사항이 다를 수 있습니다. 이러한 경우 서비스에 대한 외부 액세스를 관리하기 위해 여러 Ingress 리소스를 사용해야 할 수 있습니다. 애플리케이션에는 애플리케이션별 라우팅 규칙이 포함되므로, 일반적으로 배포 아티팩트 (배포, 서비스, 볼륨 등과 함께)에 Ingress 리소스에 대한 정의가 포함됩니다. Ingress 리소스를 분리하면 클러스터의 다른 애플리케이션에 대한 트래픽 라우팅에 영향을 주지 않고 Ingress 리소스를 수정할 수 있기 때문에 좋은 방법입니다.
Ingress들에 대해서 AWS 로드 밸런서 컨트롤러를 사용하는 것이 유용하다 할지라도, 이 접근 방식에는 단점이 있습니다. 컨트롤러는 각 Ingress에 대해 애플리케이션 로드 밸런서 (ALB) 를 생성하므로 로드 밸런서 수가 필요 이상으로 많아질 수 있습니다. 각 ALB별로 시간당 요금이 부과되기 때문에 이것은 비용을 증가를 유발시킬 수 있습니다. 각 서비스에 대해 별도의 로드 밸런서를 사용하는 것은 빠르게 비용을 증가시킬 수 있습니다. 여러 Ingress들에서 ALB를 공유하면 필요한 ALB 수를 최소화하여 비용을 절감할 수 있습니다.
아키텍처에서 ALB 수를 최소화하기 위해 AWS 로드 밸런서 컨트롤러를 사용하여 Ingress를 그룹화할 수 있습니다. 컨트롤러는 단일 ALB를 여러 Ingress 리소스와 공유할 수 있는 IngressGroup 기능을 제공합니다. 이를 통해 로드 밸런서를 통합하고 비용을 절감할 수 있습니다. 또한 Ingress group에는 서로 다른 네임스페이스들의 Ingress들이 포함될 수 있으므로 여러 네임스페이스의 마이크로서비스에 대한 액세스를 쉽게 관리할 수 있습니다.
Ingress group 활용
여러 Ingress와 ALB를 공유하는 프로세스를 살펴보겠습니다. 이 데모에서는 두 개의 서로 다른 네임스페이스에 네 개의 웹 애플리케이션을 배포해 보겠습니다. 그런 다음 단일 ALB를 공유하도록 여러 Ingress들을 구성하고 그룹화하는 방법을 보여 드리겠습니다. group.name annotation을 사용하여 여러 Ingress 리소스를 그룹화할 수 있도록 하겠습니다.
위 다이어그램은 설치 후 AWS 로드 밸런서 컨트롤러가 수행하는 작업을 보여줍니다. 쿠버네티스 API 서버에서 Ingress 리소스에 대한 업데이트를 감시합니다. 변경을 감지하면 애플리케이션 로드 밸런서, 리스너, 대상 그룹 및 리스너 규칙과 같은 리소스를 업데이트합니다.
- Ingress 리소스에 언급된 모든 쿠버네티스 서비스에 대해 대상 그룹이 생성됩니다.
- Ingress 리소스 annotation에 정의된 모든 포트에 대해 리스너가 생성됩니다.
- 리스너 규칙 (Ingress 규칙이라고도 함)은 Ingress 리소스 정의의 각 경로에 대해 생성됩니다.
이 글에서는, 서로 다른 배경색으로 웹 페이지를 렌더링하는 웹 애플리케이션의 네 가지 변형을 실행해 보겠습니다. blue 및 green 앱은 blue-green-ns 네임스페이스에서 실행되고 orange 및 purple 앱은 orange-purple-ns 네임스페이스에서 실행됩니다. 앱이 배포되면, blue-green-Ingress와 orange-purple-Ingress라는 두 개의 Ingress 리소스를 생성할 것입니다. Ingress 규칙은 경로 기반 라우팅을 구성합니다.
아래 다이어그램에서 ALB는 트래픽을 수신하면 Ingress 규칙에 따라 요청을 파드로 라우팅합니다. blue-green-Ingress Ingress에는 bleu 및 green 웹 앱에 액세스하기 위한 라우팅 규칙이 있으며 blue-green-ns 네임스페이스에 배포됩니다. 마찬가지로 orange-purple-Ingress Ingress는 orange 및 purple 웹 앱에 액세스하기 위한 라우팅 규칙을 가지고 있으며, orange-purple-ns라는 네임스페이스에 배포됩니다.
솔루션 개요
이 블로그의 내용을 따라하려면 다음 사항이 필요합니다.
- 기존 노드 그룹이 있는 Amazon Elastic Kubernetes Service (Amazon EKS) 클러스터
- 클러스터에 설치된 AWS 로드 밸런서 컨트롤러
- AWS 및 쿠버네티스 API 서버에 액세스할 수 있는 머신에 필요한 도구. 로컬 또는 원격 시스템일 수도 있고 AWS Cloud9일 수도 있습니다. 다음 도구를 설치해야 합니다.
먼저 Github에서 코드를 복제하고 샘플 애플리케이션을 배포합니다.
실행 결과에는 생성한 리소스가 표시되어야 합니다.
네임스페이스 blue-green-ns의 리소스 상태를 확인합니다.
파드는 실행 상태여야 합니다.
마찬가지로 애플리케이션 파드가 orange-purple-ns 네임스페이스에서 작동하는지 확인하십시오.
또한 다음과 같은 두 가지 Ingress 리소스가 있습니다.
두 Ingress 리소스의 주소가 동일하다는 것을 알 수 있습니다.
Ingress를 그룹화했기 때문에 각 Ingress마다 개별 ALB가 생기지 않았습니다. Ingress를 더 자세히 살펴보기 전에 라우팅이 원하는 방식으로 작동하는지 확인해 보겠습니다.
ALB에 할당된 주소 확인하기
“/green” 경로의 ALB 주소로 이동합니다. 녹색 배경의 웹 페이지 (다음 그림 참조) 는 라우팅이 의도한 대로 작동하고 있음을 나타냅니다.
마찬가지로 “/blue”, “/orange” 및 “/purple” 경로에는 각각 해당 배경색이 있는 페이지가 표시되어야 합니다.
두 Ingress에 ALB가 하나만 있는 이유를 다시 살펴보겠습니다. Ingress 중 하나를 설명하면 alb.ingress.kubernetes.io/group.name annotation이 포함된 것을 알 수 있을 것입니다.
다음은 blue-green-ingress.yaml의 Ingress annotation입니다.
alb.ingress.kubernetes.io/group.name annotation을 추가하여 Ingress에 그룹을 할당할 수 있습니다. 동일한 group.name 주석이 있는 Ingress는 Ingress 그룹을 형성합니다. Ingress 그룹은 여러 네임스페이스에 Ingress를 포함할 수 있습니다.
이 예제에서는 blue-green-ingress와 orange-purple-ingress 모두 app-color-lb를 이 annotation의 값으로 사용하므로 동일한 그룹에 속하게 됩니다. 이를 통해 ALB는 해당 라우팅 규칙에 따라 두 Ingress의 트래픽을 라우팅할 수 있습니다. ALB에서 리스너 규칙으로 구성된 Ingress 규칙을 볼 수 있습니다. 아래 스크린샷은 AWS 로드 밸런서 컨트롤러가 생성한 규칙을 보여줍니다.
IngressGroup을 사용하면 단일 ALB가 네 가지 애플리케이션 모두의 진입점 역할을 합니다. 이러한 설계 변경으로 필요한 ALB 수가 줄어들고 비용이 절감됩니다.
IngressGroup의 설계 고려 사항
다중 테넌트 환경에서 IngressGroup을 사용하기 전에 고려해야 할 중요한 측면은 충돌 해결입니다. AWS 로드 밸런서 컨트롤러는 ALB에서 Ingress 규칙을 구성할 때 group.order 필드를 사용하여 평가 순서를 설정합니다. group.order의 값을 선언하지 않으면 컨트롤러의 기본값은 0입니다.
ALB는 Ingress 규칙을 적용하여 요청을 라우팅하는 방법을 결정합니다. 규칙 평가 순서는 group.order 필드에 의해 설정됩니다. 순서 값이 낮은 규칙이 먼저 평가됩니다. 기본적으로 IngressGroup 내 Ingress 간의 규칙 순서는 Ingress 네임스페이스/이름의 어휘 순서에 따라 결정됩니다.
Ingress 규칙의 기본 순서로 인해 Ingress에 규칙이 잘못 구성된 경우 애플리케이션 전반의 잘못된 라우팅이 발생할 수 있습니다. 여러 팀 또는 애플리케이션 간의 라우팅 충돌을 피하기 위해 명시적인 Ingress 규칙을 만들고 group.order를 사용하여 실행 순서를 설정해야 합니다.
공유 환경에서 IngressGroup을 사용할 때의 다른 주요 고려 사항은 다음과 같습니다. IngressGoup은 여러 네임스페이스의 Ingress를 포함할 수 있으므로 IngressGroup의 이름은 클러스터 전체에 걸쳐 있습니다. group.name에 명확한 값을 사용하여 이름 충돌을 방지해야 합니다. AWS 로드 밸런서 컨트롤러는 현재 IngressGroup에 대한 액세스를 제어하는 세분화된 제어 기능을 제공하지 않습니다. 따라서 그룹에 MyIngressGroup과 같은 일반적인 이름을 사용하는 것을 피하셔야 합니다. 클러스터의 다른 누군가가 동일한 이름으로 Ingress를 만들어 그룹에 해당 Ingress를 추가할 수 있기 때문입니다. 우선 순위가 더 높은 규칙을 만들면 애플리케이션 트래픽이 해당 규칙에 의해 잘못 라우팅 될 수 있습니다.
AWS ALB (Application Load Balancer)에는 리스너당 구성할 수 있는 규칙 수에 몇 가지 제한이 있습니다. 이러한 제한은 로드 밸런서에 과부하가 걸리고 성능에 영향을 미치지 않도록 하기 위한 것입니다. 예를 들어, 각 ALB 리스너는 기본적으로 최대 100개의 규칙을 가질 수 있습니다. 이러한 한도에 대한 최신 정보는 AWS 공식 문서를 확인하는 것이 중요합니다.
대상 그룹 바인딩을 사용하여 로드 밸런서와 쿠버네티스 리소스 분리
이전 섹션에서는 Ingress를 생성할 때 AWS 로드 밸런서가 수행하는 작업에 대해 설명했습니다. 컨트롤러는 새 Ingress 리소스가 생성될 때 ALB를 생성합니다. 어떤 Ingress가 IngressGroup의 일부인 경우 컨트롤러는 Ingress 전반의 Ingress 규칙들을 병합하고 ALB, 리스너 및 규칙을 구성합니다. 로드 밸런서의 라이프사이클은 하나 이상의 관련 Ingress들과 연동됩니다. Ingress를 삭제하면, 그룹에 다른 Ingress가 없을 경우 AWS 로드 밸런서 컨트롤러가 ALB를 삭제합니다. 컨트롤러는 트래픽을 애플리케이션으로 라우팅하는 로드 밸런서를 만들고 구성합니다.
고객이 직접 로드 밸런서를 관리하는 것을 선호하는 몇 가지 시나리오가 있습니다. 이 경우 로드 밸런서의 생성 및 삭제를 서비스 또는 Ingress의 라이프사이클과 분리합니다. 고객은 Amazon EKS 클러스터에 로드 밸런서 생성 권한을 부여하지 않거나, 다른 상황에서는 워크로드를 Amazon EKS로 마이그레이션하고 싶었지만 로드 밸런서는 보존하기를 원할 수 있습니다. 두 시나리오 모두에서 기존 로드 밸런서를 사용하여 쿠버네티스 서비스를 노출할 수 있는 기능이 필요했습니다.
대상 그룹 바인딩은 AWS 로드 밸런서 컨트롤러에서 관리하는 사용자 지정 리소스입니다. 이를 통해 기존 로드 밸런서를 사용하여 쿠버네티스 애플리케이션을 노출할 수 있습니다. 대상 그룹 바인딩 리소스는 쿠버네티스 서비스를 로드 밸런서 대상 그룹과 바인딩합니다. TargetGroupBinding 리소스를 만들면 컨트롤러가 트래픽을 서비스로 라우팅하도록 대상 그룹을 자동으로 구성합니다. 다음은 대상 그룹 바인딩 리소스의 예시입니다.
분명한 이점은 Ingress나 클러스터를 만들고 삭제할 때 로드 밸런서가 정적 상태를 유지한다는 것입니다. 로드 밸런서의 라이프사이클은 해당 로드 밸런서가 노출하는 서비스로부터 독립됩니다. 또 다른 이점은 기존 ALB를 사용하여 여러 Amazon EKS 클러스터에 트래픽을 분산할 수 있다는 것입니다.
클러스터 전반에서 애플리케이션 트래픽 로드 밸런싱
ALB는 가중치가 적용된 대상 그룹을 사용하여 여러 백엔드에 트래픽을 분산할 수 있습니다. 이 기능을 사용하면 먼저 각 클러스터의 대상 그룹을 만든 다음 대상 그룹을 여러 클러스터의 서비스에 바인딩하여 트래픽을 여러 클러스터로 라우팅할 수 있습니다. 이 전략을 사용하면 각 클러스터로 보내는 트래픽의 비율을 제어할 수 있습니다.
이러한 트래픽 제어는 blue/green 클러스터 업그레이드를 수행할 때 특히 유용합니다. 제어된 방식으로 이전 클러스터에서 새 클러스터로 트래픽을 마이그레이션 할 수 있습니다.
또한 고객은 이 아키텍처를 사용하여 다중 클러스터 환경에서 워크로드의 복원성(Resilience)을 개선합니다. 애플리케이션을 여러 쿠버네티스 클러스터에 동시에 배포하는 고객이 있습니다. 이를 통해 쿠버네티스 클러스터가 단일 장애 지점이 되는 것을 방지할 수 있습니다. 한 클러스터에서 장애 이벤트가 발생하는 경우 로드 밸런서 대상에서 해당 클러스터를 제거할 수 있습니다.
자세히 알아보기
대상 그룹 바인딩(TargetGroupBinding)이 실제로 작동하는 방식을 보여주기 위해 Amazon EKS 클러스터에 두 가지 버전의 웹 애플리케이션을 배포해 보겠습니다. 배포 이름을 black과 red로 지정하겠습니다. 두 애플리케이션 모두 전용 네임스페이스에서 실행됩니다. ALB를 사용하여 애플리케이션의 두 복제본 간에 트래픽을 균등하게 분배할 것입니다.
애플리케이션을 노출하기 위해 두 개의 서비스를 만들 것입니다. 그런 다음 TargetGroupBinding 리소스를 생성하여 이러한 서비스를 대상 그룹과 연결합니다.
전제 조건:
따라하기 위해서는 다음과 같은 준비가 필요합니다.
- AWS 로드 밸런서 컨트롤러가 설치된 Amazon EKS 클러스터
- 애플리케이션 로드 밸런서, 대상 그룹 및 리스너 생성 기능
로드 밸런싱 설정
환경 변수에 VPC 및 퍼블릭 서브넷의 ID를 설정합니다.
애플리케이션 로드 밸런서의 보안 그룹을 생성합니다.
애플리케이션 로드 밸런서에 외부에서 80번 포트로 접속할 수 있도록 보안 그룹 규칙을 추가해 줍니다.
애플리케이션 로드 밸런서를 생성합니다.
이 애플리케이션 로드 밸런서는 AWS 로드 밸런서 컨트롤러에 의해서 생성된 로드 밸런서가 아니기 때문에, EKS Cluster의 노드 인스턴스에 애플리케이션 로드 밸런서의 트래픽을 허용하기 위한 추가 설정이 필요합니다. EKS Cluster의 노드 인스턴스의 80번 포트에서 애플리케이션 로드 밸런서가 트래픽을 허용하도록 인스턴스의 보안 그룹에 규칙을 추가합니다.
Amazon EKS 클러스터와 동일한 VPC에 리스너 하나와 대상 그룹 두 개를 생성합니다.
다음은 위의 구성을 적용한 후 AWS 관리 콘솔에서 확인한 대상 그룹 규칙의 스크린샷입니다.
애플리케이션 배포
이제 애플리케이션 로드 밸런서와 두 개의 대상 그룹이 생성되었으므로 두 대상 그룹을 해당 서비스에 연결합니다. 사용자 지정 리소스 정의 (CRD: Custom Resource Definition) 를 바인딩하는 두 개의 대상 그룹에 대한 매니페스트를 만들어 보겠습니다.
다음으로 클러스터에 애플리케이션 및 대상 그룹 바인딩을 생성합니다.
AWS 관리 콘솔로 다시 전환하여 이 구성을 시각화해 보겠습니다. 대상 그룹 중 하나로 이동하면 AWS 로드 밸런서 컨트롤러가 해당 파드를 대상으로 등록한 것을 확인할 수 있습니다.
대상이 정상 상태가 되면 ALB의 DNS 이름으로 이동하여 브라우저에서 엽니다. 검정색 또는 파란색 배경의 페이지가 표시될 수 있습니다. 페이지를 새로 고침하면 색상이 번갈아 나타납니다.
참고: 페이지에 액세스할 때 시간 초과 오류가 발생하는 경우 ALB의 보안 그룹에 IP 주소로부터의 HTTP 트래픽을 허용하는 인바운드 규칙이 있는지 확인하세요.
페이지가 번갈아 나타나는 경우 ALB는 요청을 해당 네임스페이스에서 실행 중인 두 서비스에 전달합니다. /black 서비스를 다른 클러스터로 이동하여 여러 Amazon EKS 클러스터 간에 트래픽을 로드 밸런싱할 수도 있습니다.
리소스 정리하기
이 블로그에서 생성한 인프라는 삭제하기 전까지는 계속해서 비용이 발생합니다. 향후 불필요한 과금 방지를 위해 삭제하시기 바랍니다. 다음 명령을 사용하여 이 데모를 위해 생성된 AWS 리소스를 정리하십시오.
결론
이 블로그에서는 ALB를 여러 Ingress 리소스와 공유하여 비용을 절감하는 방법을 살펴보았습니다. 또한 쿠버네티스 클러스터의 서비스 및 Ingress 리소스에서 로드 밸런서의 라이프사이클을 분리하는 방법을 살펴보았습니다. 마지막으로 ALB 가중치 대상 그룹을 사용하여 AWS 로드 밸런서 컨트롤러의 TargetGroupBinding 기능을 사용하여 여러 클러스터로 트래픽을 라우팅하는 방법을 배웠습니다.
이 블로그에 소개된 내용들에 대한 상세한 설명은 다음 링크들을 참조하십시오.
- AWS 로드 밸런서 컨트롤러 LiveDoc
- 다양한 Annotation 지원
- AWS 로드 밸런서 컨트롤러 프로젝트용 Github 링크
- AWS 로드 밸런서 컨트롤러에 대한 이전 게시물