Category: Networking & Content Delivery


AWS Lambda@Edge – 미리 보기 출시

지난 주에 한 AWS 고객으로 부터 Hacker News에 올린 댓글을 통해 한 통의 메일을 받았습니다.

그는 싱글 페이지 애플리케이션(SPA)을 빠른 속도의 웹 페이지 배포가 가능한 Amazon CloudFront를 통해 Amazon S3에 정적 웹 호스팅으로 서비스를 하고 있는데, 그 페이지에서 AWS Elastic Beanstalk에서 운용중인 자체 API를 통해 개별 사용자를 위한 동적인 작업을 진행하고 있다고 합니다. 그 분이 설명한 문제는 다음과 같습니다.

최근의 웹 환경에서는 검색 엔진을 위해 별도 색인을 생성하고 Facebook 및 Twitter 내에서 콘텐츠 미리보기가 올바르게 표시 되려면 각 페이지의 미리 렌더링 된 버전을 제공해야 합니다. 이를 위해서는 사용자가 Google 사이트를 방문 할 때마다 Cloudfront의 프론트엔드에 서비스를 제공해야 합니다. 그러나 사용자 에이전트가 Google/Facebook/Twitter 인 경우 미리 렌더링된 사이트 버전으로 리디렉션을 해야합니다.

한 명의 고객이 보내준 사용 사례를 넘기지 않고, 우리가 앞으로 이러한 문제를 개선하겠다는 사실을 알려주었습니다. 여러 고객들이 이미 엣지에서 신속하게 의사 결정을 내림으로써 맞춤형 최종 사용자 경험을 제공하고자 하는 의견을 주었습니다.

(레이턴시 기준) 고객에게 가까이 있는 위치에서 HTTP 요청을 “지능적으로” 처리하는 데는 많은 주목할만한 사용 사례가 있습니다. 예를 들어, HTTP 헤더 검사, 접근 제어 (특정 쿠키가 필요함), 모바일 디바이스 탐지, A/B 테스트, 크롤러 또는 봇에 대한 신속한 처리 또는 특수한 별도 처리, 레거시 시스템을 수용 할 수 있는 사용자 친화적인 URL 리다이렉트 등입니다. 이런 요구 사항 대부분은 단순한 패턴 일치 및 규칙으로 표현할 수 있는 것보다 좀 더 복잡한 처리 및 의사 결정을 필요로합니다.

AWS Lambda@Edge 서비스 소개
이러한 요구 사항을 지원하기 위해 AWS Lambda@Edge 미리 보기를 시작합니다. 이 새로운 람다 기반 처리 모델을 사용하면, 전 세계에 산재하는 AWS 엣지 로케이션에서 JavaScript 코드를 작성하여 실행할 수 있습니다.

이제는 가벼운 요청 처리 로직을 작성하고 CloudFront 배포판을 통과하는 요청(request) 및 응답(response)을 처리 할 수 있습니다. 아래와 같이 네 가지 별개의 이벤트에 대한 응답으로 코드를 실행할 수 있습니다.

Viewer Request – 콘텐츠 캐시 여부에 관계없이 모든 요청에 대해 코드가 실행됩니다. 다음은 간단한 헤더 처리 코드입니다.

JavaScript
exports.viewer_request_handler = function(event, context) {
  var headers = event.Records[0].cf.request.headers;
  for (var header in headers) {
    headers["X-".concat(header)] = headers[header];
  }
  context.succeed(event.Records[0].cf.request);
}

Origin Request – Your code will run when the requested content is not cached at the edge, before the request is passed along to the origin. You can add more headers, modify existing ones, or modify the URL.

Viewer Response – 캐시 여부와 관계없이 모든 응답에서 실행됩니다. 이것을 사용하여 브라우저로 다시 전달할 필요가 없는 일부 헤더를 정리할 수 있습니다.

Origin Response – 캐시 실패로 인해 원본(Origin)에서 다시 가져와서 엣지(Edge)에 반응한 후 코드를 실행합니다.

개별 코드는 URL, 메소드, HTTP 버전, 클라이언트 IP 주소 및 헤더 등 HTTP 요청 및 응답에서 나오는 여러 데이터를 접근할 수 있습니다. 간단하게 헤더를 추가, 수정 및 삭제할 수도 있고, HTTP 바디(Body)를 포함한 모든 값을 변경할 수 있습니다. 처음에는 헤더를 추가, 삭제 및 수정할 수 있습니다. 곧 바디를 포함한 모든 값에 대한 읽기 / 쓰기 접근 권한을 갖게됩니다.

자바 스크립트 코드는 HTTP 호출/응답의 한 부분이 되기 때문에 재빠르고 의미 있는 스스로 완결적인 코드여야 합니다. 다른 웹 서비스를 호출 할 수 없으며, 다른 AWS 리소스에 접근할 수 없습니다. 128MB의 메모리 내에서 실행되어야 하며 50ms 이내에 실행이 끝나야 합니다.

처음 시작을 해보려면, 새로운 람다 함수를 생성하고, CloudFront 배포를 트리거로 설정한 후 새 Edge 런타임을 선택하면됩니다.

CynNG_pVQAADVbR

그런 다음, 코드를 만들면 됩니다. Lambda 함수는 엣지 로케이션의 여러 가지 측면을 개선하는데 도움을 줄 것입니다.

미리 보기 신청하기
이 기능이 새로운 애플리케이션 및 개발 도구로서 창의적인 적용을 해 볼 수 있을 것으로 생각하고, 여러분이 직접 해 보시기를 권해 드립니다.

오늘 AWS Lambda@Edge 미리 보기를 시작하였고, 직접 해보시려면 미리 보기 신청 페이지에서 등록해 주시기 바랍니다.

Jeff;

이 글은 AWS re:Invent 2016 신규 출시 소식으로 AWS Lambda@Edge – Preview의 한국어 번역입니다. re:Invent 출시 소식에 대한 자세한 정보는 12월 온라인 세미나를 참고하시기 바랍니다.

IPv6 지원 업데이트 – CloudFront, WAF 및 S3 Transfer Acceleration

최근 Amazon S3 IPv6 지원 발표 이후, 이번에는 Amazon CloudFront, Amazon S3 Transfer AccelerationAWS WAF와 60개가 넘는 모든 CloudFront 엣지 로케이션에서도 IPv6 지원이 이용 가능합니다. AWS는 모든 자율 시스템 네트워크(ASN)에서 IPv6를 활성화하기 위한 단계적 마이그레이션 프로세스를 오늘부터 시작하고, 앞으로 몇 주에 걸쳐 모든 네트워크에서 확장 할 예정입니다.

CloudFront IPv6 지원
이제 각 Amazon CloudFront 배포 버전마다 IPv6 지원을 활성화 할 수 있습니다. IPv6을 사용하여, CloudFront 엣지 로케이션에 연결하는 방문자와 네트워크는 자동으로 IPv6 콘텐츠를 가져옵니다. IPv4를 사용하여 연결하는 경우, 예전처럼 작동합니다. 오리진(Origin) 서버 연결은 IPv4를 사용합니다.

새로 만든 배포 게시 지점은 자동으로 IPv6을 사용합니다. 기존 게시 지점을 변경하려면, Enable IPv6를 선택합니다. 이것은 콘솔 또는 CloudFront API에서 설정할 수 있습니다.

새로운 기능의 중요 사항은 아래를 참조하십시오.

  • 별칭 레코드(Alias Records) – 게시 지점에서 IPv6 지원을 활성화하면, DNS 항목은 AAAA 레코드를 포함해서 업데이트 합니다. Amazon Route 53과 별칭 레코드를 사용하여, 배포 도메인 전체 또는 일부를 가르키고 있는 경우, 그 도메인에 AAAA 별칭을 추가 해야합니다.
  • 로그 파일(Log Files) – CloudFront 접속 로그를 사용하는 경우, IPv6 주소가 c-ip 필드에 표시되므로, 로그 처리 시스템이 이를 처리할 수 있도록 해야 합니다.
  • 신뢰할 수 있는 서명(Trusted Signers) – 신뢰할 수 있는 서명 및 IP 주소 화이트 리스트를 함께 사용하는 경우, IP 허용 목록과 실제 내용 IPv4/IPv6 배포를 갖추는 신뢰된 서명과 각 URL의 IPv4 제한 배포 지점을 사용할 것을 적극 권장합니다. 이 모델에서는 IPv4 주소를 사용하여 전송 한 서명 요청에 서명한 것으로, 콘텐츠 요청이 화이트리스트에 실려 있지 않은 다른 IPv6 주소에서 주어진 같은 문제를 해결 할 수 있습니다.
  • CloudFormation – CloudFormation 지원을 준비 중 이번 출시에서는 CloudFormation 템플릿에서 만든 배포판에서 IPv6를 사용할 수 없습니다. 기존 스택을 업데이트 할 때, 스택에서 참조 배포판 설정 변경은 없습니다.
  • AWS WAF – AWS WAF와 CloudFront를 함께 사용하는 경우 IPv6 주소의 화이트리스트 또는 블랙리스트에 연결 되도록, WebACL과 IP 규칙 세트를 업데이트 해야합니다.
  • Forwarded 헤더 (Forwarded Headers) – 배포 지점에서 IPv6를 사용하는 경우, X-Forwarded-For 헤더에 IPv6 주소가 포함합니다. 오리진(Origin)이 형식 헤더를 처리 할 수 ​​있는지 확인하십시오.

자세한 내용은 IPv6 Support for Amazon CloudFront를 참고하십시오.

AWS WAF IPv6 지원
AWS WAF는 애플리케이션 레이어에서 발생하는 공격으로부터 응용 프로그램을 보호합니다. (자세한 사항은 AWS WAF 신규 서비스를 참고하십시오.)

AWS WAF가 IPv4 또는 IPv6 주소를 통해 요청을 검사 할 수 있습니다. IPv6와 일치하는 웹 접근 목록(ACL)을 만들 수 있습니다. 자세한 내용은 Working with IP Match Conditions를 참조하십시오.

기존 WAF 기능은 모든 IPv6 지원 성능에 보이는 변화는 없습니다. IPv6는 WAF가 수집 되어 표시한 샘플 요청으로 표시됩니다.

S3 Transfer Acceleration IPv6 지원
Amazon S3 전송 가속 기능이 IPv6를 지원하게 되었습니다. (자세한 내용은 AWS 스토리지 업데이트 – Amazon S3 Transfer Acceleration 참조). 업로드에 사용할 수 있는 이중 스택 엔드 포인트에 쉽게 전환 할 수 있습니다. 다음과 같이 변경 하면됩니다.

https://BUCKET.s3-accelerate.amazonaws.com

에서

https://BUCKET.s3-accelerate.dualstack.amazonaws.com

클라이언트 객체 생성 및 듀얼 스택 전송의 활성화를 가능하게 하는 AWS SDK for Java 사용 코드는 다음과 같습니다.

Java
AmazonS3Client s3 = new AmazonS3Client();
s3.setS3ClientOptions(S3ClientOptions.builder().enableDualstack().setAccelerateModeEnabled(true).build());

대부분 응용 프로그램과 네트워크 스택은 자동으로 IPv6 사용을 선호하는 경향이 있기 때문에 더 이상의 설정은 필요하지 않습니다. IPv6 주소와 함께 사용하기에 기능 동작에 문제가 없는지 확인하기 위해 패킷 IAM 정책을 검토하는 것이 좋습니다. 자세한 내용은 IPv6를 사용하여 Amazon S3에 요청 전송을 참조하십시오.

테스트를 잊지 마세요!
AWS 리전에 IPv6 연결에 제한이 있거나 존재하지 않는 경우, 대신 IPv4를 사용합니다. 이전에 블로그에서도 언급했지만, IPv6를 지원하도록 클라이언트 시스템을 구성 할 수 있습니다. 그러나, 이 경우 IPv6 패킷을 인터넷에 라우팅 설정하지 않은 네트워크에 연결해야 합니다. 이러한 이유에서 IPv6로 전환하기 전에 응용 프로그램 수준에서 네트워크 수행 지점 간 연결 테스트를 수행하는 것이 좋습니다.

Jeff;

이 글은 IPv6 Support Update – CloudFront, WAF, and S3 Transfer Acceleration의 한국어 버전입니다.

AWS 기반 웹 및 애플리케이션 서버 부하 테스트: A to Z

