소개

웹사이트가 로드해야 할 이미지와 자산 때문에 느려지는 것을 경험해본 적이 있나요? 아니면 사이트가 성장하면서 이러한 파일을 관리하는 데 어려움을 겪어본 적이 있나요? 웹 서버에서 이미지를 직접 저장하고 제공하는 것이 처음에는 편리해 보일 수 있지만, 곧 병목 현상으로 이어질 수 있습니다.

여기서 AWS가 등장합니다. S3와 같은 스토리지 서비스와 CloudFront라는 강력한 CDN을 사용하면, 전 세계 어디에서든 사용자에게 이미지를 빠르게 관리하고 최적화하여 제공할 수 있습니다.

이 가이드에서는 웹 앱 서버에 이미지를 저장하는 것이 왜 나쁜 아이디어인지, 서비스 분리가 어떻게 게임 체인저가 되는지, 그리고 AWS 도구가 여러분의 삶을 얼마나 쉽게 만들어 줄 수 있는지에 대해 설명하겠습니다. 시작해볼까요!

웹 서버에 이미지를 저장하는 것이 나쁜 이유

서버 부하 증가

웹 서버가 앱을 실행하고 이미지를 제공하는 역할을 동시에 맡게 되면, 금방 과부하가 걸릴 수 있습니다. 모든 이미지 요청은 추가 작업을 쌓아 올려서 모든 것을 느리게 만듭니다. 사이트에 많은 트래픽이 발생하면 서버가 이를 따라잡기 힘들어져 지연이나 심지어 다운되는 상황이 발생할 수 있습니다. 마치 장을 보면서 동시에 뛰어가는 것과 같죠—효율적이지 않습니다!

제한된 확장성

사이트가 성장함에 따라 이미지와 사용자 수가 증가합니다. 단일 웹 서버는 한계가 있어 벽에 부딪히게 됩니다. 확장하려면 더 큰 서버에 더 많은 돈을 써야 하거나 모든 것을 마이그레이션하는 번거로움을 겪어야 합니다. AWS S3와 같은 클라우드 스토리지를 사용하면 공간이 부족해지는 걱정 없이 여러분과 함께 성장합니다.

성능 병목 현상의 위험

큰 이미지 파일은 사이트를 느리게 만들 수 있습니다. 특히 앱의 기능을 처리하는 동일한 서버에서 이미지를 제공하는 경우 더욱 그렇습니다. 사이트의 한 부분이 느리면 다른 모든 부분도 지연되어 사용자들은 긴 로딩 시간에 불만을 느낄 수 있습니다. 마치 단일 차선 도로에서 교통 체증이 발생하는 것과 같습니다—모든 것이 밀리게 됩니다.

보안 문제

웹 서버에서 이미지를 제공하면 불필요한 위험에 노출될 수 있습니다. 해커가 취약점을 악용해 민감한 정보에 접근할 수 있으며, 다른 사이트가 여러분의 이미지를 핫링크하여 대역폭을 훔칠 수 있습니다. 적절한 보호 장치가 없다면, 서버 파일 경로를 우연히 노출할 수도 있습니다. 이는 마치 현관문을 활짝 열어두는 것과 같습니다.

CDN을 사용해야 하는 이유

느리게 로드되는 웹사이트에 짜증이 난 적이 있다면, CDN (Content Delivery Network)이 왜 게임 체인저인지 이해할 수 있을 것입니다. CDN은 전 세계에 분산된 미니 창고 네트워크와 같아서, 각 창고는 여러분의 사이트 이미지와 자산의 복사본을 저장합니다. 모든 사용자가 메인 서버에서 콘텐츠가 이동할 때까지 기다릴 필요 없이, CDN은 가장 가까운 창고에서 콘텐츠를 제공하여 모든 것을 더 빠르고 원활하게 만듭니다.

CDN은 데이터를 전 세계 엣지 서버에 분산시켜 콘텐츠 배달 속도를 높입니다.
CDN은 데이터를 전 세계 엣지 서버에 분산시켜 콘텐츠 배달 속도를 높입니다.