사용자가 이용하고 있는 온라인 서비스로부터 예상치 못한 느려짐을 겪거나, 접속 불가로 인해 서비스 이용 조차 할 수 없다면, 서비스에 중요한 재방문율(Retention Rate)과 유료 전환율(Conversation Rate)을 하락 시켜 비지니스에 큰 손실을 야기 할 수 있습니다. 이런 성능 관련 문제를 예방하기 위해 성능 테스트, 특히 부하 테스트에 대한 중요성이 크게 증가하고 있으며, 더불어 관련  도구 및 서비스의 다양성 또한 증가하고 있습니다.

이번 글은 AWS 클라우드에서 어떻게 웹/애플리케이션 서버의 부하 테스트를 하는지 모범 사례를 알려드리기 위한 것으로, 부하테스트 목적과 고려 사항 그리고 단계 및 도구 등을 대해 다루고자 합니다.

부하 테스트의 목적
일반적으로 부하 테스트는 서비스 개발 이후, 운영을 하기 직전 수행하는 테스트 중 하나로서, 실제 요구되는 부하를 서비스가 수용할 수 있는지를 확인하기 위한 작업 입니다. 사용자 활동을 시뮬레이션 하고 인프라 및 서버의 동작을 모니터링 함으로써, 전부는 아닐지라도, 많은 부분의 병목 현상(Bottleneck)을 제거할 수 있습니다.

부하 테스트의 목적으로는 보통 다음 세가지가 있습니다.

  • 현재 서비스 구성의 제한(limit)을 찾기 위함
  • 원하는 부하를 수용할 수 있게끔 구성되었는지 확인하기 위함
  • 병목 지점을 찾고 병목 현상을 제거하기 위함

부하 테스트 전 고려되어야 할 점
실제 성능 테스트 시, 부하 테스트를 비중 있게 여기지 않는 경우가 많으며, ApacheBenchJMeter 와 같은 도구를 다운로드 한 뒤, 특정 시나리오를 기반으로 하여 도구를 실행하는 것만으로 충분하다고 생각하는 경우가 있습니다. 하지만, 실제 워크로드는 다양한 변수와 시나리오를 가지고 있기 때문에, 부하 테스트를 진행할 때 충분히 이점을 반영 하여 야지만 실제 서비스에서 예상 가능한 결과를 가져올 수 있다는 것은 분명한 사실 입니다.

그럼 실용적인 부하 테스트를 위해 어떤 부분들을 고려해야 할까요?

  • 충분한 테스트용 서버 자원 확보: 최대의 트래픽을 생성하여 테스트 하기 위해서는 충분한 서버 자원이 요구되며, 부족할 경우 적절한 테스트가 이루어지기 힘듭니다.
  • 테스트 시, 블랙박스 혹은 격리된 환경 제어: 부하 테스트는 많은 요청과 패킷을 생성하기 때문에 사내 인프라의 많은 부분을 포화 상태로 만들기 쉽습니다. 이를 방지하기 위해 제한된 자원만 할당된 블랙 박스 혹은 격리된 환경에서 테스트를 수행하는 경우가 많습니다.
  • 글로벌 기반의 부하 생성: 글로벌 서비스의 경우, 전 세계 각 지역에서 부하를 생성하여 테스트를 진행하여야만 실제 사용 패턴에 가까운 시나리오가 될 수 있습니다. 이를 통해 글로벌 커버리지를 확인할 수 있으며, 실제 워크로드에서 얻을 수 있는 유사한 각종 성능 관련 지표도 얻을 수 있습니다.
  • 높은 비용과 불규칙적인 사용성에 대한 주의: 격리된 환경과 더불어 여러 리전을 커버하기 위한 테스트 환경은 때로 높은 비용을 요구합니다. 구성된 환경은 짧은 기간 동안만 집중적으로 사용되기도 하며, 안정적인 서비스가 유지될 땐 드물게 사용되기도 하기 때문에, 사용하지 않을 때도 유지하여야 하는 등의 자원을 효율적으로 사용하지 못해 불필요한 비용이 발생 하기도 합니다.
  • 높은 아키텍처 복잡성에 대한 주의: 상기 언급된 부분들을 고려하여 부하 테스트 환경을 구성한다면 꽤나 높은 복잡성이 요구 됩니다. 나아가 반복적인 테스트를 위해, 가상의 가짜(Dummy) 데이터 등에 의해 지저분해진 환경을 초기화 시켜줄 수 있는 방안도 필요 합니다.

AWS 클라우드 기반 부하 테스트의 장점
AWS 클라우드는 부하 테스트를 진행하기 위해 고려할 사항에 대한 적절한 해답을 가지고 있습니다.  AWS 클라우드에서 부하 테스트 하게 된다면 어떤 특징을 가지고 있을까요?

  • 사용한 만큼 지불하는 비용 효율성: Amazon EC2 인스턴스는 사용한 만큼만 비용이 발생하기 때문에, 테스트 조건에 맞는 인스턴스 타입을 선택하여 비용 효율성을 높일 수 있습니다. 예를 들어, 정식 부하 테스트를 진행하기 전에 저렴한 마이크로 인스턴스 수십~수백대를 활용하여, 서버 워밍업을 저렴한 비용으로 할 수 있습니다. 또한, 인스턴스 사용이 끝나면 즉시 종료할 수 있어 불필요한 비용 발생을 줄일 수 있습니다.
  • 충분하고 유연한 컴퓨팅 자원 제공: AWS가 제공하는 컴퓨팅 자원을 활용한다면, 필요한 규모의 부하에 대해 자유롭게 테스트를 수행할 수 있습니다. 또한, 오토스케일링(Auto Scaling)을 통해 부하 테스트 시 자원을 자동으로 증설 혹은 감소 시킬 수 있습니다.
  • 글로벌 리전(Region)으로부터의 부하 생성: AWS가 제공하는 글로벌 인프라를 통해 전 세계 각 리전으로부터의 부하 생성을 손쉽게 할 수 있습니다.
  • 쉽고 단순한 아키텍처 구성 및 관리: AWS CloudFormation 을 비롯한 다양한 배포 자동화 서비스 및 기능을 통해 프로덕션과 테스트 용 환경을 동일한 방법으로 손 쉽게 구성할 수 있습니다. 뿐만 아니라 관리형 서비스를 활용하여 운영 측면에서의 부담도 줄일 수 있어, 테스트 환경 구축에 관한 복잡성을 줄일 수 있습니다.

부하 테스트의 단계
부하 테스트는 서비스 전체 스택을 대상으로 진행할 수도 있지만, 최근에는 마이크로서비스(Microservices) 나 서비스 지향 구조(Service-Oriented Architecture) 등의 형태로 서비스를 디자인하는 경우가 많아, 전체 스택을 구성하고 있는 작은 컴포넌트들부터 진행되는 경우가 많아지고 있습니다.

또, 빠른 병목 현상 발견과 수정을 위해, 애플리케이션 로직이 적용되기 전 순수한 인프라 수준에서 시작하여 작은 컴포넌트들, 솔루션, 그리고 애플리케이션 순으로 부하 테스트를 확대해 나갈 수도 있습니다.

아래는 일반적으로 수행할 수 있는 부하 테스트 단계 입니다.

  • 비결합(Loosely Coupled)된 개별 컴포넌트에 대한 부하 테스트: 이를 통해 각 컴포넌트 별 병목 현상을 보다 빠르게 발견하고 수정할 수 있습니다.
  • 내부 서비스에 대한 부하 테스트: 로그 기록 서비스와 같이 높은 처리량이 요구되는 서비스나, 결제 서비스와 같이 전체 서비스 품질에 있어 중요한 내부 서비스를 대상으로 테스트를 진행 합니다.
  • 외부 서비스에 대한 부하 테스트: Facebook, Twitter 등의 소셜 서비스나 Google 등의 플랫폼에 대한 서비스들, 또는 푸시 알림 서비스 등의 외부 서비스를 대상으로 테스트를 진행 합니다.
  • 전체 스택에 대해 부하 테스트: 개별 컴포넌트들에 대한 테스트를 완료한 뒤, 컴포넌트간의 상호작용을 알기 위해 처음부터 끝까지 전체 스택에 대해서 테스트 진행 합니다.

단계별 부하 테스트 수행 방법
앞서 언급한 것처럼, 부하 테스트는 전체 스택에 대해서도 수행 가능하지만, 작은 비결합된 컴포넌트나 기능 단위로도 수행 가능합니다. 그리고 작은 단위로 수행될 수록 더 분명하게 병목 지점을 파악하기에 수월 합니다. 그렇기에, 가능한 작은 단위부터 단계별로 진행하는게 원하는 결과를 얻어내는데 효율적입니다.

다음은 전형적인 3단계(3-tier) 웹 서비스에 대해 단계별로 부하 테스트를 진행하는 것을 설명하고 있습니다.

load-test-image001

  1. 최초 ‘WEB’ 을 출력하는 웹 페이지를 대상으로 동시 연결성에 대한 테스트 수행 → 결과 평가→최적화 진행 (Client →Web Server)
  2. 웹 서버를 통해 애플리케이션 서버에서 넘겨 받은 ‘APPLICATION’ 을 출력하는 웹 페이지를 대상으로 동시 연결성에 대한 테스트 수행→ 결과 평가 → 최적화 진행 (Client →Web Server → App Server – w/o Logic)
  3. 데이터베이스에서 최소한의 쿼리 결과를 전달 받아 출력하는 웹 페이지를 대상으로 동시 연결성에 대한 테스트 수행 →결과 평가 → 최적화 진행
    (Client →Web Server → App Server – w/o Logic → Database)
  4. 3-tier 스택 전체를 대상으로 애플리케이션 로직이 적용된 페이지에 동시 연결성에 대한 테스트 수행 → 결과 평가 → 최적화 진행
    (Client → Web Server → App Server – with Logic →Database)
  5. 4번을 기반으로 다양한 시나리오를 지정하여 테스트 수행 → (얻고자 하는 지표 기준에 대해서) 결과 평과 → 최적화 진행