이미지 및 자산 제공을 위해 CDN을 사용하는 것이 당연한 이유는 다음과 같습니다:

전 세계 사용자에게 더 빠른 로드 시간

예를 들어, 여러분의 메인 서버가 뉴욕에 있지만 도쿄에 있는 누군가가 여러분의 사이트를 방문한다고 가정해보세요. CDN이 없다면, 그들의 요청은 세계를 반 바퀴 돌아야 하므로 시간이 걸립니다. CDN을 사용하면 도쿄 근처의 서버가 콘텐츠를 제공하여 이동 시간을 줄이고 사이트가 즉시 로드됩니다. 더 빠른 로드 시간은 사용자들을 더 행복하게 만들고, 행복한 사용자는 더 오래 머무릅니다.

지연 시간 감소 및 사용자 경험 개선

지연 시간은 사용자가 무언가를 클릭하고 콘텐츠가 실제로 나타날 때까지의 성가신 지연입니다. 사용자가 서버에서 멀어질수록 지연 시간이 증가합니다. CDN은 이미지를 사용자에게 더 가깝게 가져와 지연 시간을 줄이고 모든 것이 즉각적으로 느껴지도록 합니다. 런던의 소파에서 사이트를 탐색하든 시드니의 카페에서 하든, 사용자들은 동일한 원활한 경험을 즐길 수 있습니다.

메인 서버의 트래픽 분산

여러분의 웹 서버를 바쁜 레스토랑의 셰프라고 생각해보세요. CDN이 없다면, 셰프는 모든 것을 처리해야 합니다: 요리, 서빙, 심지어 멀리 있는 고객에게 음식을 배달하는 것까지요. CDN을 사용하면 셰프(여러분의 서버)는 요리(앱 실행)에 집중할 수 있고, CDN은 배달(이미지 및 자산 제공)을 처리합니다. 이렇게 하면 메인 서버의 트래픽이 대폭 줄어들어 과부하를 방지하고 트래픽 급증 시에도 사이트가 원활하게 운영됩니다.

S3와 CloudFront는 무엇인가요?

S3 (Simple Storage Service)

S3는 아마존의 안전하고 확장 가능하며 매우 신뢰할 수 있는 클라우드 저장소 솔루션입니다. 이미지, 비디오 및 기타 자산을 포함한 모든 종류의 데이터를 저장하도록 설계되어 있어 웹사이트 및 애플리케이션에 이상적인 선택입니다. 작은 개인 블로그를 호스팅하든 대규모 전자상거래 플랫폼을 운영하든, S3는 여러분의 저장 요구를 손쉽게 처리할 수 있습니다. 또한 유연한 저장소 계층을 제공하므로 사용한 만큼만 비용을 지불하면 됩니다.

CloudFront

CloudFront는 아마존의 콘텐츠 배달 네트워크 (CDN) 서비스로, 빠르고 안전한 콘텐츠 배달을 보장합니다. 이미지와 자산을 전 세계에 위치한 엣지 서버에 캐시하여 사용자가 가장 가까운 서버에서 빠르게 접근할 수 있도록 합니다. S3와 결합하면 CloudFront는 저장된 자산을 원활하게 가져오고 최소한의 지연으로 제공하여 배달 프로세스를 최적화합니다. S3와 CloudFront는 웹사이트 콘텐츠를 관리하고 제공하기 위한 강력하고 효율적이며 확장 가능한 솔루션을 제공합니다.

S3와 CloudFront 사용 비용

AWS의 가장 좋은 점 중 하나는 사용한 만큼만 비용을 지불한다는 것입니다. 간단한 비용 내역은 다음과 같습니다:

  • S3 비용:
    • 저장 비용: 저장된 데이터의 GB당 비용을 지불하며, 저장소 계층에 따라 다른 요금이 적용됩니다 (예: Standard, Infrequent Access, Glacier).
    • 요청 비용: 버킷에 대해 PUT, GET 및 기타 요청에 대한 요금이 부과됩니다.
    • 데이터 전송: S3에서 인터넷으로 데이터를 전송할 때 추가 요금이 발생합니다.
  • CloudFront 비용:
    • 데이터 전송: 엣지 위치를 통해 사용자에게 전달되는 데이터 양에 대해 비용을 지불합니다.
    • 요청: CloudFront에 대해 HTTP/HTTPS 요청에 대한 요금이 부과됩니다.
    • 지역 요금: 사용자 위치에 따라 비용이 달라질 수 있습니다.