부하 테스트 시, 각 레이어별 고려하여야 할 사항
부하 테스트를 수행한 뒤 각 레이어별로 발생할 수 있는 상황과 고려하여야 할 부분에 대해서 알아보도록 하겠습니다.

  1. 네트워크 용량 확인: 테스트 환경이 구성된 인프라와 관련하여 여러가지 지표를 확인할 수 있지만, 대표적으로 아웃바운드 연결이 예상되는 최대의 부하를 처리할 수 있는지 확인할 필요가 있습니다. Amazon EC2 의 경우 인스턴스 타입 마다 서로 다른 네트워킹 성능을 제공하고 있기에, 부하에 따른 적절한 인스턴스 타입 선택이 중요 합니다. 또 사내 인프라와 프라이핏하게 연결되어 있다면, VPN 관련 네트워킹 성능에 대해서도 확인을 하여야 합니다.
  2. 부하 생성 클라이언트: 앞서 설명하였듯이 부하 테스트의 요구사항 중 하나로, 필요한 만큼의 부하를 생성할 수 있는 충분한 인스턴스의 확보가 요구됩니다. 하지만, 설정 및 구현 방식에 의해 하나의 부하 생성 클라이언트가 처리할 수 있는 동시성에 큰 제한이 있다면, 필요 이상으로 복수개의 인스턴스가 요구되어 비용이 증가할 수 있습니다. 이럴 땐 Thread 기반의 툴 보다는 높은 동시성을 제공하는 Async IO 기반의 툴을 사용하여 테스트를 진행하는게 좋습니다.
  3. 로드 밸런싱: ELB(Elastic Load Balancing)는 서비스 전체 부하를 백엔드에 등록된 복수개의 인스턴스로 분산하는 기능을 제공합니다. 부하 테스트를 수행할 때 다양한 이유로 기대치 보다 낮은 결과나 5xx 에러가 발생하는 것을 볼 수 있습니다. 이 때, ELB 가 제공하는 다양한 모니터링 지표들을 확인하면, 어느 곳에서 병목 현상이나 에러가 발생되는지 확인하는데 도움이 됩니다. 가장 자주 발생하는 문제는, 503 Server Unavailable 이나 504 Gateway Timeout 에러 발생과 동시에, ELB 의 모니터링 지표에 SurgeQueueLength 가 1024 로 기록되고 SpilloverCount 가 0 보다 높을 경우 입니다. SurgeQueueLength 는 ELB 에 등록된 백엔드 인스턴스가 요청을 처리하지 못하여 쌓이게 되는 ELB 의 큐 이며, 앞서 언급한 것처럼 1024가 큐의 최대 크기 입니다. 이 최대 크기를 넘어서면 요청을 한 클라이언트에 5xx 에러를 보내게 되고, 동시에 SpilloverCount 가 기록 됩니다. 이 문제를 해결하기 위해서는 적시에 Auto Scaling 이 일어날 수 있도록 적절한 지표를 기준으로 알람을 발생 시킬 수 있도록 해야 합니다. 백엔드 인스턴스에서 동작하는 시스템이 어떤 자원을 더 많이 사용하는지 확인을 하고, 그 자원의 지표를 기준으로 Auto Scaling 을 설정하는 것이 좋습니다. SurgeQueueLength 를 기준으로 알람이 발생하게 하는 것도 한 가지 방법 입니다. ELB 가 제공하는 지표들은 여기에서 확인할 수 있습니다.
    추가로 ELB 도 발생하는 부하에 따라 Auto Scaling 을 통해 규모가 변화되도록 설계 되어 있습니다. 만약, 매우 급격한 트래픽 증가가 일어날 때 ELB 가 확장되는 속도가 증가하는 트래픽을 수용하지 못한다면 5xx 에러가 발생할 수 있습니다. 이를 방지 하기 위해, 미리 점차적으로 증가하는 부하 테스트를 통해 어느정도 ELB 를 확장 시켜 둘 수 있습니다. 또한, ELB 에 등록된 백엔드 인스턴스에서 Keep-Alive 기능을 활성화 시켜, ELB 와 백엔드 인스턴스간에 불필요한 연결 수립이 일어나는 것을 방지한다면 더 높은 성능을 기대할 수 있습니다.
  4. 서버 인스턴스: 서버 인스턴스의 설정 값에 따라 웹/애플리케이션 서버의 자원 사용 효율성이 달라 집니다. 대표적으로 Linux 서버의 open files 숫자를 늘려 두지 않으면, 동시 접속이 기본값인 1024 개로 제한되어 서버 인스턴스를 효과적으로 사용할 수 없습니다.
  5. 애플리케이션 서버: 애플리케이션 서버의 종류마다 다르지만, 일반적으로 Tomcat 등의 Thread 기반의 애플리케이션 서버일 경우, Thread Pool 의 크기가 너무 작다면 처리 되어야할 요청들이 기다리는(waiting) 상태가 길어져 전체 부하 테스트의 효율성을 떨어뜨릴 수 있습니다. 최근에는 Thread 기반의 애플리케이션 서버가 가지고 있는 제약으로 인해, Event 기반의 비동기 형태의 애플리케이션 서버가 자주 사용되어 집니다.
  6. 애플리케이션: 애플리케이션 코드와 프레임워크 둘로 나누어 생각해 볼 수 있습니다. 애플리케이션 코드 내에서 잘못된 방식으로 프레임워크나 API 를 사용할 수 있으며, blocking 코드가 포함되어 있다거나, 불필요한 연산을 진행, 또 테스트 코드를 삭제하지 않았다는 등의 문제가 있을 수 있습니다. 이 때에는 적절한 Unit Test 와 Lint 등을 통해 문제를 조기에 발견할 수 있어야 합니다.  사용하는 웹 프레임워크나 ORM(Object-relational mapping)과 같은 라이브러리가 가지고 있는 버그로 인하여 문제가 발생할 수도 있습니다. 애플리케이션 관련 다양한 문제를 해결하기 위해 APM(Application Performance Monitoring) 을 활용하여 성능을 모니터링 하는 것도 한가지 방법 입니다.
  7. 데이터베이스: CPU 사용률과 응답 시간(response time) 등을 확인할 필요가 있습니다. 특히 데이터베이스를 설정한 방법에 따라 더 요구되는 자원을 눈 여겨 볼 필요가 있습니다. 최근에는 성능을 향상 시키기 위해 메모리를 적극 활용하게끔 설정을 하는 경우가 많으며, 이때에는 메모리 사용률이 특정 수치 이상으로 넘어갈 경우, 알람을 발생 하도록 설정하여 병목 지점 확인이 가능 하겠습니다.