자세한 정보는 Amazon S3 가격 및 Amazon CloudFront 가격 에서 확인할 수 있습니다.

예시: S3와 CloudFront 사용 비용

작은 전자상거래 웹사이트를 운영하고 제품 이미지를 저장하고 제공해야 한다고 가정해보겠습니다. 다음은 간단한 비용 내역입니다:

시나리오 세부사항

  • 저장소: S3에 저장된 이미지 100 GB (Standard Tier).
  • 요청: S3에 대해 매달 50,000 GET 요청 및 10,000 PUT 요청.
  • 데이터 전송: CloudFront로 전송된 데이터 100 GB.
  • CloudFront 데이터 배달: CDN을 통해 최종 사용자에게 전달된 데이터 100 GB.

S3 비용

  1. 저장 비용:
  • S3 Standard Storage의 100 GB = $2.30 (약 $0.023 per GB).
  1. 요청 비용:
  • 50,000 GET 요청 = $0.04 (약 $0.0004 per 1,000 요청).
  • 10,000 PUT 요청 = $0.05 (약 $0.005 per 1,000 요청).
  1. 데이터 전송 비용 (CloudFront로):
  • 100 GB = $0 (S3에서 CloudFront로의 데이터 전송은 무료입니다).

총 S3 비용: $2.39/월

CloudFront 비용

  1. 데이터 전송 비용 (CloudFront에서 사용자에게):
  • 100 GB를 최종 사용자에게 전달 = $8.50 (약 $0.085 per GB for the first 10 TB).
  1. 요청 비용:
  • 50,000 HTTP/HTTPS 요청 = $0.10 (약 $0.002 per 1,000 요청).

총 CloudFront 비용: $8.60/월

총 합계

총 월 비용: $2.39 + $8.60 = $10.99

AWS S3와 CloudFront를 설정하여 이미지 및 자산 호스팅하기

이 가이드는 AWS S3와 CloudFront를 구성하여 사용자 정의 서브도메인으로 이미지를 효율적으로 제공하는 방법을 안내합니다.

이 설정은 다음을 보장합니다:

  • 허용된 도메인에서의 요청 (예: yoursite.com)만 자산에 접근할 수 있습니다.
  • Referer 헤더가 없는 요청 (예: S3 URL에 직접 접근)은 차단됩니다.
  • 무단 웹사이트에서의 요청 (핫링크)은 거부됩니다.
  1. AWS Certificate Manager (ACM)에서 SSL 인증서 생성

CloudFront는 사용자 정의 도메인에서 HTTPS를 사용하기 위해 유효한 SSL 인증서가 필요하므로, 첫 번째 단계는 SSL 인증서를 생성하는 것입니다.

  • AWS Certificate Manager (ACM)로 이동합니다.
  • Click Request a certificate.
  • Choose Request a public certificate.
  • 서브도메인 입력 (images.yoursite.com) 및 와일드카드 인증서를 원할 경우 *.yoursite.com을 추가합니다.
  • Select DNS Validation (권장).
  • 제출 후, AWS는 CNAME 레코드를 제공하며, 이를 DNS 제공업체 (예: Route 53, Cloudflare, GoDaddy)에 추가해야 합니다.
  • DNS 레코드가 검증되면 인증서가 발급됩니다.
AWS Certificate Manager: 서브도메인에 대한 SSL 인증서가 성공적으로 발급되었습니다.
AWS Certificate Manager: 서브도메인에 대한 SSL 인증서가 성공적으로 발급되었습니다.
  1. 이미지를 제공할 서브도메인 생성

이제 SSL 인증서가 준비되었으므로, 이미지를 제공할 서브도메인 (images.yoursite.com)을 설정합니다.

  • DNS 제공업체 (Route 53, Cloudflare 등)로 이동합니다.
  • CNAME 레코드를 생성합니다:
    • 레코드 이름: images
    • 유형: CNAME
    • 값: <your-cloudfront-distribution-id>.cloudfront.net
  1. CloudFront 배포 생성

이제 CloudFront를 설정하여 S3에서 이미지를 제공하도록 합니다.

  • AWS CloudFront로 이동 → 배포 생성.
  • 원본 아래에서 구성합니다:
    • 원본 도메인 이름: S3 버킷을 선택합니다.
    • 원본 접근: 레거시 접근 ID 선택 → 원본 접근 ID 생성 (OAI).
    • 버킷 정책: 버킷 정책을 수동으로 업데이트하겠습니다 선택.
  • 동작 구성:
    • 객체 자동 압축: ✅ 예
    • 뷰어 프로토콜 정책: HTTP를 HTTPS로 리다이렉트
    • 허용된 HTTP 메서드: GET, HEAD
    • 뷰어 접근 제한: ❌ 아니오 (서명된 URL을 원하지 않는 경우)
  • 캐시 및 원본 요청 설정:
    • 캐시 정책: ✅ CachingOptimized
    • 원본 요청 정책: ✅ UserAgentRefererHeaders (Referer를 S3로 전달)
  • SSL 인증서 할당:
    • 설정 아래에서 사용자 정의 SSL 인증서를 선택합니다.
    • AWS Certificate Manager에서 생성한 인증서를 선택합니다.
  • Click 배포 생성.
CloudFront: 원본 구성
CloudFront: 원본 구성
CloudFront: 동작 구성
CloudFront: 동작 구성
  1. S3 버킷 권한 구성

기본적으로 S3 버킷은 비공개입니다. CloudFront가 접근할 수 있도록 허용해야 합니다.

  • S3로 이동 → 버킷 선택.
  • 권한 → 모든 공개 접근 차단 ✅ 활성화 (CloudFront가 접근을 처리할 것이므로).
  • 버킷 정책 업데이트:

다음과 같이 <버킷 이름>과 <클라우드 프론트 OAI>를 실제 값으로 바꿉니다:


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAccessFromSubdomains",
            "Effect": "Allow",
            "Principal": {
                "AWS": "<cloud front oai>"
            },
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::<bucket name>/images/*",
                "arn:aws:s3:::<bucket name>/assets/*"
            ],
            "Condition": {
                "StringLike": {
                    "aws:Referer": [
                        "http://*.yoursite.com/*",
                        "https://*.yoursite.com/*",
                        "http://yoursite.com/*",
                        "https://yoursite.com/*"
                    ]
                }
            }
        }
    ]
}
  1. 마지막 단계
  • CloudFront 배포: CloudFront 배포가 완료될 때까지 기다립니다.
  • 이미지 로딩 테스트:
    • 이미지 접근 시도: https://images.yoursite.com/path/to/image.jpg
  • 403 Forbidden 오류가 발생하면 다음을 확인하세요:
    • CloudFront OAI가 올바르게 할당되었습니다.
    • S3 버킷 정책에 OAI ARN이 포함되어 있습니다.
    • Referer 헤더가 전달됩니다.

✅ 이제 AWS S3와 CloudFront로 완전히 구성되고 최적화된 안전한 이미지 제공 설정이 완료되었습니다! 🚀

결론

이제 모든 것이 완료되었습니다! AWS S3와 CloudFront가 함께 작동하여 프로처럼 이미지를 빠르고 안전하며 비용 효율적으로 제공하는 방법을 구축했습니다. 더 이상 웹 서버를 느리게 하거나 느린 로딩 시간으로 고민할 필요가 없습니다—CloudFront가 무거운 작업을 처리하고 S3가 모든 것을 정리하고 안전하게 유지합니다. Referer 헤더를 전달하고 직접 S3 접근을 차단함으로써 핫링크와 원치 않는 트래픽을 방지했습니다. 이제 여러분의 이미지는 번개처럼 빠르게 로드되고, 보호되며, 손쉽게 확장됩니다. 간단하고 효율적이며 오래 지속될 수 있도록 설계되었습니다! 🚀