부하 테스트 관련 도구 및 서비스
부하 테스트를 위해 사용할 수 있는 다양한 툴과 서비스들이 존재 합니다. 간단한 소개와 함께 특징들을 살펴보겠습니다.

  • ApacheBench (http://httpd.apache.org/docs/2.2/en/programs/ab.html): 일반적으로 HTTP 웹 서버의 성능을 측정하기 위해서 자주 사용되는 툴입니다. 기본적인 HTTP 연결에 대해서 테스트를 할 때 자주 사용되는 툴이지만, HTTP/1.1 을 지원하지 않고, 한번에 하나의 대상 URL로 테스트가 가능한 것 등의 제한이 있습니다.
  • Siege (https://www.joedog.org/siege-home/): HTTP 부하 테스트와 벤치마킹 유틸리티 입니다. 한번에 복수개의 URL 로 테스트가 가능하고, Basic 인증을 지원하며 HTTP와 HTTPS 프로토콜로 테스트가 가능하는 등 ApacheBench 의 제한을 어느정도 해소 해 줍니다. 또 ApacheBench 와 비슷한 인터페이스를 가지고 있어 다른 툴과의 연계가 자유로운 편입니다. 하지만 Thread 기반으로 구현되어 있어 동시성에 제한이 있으며, 미미할 수 있지만 Context Switching 등으로 인하여 성능에도 영향이 있습니다.
  • JMeter (http://jmeter.apache.org/): 1998 년 부터 시작된 프로젝트로서 오랫동안 기능 강화를 지속해오고 있는 Java 기반의 부하 테스트 툴 입니다. HTTP 뿐만 아니라 다양한 프로토콜을 지원하며, 많은 기능을 가진 GUI 를 제공 합니다. 실제 워크로드를 시뮬레이션 하기 위해 다양한 방법으로 커스터마이징이 가능합니다. 하지만 앞서 언급한것처럼 Thread 기반으로 구현되어 있어 성능과 동시성에 대해서 제한이 있습니다. 이를 해결하기 위해, 복수개의 인스턴스에서 실행시켜 테스트를 수행할 수 있는 Remote Testing 기능을 지원 합니다. 복수개의 EC2를 활용하거나, BlazeMeterFlood.io 와 같은 JMeter 를 지원하는 부하 테스트 서비스를 사용할 수도 있습니다.
  • The Grinder (http://grinder.sourceforge.net/): Java 기반의 부하 테스트 프레임워크 입니다. Agent 가 지정한 값을 기반으로 부하를 생성하며, IDE 형태의 콘솔에서 Agent 들을 제어 및 결과 모니터링이 가능합니다. 마찬가지로 Thread 기반으로 구현되어 있어 성능과 동시성에 대해 제한이 있습니다.
  • Gatling (http://gatling.io/): Akka 와 Netty 기반의 Scala 로 개발된 부하 테스트 프레임워크 입니다. Thread 기반이 아닌 Event 와 Async IO 기반으로 구현되어, 높은 성능을 제공하며 HTML 보고서 생성 기능은 물론 시나리오를 DSL 로 작성하여 부하 테스트에 사용할 수 있는 기능을 제공하고 있습니다.
  • Tsung (http://tsung.erlang-projects.org/): Erlang 으로 개발된 부하 테스트 툴로서, HTTP는 물론 Websocket 이나 인증 시스템, 데이터베이스, MQTT 와 같은 TCP 기반의 다양한 프로토콜을 지원합니다. 동시성 지향 프로그래밍 언어 (concurrency-oriented programming language) 인 Erlang 이 가지고 있는 장점으로 인해, 성능과 확장성, 내결함성(Fault Tolerance)에서 큰 이점을 제공하고 있습니다. GUI 를 제공하지 않아 CLI 또는 Script 를 활용하여야 합니다.
  • Bees (https://github.com/newsapps/beeswithmachineguns): AWS 의 장점을 적극 활용한 오픈 소스 부하 테스트 툴로서, 부하를 분산 생성하기 위해 사용자의 AWS 계정에서 EC2 인스턴스를 지정한 개수만큼 생성하여 부하 테스트 대상에 테스트를 진행합니다. 비용을 줄이기 위해 스팟 인스턴스를 생성하여 활용할 수 있는 옵션도 제공하고 있습니다. 부하 테스트를 위해 ApacheBench 를 사용하기 때문에 ApacheBench 가 가지고 있는 제한을 그대로 가지고 있습니다.
  • Vegeta (https://github.com/tsenart/vegeta): Go 언어로 개발된 오픈소스 HTTP 부하 테스트 툴이며 CLI 로 사용하거나 라이브러리로 사용 가능합니다. 보통의 다른 툴과 다르게 초당 일정한 속도로 특정 수치의 요청을 지속하는데 초점을 맞추고 있어, 예상되는 최대 트래픽이 지속적으로 발생하였을 때 서비스와 인프라의 상태가 어떻게 변화하는지 확인하는데 적합한 툴 입니다.
  • RedLine13 (https://www.redline13.com/): AWS 의 Advanced Technology Partner 중 하나로서, AWS 기반의 부하 테스트를 수행하는 서비스 입니다. 사용자의 AWS 계정에서 IAM 을 생성하여 RedLine13 과 연동을 하면, 사용자의 AWS 계정에서 Agent 가 포함된 인스턴스가 실행되어 테스트가 진행 됩니다. 스팟 인스턴스를 활용할 수 있어 비용을 줄일 수 있습니다. 여기에서 RedLine13 과 Apache JMeter 를 활용하여 모바일 애플리케이션을 테스트 하는 데모를 보실 수 있습니다.
  • Loader.io (https://loader.io/): 클라우드 기반의 부하 테스트 서비스로서, 웹 페이지에서 대상 서버를 선택하고 원하는 동시성 등을 지정할 수 있으며, 그 결과를 보기 좋게 표시해 줍니다. 또한, 진행한 테스트를 추후에 리플레이 할 수도 있습니다.
  • Goad (https://goad.io/): AWS Lambda 를 활용하여 부하를 분산 생성하여 테스트를 수행하는 오픈 소스 툴로서 Go 언어로 개발 되었습니다. 실제 AWS 의 이점과 AWS Lambda 의 강력함을 잘 활용한 툴 입니다. 툴을 실행하면 AWS Lambda 함수를 생성 (혹은 갱신) 하여, 대상 URL 에 동시적으로 부하 테스트를 시작합니다. 그리고 각 결과는 AWS SQS 로 보내어지고, 최종적으로 최초 실행한 툴에서 결과를 취합하여 보여줍니다.
    load-test-image003

그밖에도 다양한 AWS Marketplace에서도 다양한 파트너들의 부하 테스트 솔루션을제공하고있습니다.

부하테스트 시 유용한 팁 모음
AWS 클라우드 기반으로 부하 테스트를 진행하는데 있어서 알아두면 도움이 되는 팁들을 간단하게 소개해 드리고자 합니다.

  • 로그 기록과 확인: 부하 테스트를 진행할 때, 로그 작성은 File IO 를 요구하는 작업이기에, 미미하게 테스트 수행 능력에 영향을 미칠 수 있습니다. 특히나 테스트 환경에서는 로그 수준을 낮추어(verbose 또는 debug) 더 많은 로그가 기록되도록 하는 경우가 많아, 실제 프로덕션에 비해 성능에 미치는 영향이 더 클 수 있습니다. 하지만 가능한 로그를 기록하는게 추후 발생하는 문제 파악에 도움을 줄 수 있기 때문에 기록을 하는게 권장 됩니다. 또는, 최초의 워밍업을 진행할 때 로그를 활성화하여 진행을 하고, 이후의 테스트에 대해서는 로그를 비활성화하여 진행할 수도 있겠습니다. 만약 그 결과가 기대에 미치지 않는다면, 다시 로그를 활성화 한 뒤 테스트를 진행하고, 생성되는 로그를 통해 문제를 파악할 수 있겠습니다.
  • 적절한 인스턴스의 선택: EC2 인스턴스는 요구되는 워크로드에 맞추어 선택할 수 있도록 다양한 종류가 준비되어 있습니다. 사용하는 웹/애플리케이션/데이터베이스에 따라 상대적으로 더 요구되는 자원은 다를 수 있으며, 그에 맞추어 인스턴스를 선택하는 것이 비용도 절약하며 더 적합한 성능을 발휘할 수 있겠습니다. 예를 들어, 특별한 연산이 수행되지 않고 다른 서비스와 통신이 주 목적이라면, 적은 CPU 자원과 적절한 Memory 자원, 그리고 높은 Bandwidth 와 Enhanced Networking 을 제공하는 인스턴스가 비용과 성능 관점에서 좋은 선택일 수 있습니다.
  • 비용 최소화: 유의미한 결과를 얻기 위해 부하 테스트 대상 환경을 가능한 실제 환경과 비슷하게 구성할 필요가 있습니다. 물론, 실제 프로덕션 환경에서 테스트를 수행할 수도 있지만, 이는 가상의 가짜(Dummy) 데이터를 생성하여 프로덕션 환경을 어지럽히고 라이브 서비스의 안정성을 헤치는 등의 위험성이 있기에 적극적으로 피해야 합니다. 실제 프로덕션 환경과 비슷한 환경을 구성하여 부하 테스트를 수행하는데 있어서 가장 먼저 고려하여야 할 사항은 비용 입니다. 일반적으로 최대 부하에 대한 테스트 진행을 위해, 수십에서 수백 대의 인스턴스가 필요할 수 있으며, 큰 규모의 부하를 생성하기 위해서도 많은 인스턴스가 요구되기 때문입니다. 이 때, 비용을 최소화 하기 위해 스팟 인스턴스를 활용할 수 있습니다. 스팟 인스턴스는 EC2 컴퓨팅 예비 용량에 입찰을 통해 온디맨드 요금과 비교하여 할인된 요금으로 사용할 수 있는 방법을 제공하며, 일반적으로 50~90% 저렴한 비용으로 사용할 수 있습니다. 자세한 내용은 여기를 참조 하시기 바랍니다.
  • 다양한 도구와 서비스의 복합적 활용: 앞서 부하 테스트를 위한 다양한 툴과 서비스에 대해서 알아 보았습니다. 부하 테스트를 진행할 때, 어떤 특정 툴 또는 서비스 하나만 선택해서 사용 할 필요는 없습니다. 각 툴과 서비스 별로, 목적성과 고유의 특징을 가지고 있기에, 용도에 맞게 복합하여 사용하는게 더 효율적일 수 있습니다. 예를 들어, GUI 의 완성도가 높고 다양한 시나리오를 설정할 수 있는 JMeter 는 웹 애플리케이션 내에서 사용자의 행동 흐름에 대해 부하 테스트를 하는데 적합할 수 있습니다. 그 이외의 툴과 서비스들도 특징들이 있으며 다음과 같이 활용할 수 있겠습니다.
    도구 명 활용 방법
    JMeter 웹 애플리케이션 내에서 사용자의 행동 흐름에 대해 부하 테스트를 하고 싶을 때
    Tsung API 가 수용할 수 있는 최대치의 부하를 알고 싶을 때
    Vegeta 어떤 API 에 대해 초당 특정 수치의 요청이 지속될 경우 발생하는 상황을 파악하고 싶을 때
    Goad 부하 생성 클라이언트 구성을 포함한 부하 테스트 관련 인프라 구성을 피하고 싶을 때
    RedLine13 JMeter 로 테스트 플랜을 작성하여 활용을 원하지만, 비용을 최소화 하고 싶고 사용한 만큼만 비용이 발생하길 원할 때
    Blazemeter 높은 동시성을 위해 JMeter 의 Remote Testing 기능을 활용하고 싶지만, 테스트 플랜 작성에 집중하고, 부하 테스트 관련 인프라 구성은 하고 싶지 않을 때
    Loader.io 부하 테스트 관련 인프라 구성을 하고 싶지 않고, Tsung 과 비슷한 목적으로 사용하고 싶을 때

부하 테스트에는 보통의 시나리오 기반의 가상의 워크로드에 대한 부하 테스트 뿐만 아니라, 실제 워크로드에 대한 부하 테스트를 위해 프로덕션에서 발생하는 트래픽을 활용하는 방법도 있습니다. 프로덕션 환경의 실제 트래픽을 활용하기 위해서는, 트래픽을 재사용 하기 위해 기록하거나 곧바로 테스트 환경으로 리플레이 해 주는 gor (https://goreplay.org/) 와 같은 툴을 사용할 수 있습니다. 프로덕션 환경의 실제 트래픽을 반복하여 활용할 수 있다는 이점 이외에도, 서비스 및 애플리케이션 업데이트 예정 버전에 실제 트래픽을 흘려 보내 사용성에 대한 테스트도 진행할 수 있는 장점도 있습니다.

추가로, 많은 경우 부하 테스트는 개발 주기 마지막에 진행되는 경우가 많습니다. 애자일 방법론과 지속적인 통합(CI/CD)을 활용하는 경우 조금 더 일찍, 자주 부하 테스트를 진행할 수 있으며, 이를 통해 추후 발생할 수 있는, 비용이 많이 드는 성능 문제를 미리 방지할 수 있습니다. 따라서, 가능한 개발 주기에 부하 테스트를 포함하여 자주 진행하는 것이 바람직하다고 볼 수 있습니다.

AWS 에서 제공하는 방대한 인프라와 이미 부하에 대해 고려되어 설계된 관리형 서비스, 그리고 다양한 규모 관련 기능들을 적극 활용하여 서비스를 구축한다면 가변적인 부하에도 유연한 서비스를 제공할 수 있을 것 입니다.

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 김필중 솔루션즈 아키텍트께서 작성해주셨습니다.
load-test-image005

AWS Application Load Balancer 서비스 공개

지난 2009년 Elastic Load Balancing (ELB) 서비스를 시작하였습니다.(New Features for Amazon EC2: Elastic Load Balancing, Auto Scaling, and Amazon CloudWatch 참고). ELB는 AWS 기반 애플리케이션의 가장 중요한 아키텍처의 구성으로서 자동 스케일링과 함께 고가용성을 유지하면서 손쉽게 확장 및 감소를 할 수 있도록 도와 주고 있습니다.

상위 레이어 로드 밸런싱 기능 지원
잘 알려진 OSI 모델에 따르면, 로드밸런싱은 일반적으로 Layer 4 (네트워크) 또는 Layer 7 (애플리케이션)에서 처리합니다.

Layer 4 로드밸런싱은 네트워크 프로토콜 레벨에서 제공 되며, 실제 패킷을 살펴 보지는 못하기 때문에 HTTP나 HTTPS 같은 특정 프로토콜을 인지하지 않고 부하를 분산합니다.

대신 Layer 7 로드밸런싱은 좀 더 정교하고 강력한 기능을 제공합니다. 패킷을 조사하고, HTTP 및 HTTPS 헤더에 접근해서 좀 더 지능적인 부하 분산 작업이 가능합니다.

AWS Application Load Balancing 서비스 제공
오늘 ELB의 새로운 옵션인 애플리케이션 로드밸런서(Application Load Balancer)를 공개합니다. 이 서비스는 Layer 7 로드밸런싱을 통해 많은 고급 기능을 제공합니다. 기존의 로드 밸런싱 기능은 앞으로 Classic Load Balancer라고 부르게 되며, 여전히 Layer 4 및 Layer 7 기능을 제공합니다.

애플리케이션 로드밸런싱은 콘텐트 기반 라우팅 및 콘테이너 상 애플리케이션을 지원합니다. 표준 프로토콜인 WebSocket 및 HTTP/2를 지원하며, 인스턴스 및 콘테이너의 추가 가시성을 제공하게 됩니다. 콘테이너 및 EC2 인스턴스에서 실행하는 웹 사이트 및 모바일 앱에 대해 부하 분산에 대한 효과가 매우 높을 것입니다.

이제 좀 더 자세하게 애플리케이션 로드밸런싱 기능을 살펴 보겠습니다.

콘텐츠 기반 라우팅
애플리케이션 로드밸런서는 HTTP 헤더에 접근해서 다른 백엔드 서비스에 따라 다른 요청을 처리할 수 있습니다. 예를 들어, URL에 /api라는 경로를 포함하고 있는 경우, 다른 서버 그룹(일명 target group)으로 요청을 보낼 수 있으며 /mobile은 또 다른 서버 그룹으로 보낼 수 있습니다. 이를 통해 여러 개의 마이크로서비스를 독립적으로 실행하고 확장할 수 있도록 할 수 있습니다.

각 애플리케이션 로드밸린서는 10개의 URL 규칙을 만들 수 있으며, 앞으로 더 많은 라우팅 방법을 제공할 계획입니다.

콘테이너 기반 애플리케이션 지원
많은 AWS 고객들이 자사의 마이크로서비스를 콘테이너 형식으로 만들어서 Amazon EC2 Container Service를 통해 배포하고 있습니다. Amazon ECS는 하나의 EC2 인스턴스에 한 개 이상의 서비스를 배포 및 운영할 수 있습니다. 그러나, 포트 맵핑 및 헬스 체크 등에 대해 전통적인 로드밸린서로는 어려운 문제가 있습니다.

애플리케이션 로드밸린서를 통해 콘테이너 기반의 애플리케이션 역시 같은 타겟 그룹 내에 다수의 포트를 사용할 수 있으며, 세부적인 포트 수준의 헬스 체크를 지원할 수 있게 되었습니다.

더 자세한 통계 수치 제공
애플리케이션 로드밸린서는 포트 기반의 헬스 체크에 대한 리포트를 실행할 수 있어, HTTP 응답에 대한 범위를 정의할 수 있고 자세한 오류 코드에 대한 부분도 확인할 수 있습니다.

콘텐츠 기반의 라우팅을 제공함으로서 각 마이크로서비스의 다양한 통계 수치도 얻어낼 수 있습니다. 이는 마이크로서비스 기반에서 운영하는 타겟 그룹 또는 특정 EC2 인스턴스 그룹에 대한 유효한 부수 효과입니다. 개별 서비스에 대한 부하에 대해 좀 더 자세히 살펴 볼 수 있음으로서 확장성에 대한 도움을 얻을 수 있습니다.

애플리케이션 로드밸린서는 CloudWatch에서 전체 트래픽 (overall traffic in GB), 액티브 연결 갯수, 시간당 연결 비율 등의 새로운 통계 수치를 제공합니다.

추가 프로토콜 지원
애플리케이션 로드밸린서는 WebSocketHTTP/2를 지원합니다.

WebSocket은 클라이언트와 서버간 긴 TCP 연결을 제공하는 프로토콜로서, 긴 연결이 필요할 경우 기존의 HTTP 연결을 통해 하던 고전적인 풀링 방식을 개선할 수 있습니다. 모바일 앱의 경우, 주식 가격이나 스포츠 경기 점수 등 다양한 동적 데이터를 서로 주고 받을 때 유용하며 ALB는 ws://wss:// 프로토콜을 지원합니다.

HTTP/2 역시 기존 HTTP 1.1에 비해 중요한 기능 향상을 가진 프로토콜로서 단일 연결에 멀티플렉스 요청을 처리할 수 있고, 바이너리 속성을 통한 네트웍 트래픽을 줄여줍니다.

애플리케이션 로드밸린서는 실시간 스트리밍 뿐만 아니라 WebSocket 로드를 최적으로 처리 가능합니다. 요청 및 응답에 대한 버퍼링 대신 스트리밍 방식으로 처리함으로서 지연 속도를 줄이고 애플리케이션의 성능을 눈에 띄게 높일 수 있습니다.

ALB 생성하기
이제 애플리케이션 로드밸린서를 만들어서 트래픽을 처리해 보겠습니다.

The Elastic Load Balancing Console에 두 가지 중 하나의 로드밸린서를 선택할 수 있습니다.

Application load balancer을 선택하고 이름(MyALB)을 넣고 internet-facing를 선택 후, HTTPS listener를 추가합니다.

같은 화면에서 VPC를 선택하고 (VPC만 지원함), 원하는 가용 영역과 서브넷을 선택합니다. 애플리케이션 로드밸린서를 태그하고 Configure Security Settings 설정으로 갑니다.

HTTPS listener를 선택했기 때문에 ALB는 인증서가 필요합니다. IAM에 있는 기존 인증서를 선택하거나, AWS Certificate Manager (ACM)에서 발급 받거나 또는 로컬 인증서를 업로드할 수 있습니다.

오른쪽에서 보안 그룹을 설정합니다. 새로운 보안 그룹을 만들었으나 기존 VPC나 EC2 보안 그룹을 사용하실 수도 있습니다.

다음 단계로 타겟 그룹(main)을 만들고, 헬스 체크를 기본으로 체크합니다.

이제 타겟그룹의 EC2 인스턴스 세트를 선택하여 애플리케이션 로드밸린서를 통해 분산할 80포트를 선택합니다.

마지막 단계로 모든 설정을 확인 한후 Create를 누르면 됩니다.

Create 누르고 나면, 애플리케이션 로드밸린서가 수 분 안에 만들어집니다.

추가 타겟 그룹을 만들 수도 있습니다.

각 타겟 그룹에 원하는 경로, 즉 /api 호출을 보낼 수 있습니다.

애플리케이션 로드밸린서는 Auto Scaling, Amazon ECS, AWS CloudFormation, AWS CodeDeployAWS Certificate Manager (ACM) 서비스와 연동해서 사용할 수 있습니다.

신규 로드밸런서로 이전하기
현재 기존 로드밸런서를 사용하고 있으시고, 애플리케이션 로드밸린서로 옮기고 싶으시다면, Load Balancer Copy Utility를 활욜하시기 바랍니다. 기존 설정을 그대로 애플리케이션 로드밸린서에 맞게 옮겨주는 Python 기반의 도그로서 기존 EC2 인스턴스를 신규 로드밸런서로 등록하는 기능도 있습니다.

가용성 및 가격
애플리케이션 로드밸린서는 모든 AWS 리전에서 오늘 부터 사용가능합니다. ALB의 시간당 사용 비용은 기존 로드밸런서 보다 10% 낮습니다.

ALB를 사용하시면 로드밸런서 용량 단위(LCU)를 기반으로 시간당 과금하게 되며, LCU는 초당 연결 갯수, 활성 연결수, 및 데이터 전송량 등을 측정하게 됩니다. 이 세 가지 측면의 데이터를 기반으로 비용이 결정됩니다. 하나의 LCU는 다음 중 하나를 선택합니다.

  • 25 초당 연결 수 (2 KB 인증서, 3,000 활성 연결 수, 2.22 Mbps 데이터 전송량) 혹은
  • 5 초당 연결 수 (4 KB 인증서, 3,000 활성 연결 수, 2.22 Mbps 데이터 전송량

시간당 1 LCU에 대해 0.008 달러가 과금되며, 저희의 계산에 따르면 모든 고객들이 기존 로드밸런서에서 ALB로 이전할 경우 기본적으로 총 비용이 감소할 것으로 생각합니다. 지금 부터 한번 활용해 보시기 바랍니다.

Jeff;

본 글은 New – AWS Application Load Balancer의 한국어 번역본으로 AWS Summit 뉴욕 행사의 신규 발표 소식입니다.

Amazon CloudFront를 활용한 동적 콘텐츠 전송 성능 개선하기

게임 서비스에 있어서 데이터 전송 성능은 매우 중요한 요소입니다. 성능 향상을 통해 더 많은 페이지 뷰, 풍부한 사용자 경험, 높은 전환율을 얻을 수 있으며, 이는 비지니스 성공과도 직결된 중요한 요소들이라고 볼 수 있습니다. 한 통계 자료에 따르면 페이지 로딩시의 1초 지연은 7%의 전환율 하락을 가져올 수 있다고 합니다.  뿐만 아니라, 글로벌 서비스에서 최종 사용자 경험을 향상 시키는데 있어서 콘텐츠 전송 성능은 매우 중요한 요소 입니다.

CDN을 통한 동적 콘텐츠 전송에 대한 이해
Amazon CloudFront는 AWS의 콘텐츠 전송 서비스(CDN) 로서, 다른 서비스들과 통합되어 최종 사용자에게 효과적으로 콘텐츠를 쉽고 빠르게 전송할 수 있습니다. CDN은 최종 사용자와 원본 저장소(Origin) 사이에서 프록시(Proxy) 역할을 하며,  전 세계 56개(2016년 6월 20일 기준) 엣지 로케이션(Edge Location)에 미리 캐시 함으로써 빠르게 사용자에게 콘텐츠 전송을 할 수 있습니다.

일반적으로 이미지나 동영상 파일 같은 정적 콘텐츠 전송을 위해서 Amazon CloudFront를 많이 활용하고 있지만, 동적 콘텐츠 전송을 위해 사용하는 것에 대해서는 몇 가지 이유로 고민을 합니다. 동적 콘텐츠는 대게 자주 변경되는 정보를 가지고 있거나, 사용자가 보낸 요청에 포함된 요인에 따라 그 내용이 변경되는 특성을 가지고 있습니다.

그래서 항상 최신의 콘텐츠를 가져오기 위해 TTL 을 0 으로 설정하여 원본 저장소에 매번 접속 하여야 하기 때문에, 엣지에 캐시를 함으로써 향상되는 콘텐츠 전송 가속의 효과가 미비하다고 생각되는 이유 때문입니다. 하지만, TTL 을 0으로 설정하여 매번 원본 저장소에 접속하여 동적 콘텐츠를 제공하더라도, CloudFront를 프록시로 사용함으로써 전송 성능을 향상 시킬 수 있습니다.

먼저 콘텐츠 전송 성능에 대해서 얘기하기 앞서, 요청에 대한 응답 시간을 어떤 요인들로 구분하여 생각할 수 있는지 알아보는게 도움이 될 것입니다.

데이터 전송 관점에서 성능 향상 방법
아래 그림에서 보시다시피 응답 시간은 간단히 DNS Lookup 시간과, 연결 수립 시간, 최초 바이트를 받기까지의 시간, 콘텐츠 다운로드 시간의 합으로 생각해 볼 수 있습니다.

최종 사용자가 요청을 보내면, 먼저 DNS Lookup 을 하게 됩니다. 이 후 대상 서버와 TCP handshakes/retries 등의 과정으로 연결을 수립하게 됩니다. 그리고 TTFB 로 알려져 있는 최초의 응답을 기다리게 되고, 그 이후 콘텐츠를 다운로드 합니다.

이 과정이 완료되면 요청에 대한 응답이 완료되었고, 콘텐츠가 전송 되었다고 볼 수 있습니다. 앞서 나열한 요인들을 포함한 응답 시간을 CloudFront는 어떻게 처리하여 콘텐츠 전송 성능을 향상 시킬까요?

  1. 최적화된 네트워크: Amazon CloudFront 엣지와 AWS 리전 사이의 네트워크는 지속적으로 모니터링되고 성능 및 가용성면에서 최적화 됩니다. 게다가 네트워크상에 문제가 발생할 경우 신속하게 감지 및 수정되고, 최종 사용자를 다른 네트워크 경로로 자동 라우팅하여 최종 사용자에 미치는 영향을 최소화 합니다. 이를 통해 더 적은 패킷 감소와 더 나은 성능을 기대할 수 있습니다.
  2. 원본과의 지속적인 연결 유지: IP 기반의 네트워크를 통해 TCP/IP 연결을 맺기 위해서는 TCP 3-way handshake 라는 과정을 거치게 됩니다. 이 과정에 필요한 패킷 사이즈는 그렇게 크지 않기 때문에 큰 오버헤드가 아닐 수 있습니다. 하지만 글로벌 서비스와 같은 경우 지리적으로 떨어져 있는 곳에서 최종 사용자가 요청을 하게 되고, 지리적인 요건으로 인한 높은 RTT(Round-Trip Time)로 인해 매우 큰 오버헤드가 될 수 있습니다. CloudFront는 엣지에서 오리진으로의 지속적인 연결을 유지 및 재사용 하여 대게 수백 밀리세컨드가 소요되는 연결 설정 시간을 줄여 줍니다. 글로벌 서비스에서는 물론, 초당 요청 건수가 많아지면 많아질수록 지속적인 연결 유지로 얻을 수 있는 콘텐츠 전송 속도 향상의 효과는 커집니다.
  3. TCP/IP 최적화: 네트워크의 대역폭은 다양한 이유로 시시때때로 바뀌게 됩니다. CloudFront의 모든 호스트에는 엣지와 최종 사용자 간의 시시때때로 변하는 네트워크 대역폭 사용을 최대화 하기 위해 TCP initcwnd(initial congestion window) 값이 최적화 되어 있습니다.
  4. Gzip 압축 사용: Amazon CloudFront가 제공하는 GZIP 압축을 사용한다면 전송되는 데이터의 크기를 줄여, 트래픽을 줄일 수 있습니다. 이를 통해, 데이터 전송은 더 짧은 시간 안에 완료할 수 있을 뿐만 아니라, 데이터 전송 비용도 절감할 수 있습니다. 특히나 동적 콘텐츠는 대부분 매우 높은 압축률을 보여주는 텍스트 형태이기에 압축을 통한 효율이 더 높습니다. 또, CloudFront 엣지에서 압축 작업을 수행함으로써 오리진에서 압축을 위해 자원을 사용할 필요가 없어지는 장점도 있습니다.

앞서 설명한 대부분의 기능과 방법들은 CloudFront 엣지와 오리진 사이의 최적화에 관련된 내용 입니다. 최종 사용자와 엣지 사이의 최적화는 어떨까요? CloudFront는 지속적으로 지연 시간을 측정하여 최종 사용자가 항상 더 나은 경험을 할 수 있는 엣지로 연결을 하도록 합니다. 그리고, 여러 리전에 오리진을 배치하여 실제 물리적 거리를 줄일 수 있을 경우 Amazon Route 53의 LBR(Latency Based Routing)을 사용하여 최종 사용자로부터 최적의 리전에 있는 오리진에서 콘텐츠가 전송될 수 있도록 합니다.

지금까지 설명한 내용으로 앞서 언급한 응답 시간 관여 요인들을 최적화 하여 응답 시간을 줄일 수 있습니다.

  • DNS Lookup 시간: CloudFront의 라우팅 기술, Route 53과의 통합
  • 연결 수립 시간: CloudFront의 지속적인 연결 유지
  • 최초의 응답 시간(TTFB): CloudFront의 지속적인 연결 유지, Gzip 압축
  • 콘텐츠 다운로드 시간: CloudFront의 TCP/IP 최적화, Gzip 압축

CloudFront를 활용한 동적 콘텐츠 전송 테스트
Amazon CloudFront가 제공하는 응답 시간을 줄이기 위한 다양한 방법들을 살펴보았습니다. 이를 통해 어느 정도 응답 시간을 줄일 수 있는지는 간단한 테스트로 확인할 수 있습니다.

아래는 Amazon CloudFront를 활용한 동적 콘텐츠 전송 테스트 시나리오입니다.

  • 미국 동부(버지니아)에 있는 사용자가 한국에 있는 개인 서버로 접속하여, 1.7KB 정도의 동적 콘텐츠를 요청
  • CloudFront 엣지와 오리진과의 네트워크 성능에 집중하기 위해, 모든 캐시는 비활성
  • 마찬가지로 네트워크 성능에 집중하기 위해, 요청을 보낸 후 응답을 받은 뒤, 곧바로 다시 요청을 보내는 방법으로 진행 (Python 스크립트 사용)
  • 1일 03:09:00 초 ~ 5일 19:29:30 초 까지 5일 가까운 기간 동안 테스트 진행
  • 테스트1(빨간색 라인): 버지니아 EC2 -> CloudFront (No-cache, TTL 0) -> 오리진 (서울, 개인 서버, Node.js)
  • 테스트 2(파란색 라인): 버지니아 EC2 -> 오리진 (서울, 개인 서버, Node.js)

아래는 저의 인터넷 환경에서 얻은 결과입니다. (여러분의 환경과 설정 값들로 인해, 결과는 다를 수 있음을 유의해 주시기 바랍니다.)

횟수 평균 최소 최대 90백분위 10백분위 > 1초
CloudFront 1,902,091번 0.212초 0.187초 9.605초 0.209초 0.197초 40번
직접 연결 1,027,763번 0.393초 0.365초 7.415초 0.403초 0.384초 118번

동일한 기간 동안 테스트를 진행하였고, 그 결과를 확인해보면, CloudFront를 사용하였을 때 87만번 이상의 요청을 더 처리하였으며, 응답 시간은 직접 연결했을 때 보다 평균 181ms로 이는 약 1.8배 정도 더 빠른 결과 입니다. 또한, CloudFront를 사용하였을 때 1초 이상의 응답 지연은 직접 연결한 것에 비해 34% 정도 밖에 되지 않았습니다. 이를 통해, 직접 연결 보다 CloudFront를 활용하였을 때 더욱 빠르고 안정적인 서비스가 가능할 수 있음을 알 수 있습니다.

추가로 미국 서부(오레곤) 리전의 EC2에서 요청을 보냈을 때, 지리적인 이점으로 인해 더 낮은 평균 응답 시간을 얻을 수 있었습니다.

  • 테스트1: 오레곤 EC2 -> CloudFront (No-cache, TTL 0) -> 오리진 (서울, 개인서버, Node.js)
  • 테스트2: 오레곤 EC2 -> 오리진 (서울, 개인서버, Node.js)

아래는 저의 인터넷 환경에서 얻은 결과입니다. (여러분의 환경과 설정 값들로 인해, 결과는 다를 수 있음을 유의해 주시기 바랍니다.)

횟수 평균 최소 최대 90백분위 10백분위 > 1초
CloudFront 2,689,804번 0.150초 0.129초 5.223초 0.191초 0.134초 52번
직접 연결 1,642,063번 0.249초 0.236초 3.700초 0.248초 0.241초 90번

간단한 테스트를 통하여 Amazon CloudFront를 사용하면 동적 콘텐츠 전송을 가속할 수 있음을 알 수 있었습니다. 이러한 동적 콘텐츠를 위해서 캐시 기능을 사용할 수 있다면 어떨까요? 분명 더 나은 콘텐츠 전송 속도는 물론 원본 저장소 자원 사용도 줄일 수 있을 것 입니다.

동적 콘텐츠에 대한 캐싱을 통한 성능 향상하기
웹 애플리케이션 및 게임 서비스 등에서 제공하는 다양한 기능들에서 동적 콘텐츠 임에도 불구하고 일정 기간 동안은 갱신되지 않아도 크게 영향이 없는 것들을 찾을 수 있습니다. 이런 동적 콘텐츠들은 짧게는 수십초부터 길게는 수일까지 내용을 갱신할 필요가 없으며, 캐싱을 통하여 더 빠르게 전송될 수 있습니다.

아래는 동적 콘텐츠를 캐싱할 수 있을만한 애플리케이션 및 게임 서비스 내의 기능들의 예 입니다.

  1. 리더보드: http://www.example.com/leaderboards/?page=50&lowest=true – 리더 보드는 소셜 기능을 포함하는 많은 서비스들, 특히 게임에서 많이 요구되는 기능입니다. 게임을 예를 들면, 게임 플레이어들이 전투와 같은 게임 내 활동을 통해 점수가 업데이트 되고, 백그라운드에서 순위가 집계 및 계산이 된 후, 그 결과가 갱신되어, 리더보드에서 순위 정보가 표시됩니다. 게임과 같이 경쟁을 요하는 서비스에서 최종 사용자로부터 자주 요청되는 콘텐츠 입니다. 만약 이 순위 정보를 즉각 계산하고 갱신하고자 한다면 많은 자원을 필요로 할 것입니다. 하지만, 순위 정보는 항상 최신일 필요성이 적다는 점을 감안하면, CloudFront에 캐싱 하여 더 빠르게 응답을 처리하는 동시에 오리진의 자원을 효율적으로 사용할 수 있을 것입니다.

    <게임Castle Clash의 리더보드. 매일 자정 리더보드 갱신>
  2. 통계 정보: http://www.example.com/stats/player1/ – 최종 사용자는 추가적인 정보를 얻기 위해서 통계 정보를 요청합니다. 이 통계 정보는 특정한 활동에 대한 집계 일 수도 있으며, 최종 사용자의 활동으로부터 예측한 정보일 수도 있습니다. 이러한 정보는 최종 사용자의 지난 정보들을 수집한 뒤 생성되는 것으로서 자주 요청될 필요성이 적습니다. CloudFront 의 캐시 기능과 보다 긴 TTL 설정을 통하여 더 빠르게 정보를 제공할 수 있습니다.

    <World of Warships 포럼의 게임 플레이어 통계 정보>
  3. 각종 리플레이 기반의 기능: http://www.example.com/replay/player1/20/ – 게임 내에서 전투와 같은 활동은 추후 다시 재현하기 위해 리플레이로 저장할 수 있습니다. 리플레이는 일반적으로 게임 플레이어와 상대방(AI 혹은 다른 게임 플레이어)이 언제 어떤 활동 및 명령을 수행 했는지에 대한 순차적인 데이터들의 모음입니다. 이런 데이터를 기반으로 멀티플레이어 게임과 같은 기능을 구현할 수 있습니다. 리플레이 데이터는 한번 생성된 후 수정이 필요하지 않은 정적 콘텐츠의 특징을 가지고 있으며 CloudFront 의 캐시 기능을 백분 활용할 수 있습니다.

    <게임 Drag Racing Classic의 멀티플레이어 화면>

뿐만 아니라 VarnishSquid 등의 Caching Proxy를 CloudFront와 함께 사용한다면 더 세밀하고, 더 효율적으로 동적 콘텐츠를 캐싱할 수 있습니다.

지금까지 Amazon CloudFront를 활용하여 동적 콘텐츠의 전송을 가속 할 수 있는 방법을 알아 보았습니다. Amazon CloudFront가 제공하는 비용 효율성과 동적 콘텐츠 가속을 위한 기능들을 사용하여 보다 쉽고 빠르게 콘텐츠를 전송하여 최종 사용자 경험 향상은 물론 인프라의 부하도 줄일 수 있습니다. 이외에도 Amazon Route 53, Amazon S3 등의 AWS 서비스와 파트너 솔루션과의 통합으로도 성능 및 가용성을 향상 시킬 수 있습니다.

더 자세한 정보는 Amazon CloudFront – 동적 콘텐츠 전송 페이지와 Amazon CloudFront 개발자 안내서를 참고하시기 바랍니다.

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 김필중 솔루션즈 아키텍트께서 작성해주셨습니다.

Amazon CloudFront, 한국에 세번째 엣지 로케이션 공개

아마존웹서비스는 한국에 Amazon CloudFront의 세번째 엣지 로케이션(Edge Location)을 공개합니다. 2013년 5월 한국에 처음으로 국내 고객을 위한 콘텐츠 배포 지점인 엣지 로케이션을 설치한 이후, 2015년 1월 두번째 엣지를 설치 하였습니다.

늘어나는 한국 고객의 트래픽 처리와 많은 피드백을 통해 세번째 엣지 로케이션을 설치하게 되었고, 이로서 전 세계적으로 55개의 콘텐츠 배포망을 갖추게 되었습니다. (자세한 것은 AWS 글로벌 인프라 구조를 살펴 보세요.)

새로운 엣지 로케이션을 통해 AWS 고객들의 애플리케이션을 일반 사용자에게 빠르게 배포하고, 가용성을 더욱 높일 수 있게 되었습니다. 특히 Amazon CloudFront는 통해 웹 페이지 캐싱, 실시간 스트리밍, S3 전송 가속화 기능, 웹 애플리케이션 방화벽, 무료 SSL 보안 서버 및 인증서 제공 서비스, API 게이트웨이 배포 지점 등 다양한 AWS 서비스와의 연동 분야를 가지고 있습니다.

이제 한국 고객들은 지난 1월 설립한 Asia Pacific (Seoul) 리전과 더불어 3개의 엣지 로케이션을 통해 더 높은 품질의 클라우드 서비스를 제공할 수 있게 되었습니다.

Amazon CloudFront의 더 자세한 사항은 서비스 상세 페이지를 참고하시기 바랍니다.

이 글은 Announcing Third Edge Location in Seoul, Korea for Amazon CloudFront의 한국어 편집입니다.

AWS Direct Connect 서울 리전에 연결하기

지난 1월 7일 Asia-Pacific (Seoul) 리전이 국내에 개설 된 이후, 가장 많은 주목을 받은 AWS 서비스 중 하나가 바로 AWS Direct Connect 서비스입니다.

AWS Direct Connect는 여러분의 회사 내부 네트워크 혹은 기존 데이터 센터 환경의 온프레미스 IT 자원과 AWS 클라우드 자원을 전용 회선으로 연결하여, 하이브리드 환경을 구축할 수 있는 서비스 입니다. 전용 회선의 장점인 높은 보안성 및 일관된 네트워크 성능을 제공하고, AWS 서비스의 트래픽 비용 (Data transfer Out)을 절감시킬 수 있는 장점이 있습니다.

이 글에서는 Direct Connect를 구성하였을 때, 구체적인 모습과 서비스 설정 방법에 대해 상세히 설명 드리고자 합니다.

Direct Connect Location이란?
AWS 클라우드의 각 리전(Region)은 독립된 건물과 네트워크를 가진 복수개의 가용 영역(Availability Zone, AZ)으로 이루어져 있습니다. 여러분의 클라우드 자원을 멀티 AZ로 구성할 수 있고, 각 AZ에 나눠진 자원들은 하나의 가상 네트워크(Virtual Private Cloud)로 구성되어 있어 손쉽게 높은 가용성을 얻을 수 있습니다.

따라서, AWS에서는 각 리전 마다 한 개 이상의 AWS Direct Connect Location(이하, DX Location)을 지정하여 각 AZ에 있는 자원들을 빠른 네트워크 환경에서 연결할 수 있습니다. DX Location은 망 중립성을 제공하는 로컬 데이터 센터 사업자 중 AWS에서 지정하는 데이터 센터 상면 공급 사업자입니다. 해당 사업자의 상면에 AWS에서 네트워크 장비들을 설치하고, 백엔드로 AWS 모든 가용 영역(AZ)과 고속 전용 회선을 통해 연결해 놓은 곳을 의미합니다.

좀 더 쉽게 말씀 드리면, AWS 리전 내 만들어진 모든 클라우드 자원과 단일 회선 연동을 통해 연결될수 있도록 해 주는 브로커 역할을 수행합니다. 전 세계에 리전별로 다수의 AWS DX Location이 운영되고 있으며, 한국에서는 KINX가 파트너로 서비스를 제공합니다. 향후 고객의 피드백에 따라 DX Location은 계속 추가될 수 있습니다.

AWS Direct Connect 서비스를 구성하기 위해서는 몇 가지 단계를 거쳐야 합니다. 첫 번째 단계는 전용 회선을 여러분의 데이터 센터에서 DX Location까지 연결 하는 것이고, 그 다음에는 AWS 관리 콘솔에서 연결 설정을 수행하는 것입니다.

구성 방법: 1단계- 전용 회선 연결
전용 회선은 엄밀히 말하면 인터넷과 완전히 분리된 일대일 임대 회선(Leased Line)을 의미하고, 기업용 전용 회선으로 실제 구현 방식은 Leased Line, MPLS, MSPP, VPLS 등의 다양한 기반 기술로 구성됩니다. 간단히 말씀드리면, 네트워크 Layer1/2레벨의 물리적 구성을 하는 것입니다.

전용 회선 연결은 국내 모든 회선 사업자를 통해 하실 수 있습니다. 다만, AWS에서는 이들 중 일정 요건을 충족하는 사업자에 AWS Direct Connect 파트너 인증을 하고, AWS 고객을 더 잘 돕도록 하고 있습니다. 현재 한국 내에 AWS Direct Connect 파트너는 드림라인, KINX, 세종 텔레콤이 있습니다.

다만, AWS Direct Connect 파트너가 아니더라도 전용 회선 연결에 대한 부분은 기존 사업자들이 시장에서 해 오던 서비스 영역과 같기 때문에 여러가지 이유로 다른 사업자의 회선을 사용하셔야 할 경우에는 사용이 가능합니다.

AWS Direct Connect 파트너 인증을 가진 사업자와 일반 회선 사업자의 가장 큰 차이점은, AWS 파트너는 AWS 서비스에 대한 전반적인 이해를 기반으로 일대일로 모든 물리적/논리적 설정을 도와드리고, 이슈 발생 시 빠르게 대응이 가능하다는 점입니다. 또한, 1Gpbs 내에서 다양한 대역폭의 선택을 원하실 경우 Direct Connect 파트너는 여러분이 원하시는 속도에 맞춰 Direct Connect 회선을 구성해 드릴 수 있는 반면에, 일반 회선 사업자는 1G또는 10G의 대역폭 만을 구성할 수 있습니다.

구성 방법 2단계- 전용 회선 연결 대역폭(Bandwidth) 결정
DX Location 상면에 위치한 AWS 네트워크 장비는 1G 또는 10G 포트 만을 가지고 있습니다. 즉, 여러분의 전용 회선은 1Gbps또는 10Gbps로만 연결이 가능하다는 것을 의미합니다.

AWS 관리 콘솔에서 아래와 같이 Direct Connect 서비스를 신청하실 때 가장 먼저 하셔야 하는 것은 DX Location을 선택 후 1G 또는 10G 중 하나를 선택하는데, 이때 선택된 대역폭에 따라 AWS에서 해당 네트워크 장비의 특정 포트를 할당해 드립니다.

그런데, 1Gpbs의 대역폭이 너무 크고 그 정도가 필요하지 않으신 경우에는, 앞서 말씀 드린대로 AWS Direct Connect 파트너를 통해서 다양한 대역폭 사이에서 신청을 할 수 있습니다. AWS 파트너는 AWS 네트워크 장비 앞단에 추가적인 장비를 설치하여 1G또는 10G회선을 나누어 서비스할 수 있으며, 파트너 전용 콘솔을 통해 여러분이 원하시는 대역폭에 따라 50/100/200/300/400/500Mbps 중 하나를 선택하실 수 있습니다.

구성 방법 3단계 – 논리적인 구성 설정
물리적인 전용 회선 연결을 모두 마치고 나면, 논리적인 설정 단계로 들어갑니다.  전용 회선 연결이 마치면, 네트워크 관점에서는 장비 포트에 전기적인 신호가 감지되어 여러분의 네트워크 장비의 해당 포트에서 녹색 불빛이 반짝거림을 의미합니다.

실제 트래픽을 흘려보내기 위해서는 논리적인 설정 즉 인터페이스 및 패킷에 대한 라우팅 설정이 필요합니다. AWS Direct Console 관리 콘솔로 가보면 다음과 같은 화면이 나오며, State가 Available로 표시됩니다. 아래의 그림에 나와있는 예시는 1Gbps의 물리적인 회선이 연결되었다는 것을 의미하는데, 실제 구성을 위해서 해당 물리 구성을 기반으로 논리적인 인터페이스를 만들고 원하는 설정을 해야 합니다.

메뉴에서 해당 연결(Connection)을 선택하고, Create Virtual Interface를 클릭하면 아래와 같은 Virtual Interface를 설정하는 화면이 나오는데, 제일 처음 해야 하는 일은 해당 인터페이스를 하나의 VPC와 연결하는 Private Interface로 설정할지, 아니면 S3와 같은 공개 인터넷 서비스에 사용될수 있는 Public Interface로 사용할 지를 결정하는 것입니다.

Private 인터페이스로 구성하기

위의 예시 에서는 먼저 Private 인터페이스를 선택했고, 해당 인터페이스가 어느 VPC에 연결될 지를 골라주는 메뉴가 있습니다. VPC에 연결할 때 사용하는 방법은 가상 게이트웨이(VPW)와 라우팅 연결을 하는 것입니다. VGW는 VPN을 구성하실 때 사용하셨던 구성 요소인데, Direct Connect에서도 VGW를 사용하게 됩니다. VGW는 각 VPC마다 단 하나만 연동될 수 있으므로, VGW를 선택하시면 해당 VGW가 연결된 VPC를 선택했다는 것을 의미합니다.

그 다음은, BGP 설정을 위한 IP Address 입력인데, Private Interface의 경우 임의의 사설 IP를 받아서 설정이 가능하므로, 비교적 간단하게 설정하실 수 있습니다.

해당 설정을 마치고, 다음 단계를 클릭하면, AWS 콘솔에서 자동으로 Router의 Configuration을 만들어 주는데, 여러분의 데이터 센터에서 사용하시는 라우터를 선택하시면 해당 설정을 그대로 받으실 수 있고, 만약 리스트에 없을 경우 Generic Configuration을 받으셔서, 수동으로 설정하시면 BGP Neighbor 가 구성 되는 것을 보실 수 있습니다.

참고로 말씀드리면, VPN 설정에서는 제공되는 라우팅 옵션으로 Static 또는 BGP 중 선택이 가능했으나, Direct Connect의 경우에는 BGP 옵션만을 제공하니 주의 하시기 바랍니다. 고객에게서 어떤 장비를 써야 하는지 추천을 요청 받는 경우가 종종 있으나, BGP라는 표준 라우팅 프로토콜이 지원되는 모든 장비를 사용하실 수 있습니다. (최근에는 라우터 뿐만 아니라 방화벽 혹은 스위치도 라우팅을 지원하는데, 일반적으로 라우팅 장비가 아닌 경우에는 BGP는 추가적인 라이선스를 구매하셔야 지원되는 경우가 있으니 잘 확인하시기 바랍니다.)

Public Interface로 구성하기
이번에는 퍼블릭 서비스를 위한 Public Virtual Interface 설정 방법을 한번 살펴 보도록 하겠습니다.

Public Interface 설정에는 Private Interfac e설정과는 다르게 반드시 사전에 준비되어야 할 한 가지가 있습니다. 즉, 해당 인터페이스에 사용될 공인 IP주소가 필요합니다. 이때 필요한 IP Range는 일대일(Peer to Peer) BGP 연결이므로 /31 bit의 공인 IP 대역을 사용하면 되는데, 만약 가용한 공인 IP가 없으실 경우에는 AWS Support를 통해 신청하시면 하나의 /31 Bit 대역의 공인 IP페어를 할당 받으실 수 있습니다.

공인 IP뿐만 아니라 공인 ASN(Autonomous System Number)도 넣으실 수 있는데, 만약 현재 ASN을 가지고 계시지 않을 경우, 사설 ASN 중 임의의 번호를 선택하실 수 있습니다. Private interface 설정과 또 다른 한 가지는 VGW를 선택하는 항목이 없다는 것입니다. 앞에서 설명 드렸듯이, VGW는 하나의 VPC와 연결되는 게이트웨이라서 퍼블릭 인터페이스 구성에는 특정 VPC에 연동이 되지는 않습니다.

모든 설정을 정상적으로 마치고 다음 단계로 넘어가면, State 가 Verifying 이라고 표시되는 화면을 보실 수 있습니다.

라우팅 설정은 이전 Private Interface 설정 때와 마찬가지로 그대로 해주시면 되는데, 설정 후에도 바로 통신이 되지는 않습니다. 그 이유는 AWS의 Public 서비스들과 라우팅 연동이 되는 구성이기 때문에 여러분이 설정하신 공인 IP주소, ASN 등이 실제 유효한 정보인지를 먼저 검증하는 과정을 거치게 되며, 이는 최대 36시간 까지 소요될 수 있습니다.

DX Location 설정 완료 및 테스트
모든 설정이 완료되고, 여러분의 라우터로 연결된(Advertised) AWS의 공인 서비스 대역을 확인해 보실 수 있습니다. 아 위와 같은 다양한 IP 대역이 수신되는 것을 보실 수 있습니다.

해당 대역들은 AWS의 VPC를 제외한 모든 Public 서비스들에 대한 엔드포인트 IP대역으로써, 이를 통해 인터넷을 통하지 않고도 Direct Connect 전용 회선을 통해 다양한 서비스들을 보다 안정적으로 사용하실 수 있습니다.

더 자세한 사항은 AWS Direct Connect 홈페이지한국어 기술 문서를 참고하시면 됩니다.

이 글에 대한 정보를 간략하게 요약한 AWS Direct Connect 가이드(PDF)을 참고하시고, DX에 대한 복잡한 질문/추가 질문은  aws-dx-korea@amazon.com나 AWS Direct Connect 파트너인 드림라인, KINX, 세종 텔레콤을 통해 문의하시기 바랍니다.

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 김용우 솔루션즈 아키텍트께서 작성해주셨습니다.
speaker_Kevin1

AWS 클라우드 에서 지리적 IP(GeoIP) 차단 관리 방법

글로벌 게임 서비스를 하다 보면, 여러 가지 이유로 특정 국가에 대한 IP를 차단하거나 허용해야 하는 요구 사항이 흔히 발생합니다. 대개 이를 위해서 별도의 상용 방화벽을 사용하여 지리적 IP 블록 기능을 활용하거나, 직접 방화벽을 구축하고 지리적 IP 데이터를 인터넷을 통해 찾아서 직접 관리하는 방법을 사용하기도 합니다.

이 글에서는 실제로 일어나는 서비스 시나리오에 기반해서 현재 AWS가 제공하는 기능을 최대한 활용하여 이러한 요구 사항을 충족하는 과정을 단계별로 살펴 보고자 합니다.

1. 요구 사항
A사는 전문 게임 퍼블리셔 회사이고, B 게임 개발사가 만든 X게임을 글로벌 서비스로 오픈하려고 합니다. 퍼블리싱 계약 상 중국과 일본에서 접근은 차단해야 하지만, 일부 IP는 관리 목적을 위해 접근을 허용해야 하게 되었습니다.

그 외에도 현실적인 몇 가지 요구 사항을 추가해 본다면,

  1. 게임 서비스는 로그인 서버와 게임 서버로 구분되어 있다.
  2. 로그인 서비스는 REST 방식의 HTTPS 서버이며, 게임 서버는 TCP 이다.
  3. 게임 서버는 특정 IP로 바로 접근해야 한다.
  4. 게임 클라이언트 변경은 어렵다. 운영 체제(OS) 에 대한 접근은 퍼블리싱 회사에 대해 엄격하게 제한된다. 따라서 가능한 인프라 아키텍처로 문제를 해결해야 한다.
  5. 가능하다면 장기적으로 DDoS방어력을 갖추기 바란다.

아마 인프라 보안 관련 기술 경험이 있는 분이라면 몇 가지 대안을 생각했을 것입니다. 예를 들어, 방화벽 레이어를 서버군 앞에 둔다던가 직접 HAProxy 같은 리버스 프록시를 설정하는 해 볼 수 있을 것입니다. 그렇다면, AWS 클라우드에서 이러한 지리적 IP를 쉽게 허용 및 차단하는 방법은 무엇이 있을까요?

이를 위해, AWS에서는 자체 클라우드 서비스와 파트너들이 제공하는 다양한 파트너 솔루션을 제공합니다.  이 중에서 어떤 것이 가장 간단한 것인지 찾기 위해 팀이 모였다면, 간단한 브레인스토밍을 진행할 수 있습니다.

2. 다양한 접근 방법
일반적인 해결 방법과 AWS 안에서 가능한 모든 방법을 테이블에 올려 놓는 다고 하면, 아래와 같은 방법을 고려해 볼 수 있습니다.

  1. 모바일 클라이언트 게임에서 지역을 알아내서 접근 자체를 막는 방법
  2. 상용 방화벽 레이어를 게임 서버와 로그인 서버에 구축하는 방법
  3. HA 프록시 등으로 프록시 서버 레이어를 구성해서 두는 방법
  4. 운영 체제 내 방화벽 기능을 이용하는 방법
  5. Amazon Route 53의 지리적 IP 라우팅 기능을 이용하는 방법
  6. Amazon CloudFront 및 WAF(Web Application Firewall)을 사용하는 방법

요구 사항 중 가장 큰 제약 조건은 바로 2번 요구 사항입니다. 게임 서버와 로그인 서버는 각기 다른 방식으로 서버와 통신하기 때문에, 가장 쉽게 인프라 아키텍처로 해결할 수 있는 방법은 위에서 2, 3번입니다.

그렇다면 2번과 3번은 각기 어떤 단점이 있을까요? 공통적으로 TCP 접근을 위해 외부에 공개(public) IP를 오픈하고, 게임 서버와 연결해 줄 수 있는 NAT 기능까지 지원하는지 살펴 봐야 합니다. 뿐만 아니라, 지리적 IP 차단 및 관리가 용이한지도 살펴봐야 할 것이다.

따른 문제점은 상당한 비용이 발생한다는 점입니다. 지리적 IP 정보를 인터넷에서 받아서 직접 리눅스 서버 등으로 방화벽 레이어를 구축하는 경우, 지리적 IP 정보는 지역 수준의 구분은 인터넷에서 무료로 구할 수 있습니다. 하지만, 이를 이용해서 iptable과 같은 기능을 이용해서 직접 구현해야 합니다. 이런 것을 직접 구성하고 관리하는 것은 어렵습니다.

위의 그림은 이러한 경우의 아키텍처입니다. 게임 서버를 위한 지리적 IP 차단 레이어는 상용이든 직접 구현하든 고정 IP를 지원해야 하고, 방화벽 규칙을 위한 레이어가 존재해야 합니다. 여기서는 서브넷으로 상호 영역을 구분하였습니다.

요구 사항 3번 조건이 너무 강하다면, 게임 서버 앞단에는 직접 구현된 NAT 레이어와 방화벽 레이어가 존재해야 합니다. 비용 최적화를 위해서는 가능한 두 NAT 레이어를 분리해야 하는데, 그 이유는 AWS에서 고정 IP를 인스턴스에 부여하는 갯수가 제한이 있기 때문입니다.

특히, 요구 사항 4번 조건처럼 게임 개발사인 B사가 인프라 관리 요건에 맞게 클라이언트의 코드를 수정하는 것이 어려운 경우가 많습니다. 모바일 게임 클라이언트 코드에서 해결하는 방안은 쉽지 않습니다. 만약 개발사가 동의 한다면, 로그인 전에 특정 지리적 IP 정보를 알려주는 서버를 만들어서 로그인 전에 체크를 하는 방법은 있습니다.

4번 해결 방안은 퍼블리셔와 개발사 간의 계약에 의해 결정되므로 경우에 따라 가능한 해결책일 수 있습니다. 하지만, 게임 서버 안에 직접 운영 체제 방화벽으로 방어를 하는 것으로 일괄 적으로 관리할 수 있는 방안을 찾아야 한다는 단점이 있습니다.

3. AWS 클라우드에서 해법 찾기
자 이제 AWS 서비스를 통한 해법을 보다 깊게 살펴보겠습니다. 먼저 지리적 IP 처리 기능으로 활용할 수 있는 서비스는 Amazon Route53의 지리적 라우팅 기능과 Amazon CloudFront에 존재하는 AWS WAF (웹 애플리케이션 방화벽) 기능입니다. 앞의 요구 사항에 적합한 구현을 위해서는 각 서비스 기능에 대해 좀 더 깊이 있게 이해를 해야 합니다.

Rout53의 지리적 라우팅 기능은 클라이언트가 접속한 IP로 부터 지리적 위치를 알아내고 이를 특정한 AWS서비스 리소스로 라우팅해 주는 기능입니다.

위의 그림은 Route 53에서 지리적 라우팅의 설정 모습입니다. A 레코드 셋 설정을 통해 지리적으로 들어오는 IP를 ELB, S3, CloudFront의 엔드포인트 등으로 연결해 주게 됩니다.

로그인 서버 앞에서 지리적 IP콘트롤을 가장 간단하게 구성할 수 있는 것은 Route53과 CloudFront를 이용한 지리적 IP 제어 아키텍처입니다.

Amazon WAF는 현재 지리적 IP 차단 기능을 제공하지 않습니다. 따라서, 요구 사항을 해결하기 위해서는 앞단에서 먼저 지리적 위치를 어떻게든 알아내는 것이 필요합니다.  위 그림에서는 CloudFront를 2개 배포하고, 막으려는 대상 지리적 위치를 1번 CloudFront로 보냅니다. WAF의 경우는 규칙(Rule)의 순서에 따라 우선순위가 정해지는데, 허용하려는 IP 영역을 1번에 두고, 막으려는 지역, 예를 들면 한국(KR), 일본(JP), 중국(CN) 등을 전체 차단을 2번 규칙에 두면 됩니다. 지리적 제어가 필요 없는 클라이언트 지역은 2번 CloudFront로 보내게 됩니다.

그런데 이 방법에는 한 가지 문제가 존재합니다. CloudFront를 Route53에서 A레코드로 등록하려면 CloudFront에 CNAME을 할당해야 합니다. 문제는 위의 구성에서 CNAME이 두 개가 된다는 점입니다.

CloudFront는 고객이 최초 요청한 대상에 대해 체크를 하게 되는데, 만약 다른 도메인으로 경유해서 들어오게 되면 “Bad Request”라는 메시지를 던지게 됩니다.

즉, 위의 경우 1번 CF의 CNAME이 a.com, 2번 CF의 CNAME이 b.com이라고 이라고 하고, 이를 묶기 위해 c.com을 두었다면, 고객은 c.com으로 요구를 요청하게 됩니다. 1번, 2번 CloudFront모두 요청한 도메인(c.com)이 자신의 CNAME과 다르기 때문에 오류를 내게 됩니다. 이를 해결하는 방법은 매우 간단합니다. 클라이언트에서 요청할 때 헤더의 origin 값을 1번, 2번 CNAME으로 바꾸어서 전달해 주면 됩니다.

하지만, 클라이언트가 각기 다른 CNAME 값 중에 어디로 요청할 수 있다는 말은 이미 지리 정보를 클라이언트가 알고 있어야 한다는 문제에 다시 봉착 합니다. 이는 별도 지리 정보 제공 서버가 있어야 하거나, 클라이언트가 자신의 위치를 알고 있어야 합니다.

이를 해결하기 위해서는 좀 더 서비스 내부 기능을 활용하는 방법을 고안해 내야 합니다. 그 해결책 중의 하나가 바로 CloudFront 샌드위치 아키텍처입니다.

먼저 이와 같은 아키텍처를 고안하게 된 배경을 설명해 보고자 합니다. WAF는 CIDR로 IP 조건을 검색할 수 있습니다. 단 /8, /16, /24, /32 로 8비트 단위 레인지 만을 지원합니다. 중국에 속한 IP는 CIDR로 대략 6천개 정도 되는데, 이를 위 단위로 전환하면 대략 6만건의 CIDR가 됩니다.

조건이 너무 많아지면 성능 저하가 발생할 수 있고, 만약 고객이 여러 지역에 대해 관리를 해야 한다면 CIDR 형태로 WAF상에서 관리하는 것은 무척 힘든일이 될 수 있습니다.

재미난 것은 CloudFront의 고급 기능 중에 확장 헤드를 추가해 주는 기능이 있습니다. cloudfront-viewer-country라는 확장 헤더는 요청이 어느 나라에서 이루어졌는지를 헤더값으로 추가해주게 됩니다.

이렇게 확장 헤더값을 추가하는 기능보다 WAF는 앞에 존재하기 때문에 가져 올 수가 없습니다. 따라서, 이 기능을 이용하려면 WAF를 한번 더 통과하게 해서, cloudfront-viewer-country 확장 헤더 값을 추가한 이후에, 두번째 WAF에서 이 값을 이용해서 차단 할 수 있습니다.

첫번째 CloudFront를 통과하게 되면, 요청 IP가 CloudFront의 값으로 변하게 되는데, 원래 고객의 IP값은 x-forwarded-for 값에 존재합니다. 따라서 이 때 WAF 규칙을 만들 수 있게 됩니다.

각각 문자열 조건을 만든 다음 아래와 같이 WAF 규칙을 만드는 것입니다.

물론 본 아키텍처의 단점은 CloudFront의 가격이 2배가 나온다는 점입니다. 그러나, 지역별 IP 차단이라는 요구 사항에 대해 관리 및 운영 편리성을 생각하면 매우 효율적이고 간단한 해결책입니다.

게임 서비스에서 지리적 IP 관리는 매우 일상적인 요구 사항입니다. AWS 클라우드 서비스 빌딩 블록을 이용하여, 간단한 아키텍처 재구성만으로 본 요구 사항을 구성하는 해법을 찾아 보았습니다. 이러한 요구 사항을 충족해 주는 AWS 서비스나 기능이 나올 때 까지 활용해 볼 수 있는 대안이 될 것입니다.

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 박선용 솔루션즈 아키텍트께서 작성해주셨습니다.

CloudFront 업데이트 – 소스와 HTTPS & TLS v1.1/v1.2 통신 지원, 헤더 추가 및 변경

Amazon CloudFront는 글로벌 콘텐츠 배포망의 에지 위치를 이용하여 정적 및 동적 콘텐츠를 제공 할 수 있습니다. 몇 분 안에 설치를 진행하고, 여러분의 고객에게 빠르고 낮은 레이턴시의 웹 사이트, 영상, 음악 스트리밍 서비스를 제공할 수 있습니다.

개별 CloudFront 배포 지점은 하나 혹은 여러 개의 원래 소스 위치 (웹 서버나 S3 Bucket)를 참조할 수 있습니다. CloudFront의 에지 위치에 콘텐츠의 캐시가 존재하지 않는 경우, 배포지점에서 설정된 매핑(behaviors)을 따라 올바른 소스 위치(Origin)에 요청합니다.

오늘 부터 CloudFront와 소스 위치의 연결을 위한 3 가지 제어 기능을 새롭게 제공합니다.

  • TLS v1.1 및 v1.2 지원
  • HTTPS-only 연결 지원
  • edge-to-origin 요청 헤더 지원

TLS v1.1 및 v1.2 지원

에지 로케이션과 사용자 오리진 간의 프로토콜 설정으로 TLS v1.1 과 TLS v1.2 을 새롭게 추가했습니다. 이를 통해 CloudFront는 CloudFront 배포 지점에서 설정 중인 각 오리진 대해 SSLv3, TLS v1.1TLS v1.2를 지정할 수 있게 되었습니다.

HTTPS-only 연결 지원

CloudFront에서 엣지 로케이션에서 소스 위치와의 통신에서 사용하는 프로토콜 (HTTP 또는 HTTPS)은 항상 HTTPS를 사용하도록 지정할 수 있게 되었습니다. 이전에는 CloudFront에서 엣지와 통신에 이용되는 프로토콜(HTTP 또는 HTTPS)과 같은 프로토콜로 소스 위치와 통신하고 있었습니다. 이 설정을 사용하여 Viewer에서 HTTP 및 HTTPS 요청은 모든 HTTPS를 이용하여 소스 위치에 전송됩니다.

다음은 사용할 프로토콜 지정 및 HTTP-Only로 설정하는 방법입니다 :

Edge-to-origin 요청 헤더 지원

CloudFront에서 소스 위치에 요청을 포워드 할 때, 사용자 정의 헤더를 추가하거나 요청 헤더 값을 재정의 할 수있게 되었습니다. 이 헤더를 이용하여 소스 측의 임의 요청 헤더가 포함되어있는 것 만을 허용하도록 설정함으로써, 소스 에 대한 요청이 CloudFront에서 이루어지고있음(Shared Secret)을 평가할 수 있습니다.

Cross-Origin Request Sharing (CORS)의 경우 Viewer 측이 자동으로 적절한 헤더를 부여하여 요청 전송을 실행해도, CloudFront에서 소스에 대해 항상 적절한 헤더를 부여 할 수 있습니다. 또한 캐시 비율을 향상시키기 위해 값이 변화하는 소스에 헤더를 비활성화 할 수 있습니다.

아래가 X-CloudFront-Distribution-IdX-Shared-Secret이라는 새로운 헤더를 설정하는 방법입니다.

이들 기능은 추가 비용없이 오늘부터 사용할 수 있습니다. 더 자세한 사항은 CloudFront Developer Guide를 참고하세요.

Jeff;
이 글은 CloudFront Update – HTTPS & TLS v1.1/v1.2 to the Origin, Add/Modify Headers의 한국어 번역입니다.

Amazon CloudFront- 신규 Gzip 압축 기능 제공!

전 세계 사용자에게 Amazon CloudFront를 이용하여 낮은 지연 속도로 빠르게 콘텐츠를 제공 할 수 있습니다.

오늘 부터 CloudFront에 Gzip 압축 기능을 추가 지원합니다. 특정 CloudFront 배포 지점에 본 기능을 사용하면, (일반적으로 브라우저가 자동 수행하는) 콘텐츠 압축 요청에 텍스트와 바이너리 콘텐츠를 특정 엣지(Edge)에서 전달하게 됩니다.

이를 통해 사용자의 웹 페이지 로딩 속도가 더 빨라지며, 콘텐츠 다운로드 시간도 짧아지고, CloudFront 데이터 전송 비용 역시 절감 할 수 있습니다. 텍스트 스크립트나 이미지가 혼합된 일반 웹 페이지의 경우, 최대 80% 정도의 속도나 비용 감소가 생길 수 있습니다.

현재 AWS 블로그에서 이러한 기능을 한번 테스트 해보도록 하겠습니다. 아래는 압축 없을 때 데이터입니다.

압축 기능을 사용했을 때 데이터입니다.

웹 브라우저 상태 표시 줄에서도 보시다시피, Gzip 압축을 통해 총 다운로드 용량을 792KB에서 1​​77KB(77% 감소)까지 낮출 수 있었습니다. 다운로드 시간은 846ms에서 446ms(약 50%)까지 단축되었습니다.

Gzip 압축 사용 방법
본 기능은 몇 분안에 바로 사용할 수 있습니다. CloudFront 관리 콘솔을 열고 대상 배포 지점을 선택하고 Behavior 옵션에서 Compress Objects AutomaticallyYes로 하면 됩니다.

더 자세한 사항은 파일 압축 제공 방법 문서를 참고하시기 바랍니다.

정식 출시
압축 기능은 오늘부터 바로 사용할 수 있습니다. 압축 기능에 사용함으로서 바로 CloudFront 데이터 전송 비용을 절감 할 수 있습니다. (다만, 서비스 특성에 따라 압축하지 않은 것이 효율적인 경우도 있으므로 판단하셔서 사용하시면 됩니다.)

Jeff;

이 글은 New – Gzip Compression Support for Amazon CloudFront의 한국어 번역입니다.