프로젝트가 모두 완료되었다. 그 내용을 추후에 참고하기 좋게 정리 차, 글을 올리게 되었다.
프로젝트를 진행하며 실제로 작업한 내용은 ★ 프로젝트 + 트러블 슈팅 ★
에 올려두었다.
작업내용
GCP 서버 디스크에 존재하는 이미지 파일을 AWS S3로 이관
구성도
1. Cloudfront 구성을 의도하고 설계한 이유
기존 GCP 설계구조 상, 서버 Scale-Out의 어려움
기존 GCP설계구조상, 이미지를 저장하고 있는 Disk는 단일 서버에 종속적이였음.
이로 인해 추후 이용자가 증가하여 Scale-Out을 고려해야하는 상황이 왔을 때, 이를 시행하기에 까다로운 환경임
그리고, 이미지 조회 및 업로드에 서버 리소스가 온전히 사용되고 있음. 이를 다른 쪽으로 우회시키는 게 운영상 좋다고 판단이 되었음
⇒ 위 이유로, 이미지 서빙 속도개선 및 추후 서버 Scale-Out 시 편리한 환경을 구성시키기 위해 이미지 저장소를 Disk방식이 아닌, AWS S3로 이전시키는 설계를 구상
2. CloudFront 도입으로 얻게된 이점
- 캐시를 통한 이미지 서빙 속도 개선
- signed url을 통한 보안 강화
- scale-out에 유리한 환경 구성
- 유연한 대응이 가능한 이미지 리사이징 환경 구성
3. 버킷 3개로 분리한 이유
- private 버킷
- 특정 사용자에게만 보여지는 보안이 필요한 컨텐츠 이미지 (ex. 회차 컨텐츠 이미지)
- public 버킷
- 위 경우를 제외한 나머지 이미지 (ex. 썸네일, 배너, 이벤트 이미지 등)
- temporary 버킷
- 대량업로드 기능의 경우, 서버를 거치지않고 클라이언트에서 바로 s3로 이미지를 업로드 하고있음. 하지만 업로드 중 작업 중단 등의 이슈가 발생할 경우, 해당 데이터를 그대로 사용하는 것은 서비스 운영상 적합하지 않다고 판단. 이를 방지하기 위해 임시 버킷인 temporary에 저장한 후, 정상적으로 업로드가 확인되면 위의 두 버킷으로 이미지를 최종 전달해주기 위한 용도로 사용함 이미지 저장 만료기간 1 day설정
4. Lambda@Edge 기능 및 관련 내용 (함수호출 이벤트 , 메모리 관련 팁, 배포 리전, 동작 별 세팅 이유)
Lambda@Edge 구성 내용
각 Lambda@Edge 연결 동작 및 연결 이벤트 설정 이유
- 복호화 람다
- 연결 동작
- 보안상 비밀
- Private 버킷 조회 시, 이미지의 Path 경로를 사용자에게 노출하지 않는 방향을 의도하였음. ⇒ 암호화된 Path를 복호화하는 과정이 필요하여, Private 버킷에 접근하는 동작에 Path 복호화를 하는 해당 Lambda 연결
- 보안상 비밀
- 연결 이벤트
- Viewer-request
- 사용자의 응답을 수신하기 전, Path 복호화 작업이 필요하기에 해당 Lambda 연결
- Viewer-request
- 연결 동작
- 리사이징 & 확장자 변환 람다
- 연결 동작
- 보안상 비밀
- S3에는 jpg 확장자로 된 이미지 원본이 존재하고 있음. 그로 인해 이미지를 화면에 맞게 리사이징 해주는 기능이 필요했으며, 파일 크기를 더욱 압축할 수 있는 webp로 확장자를 변환함으로써 데이터를 더욱 빠르게 전송하고자 해당 Lambda 연결
- 보안상 비밀
- 위와 동일한 사유로 해당 Lambda 연결
- 보안상 비밀
- 연결 이벤트
- Origin_response
- Origin에서 오는 응답을 수신할 때, 이미지 리사이징 및 확장자 변환된 데이터를 받을 수 있게끔 해당 Lambda 연결
- Origin_response
- 연결 동작
- Viewer-request : CloudFront가 최종 사용자의 요청을 수신할 때
- Origin-request : CloudFront가 오리진에 요청을 전달하기 전
- Origin-response : CloudFront가 오리진의 응답을 수신할 때
- Viewer-response : CloudFront가 최종 사용자에게 응답을 반환하기 전
리사이징 & 확장자 변환 람다 구성관련 설정
- 이미지 리사이징 & 확장자 변환 구조를 구성 후, 특정 파라미터로 호출하였을 때 503 ERROR 발생하였음
- 확인 결과
- 요청 이미지 용량이 커,Lambda 할당 메모리 초과 OR 제한시간 초과로 인해 발생한 에러
- 확인 결과
- 해결 내용
- 요청 처리 시 메모리 및 제한시간 초과 방지를 위해 아래와 같이 메모리 증설 및 제한시간 재설정
5. Signed Url & pre-signed url
초기 구상은 하나의 s3 버킷에 대해 Cloudfront url을 통해 get과 put을 모두 수행하는 방향으로 진행하였으나
이 경우,
s3:getobject s3:putobject
위 두 정책이 한 버킷에 포함되어 get을 위해 발급된 Cloudfront url로 put도 가능해져버리는 보안 이슈가 발생
따라서 버킷정책에서 s3:putobject를 제외시키고 Cloudfront url은 get을 하기위한 용도로만 사용하도록 수정
pre-signed url
위 보안 이슈를 해결하기 위해, 기존 버킷 정책에 있는 s3:putobject를 삭제 후, Cloudfront를 거치지 않고 안전하게 put 기능을 수행하기위해 pre_signed_url을 사용
→ 만료시간이 설정되어 있고 S3 클라이언트에 미리 인증된 url을 발급받아 파일 업로드 요청
Signed url
- 보안에 중점을 둔 회차 컨텐츠 이미지 파일들은 url path를 암호화함과 동시에, Cloudfront 퍼블릭키를 사용한 signed url을 생성하여 호출
- 일반 이미지(썸네일, 배너 이미지 등)는 오버스펙이 될 것을 우려하여 signed url을 사용하지않고 그냥 cloudfront url을 통해 호출
6. 캐시 쿼리문자열 / 캐시 무효화 설정 / 캐시 기간
캐시 쿼리 문자열 설정내용
- 캐시 무효화 설정
- 관련 이슈
- 이미지 업로드 시, 기존에 캐싱되어있는 이미지가 계속 불러와짐으로써 컨텐츠 최신화가 수행되지 않는 문제가 발생함
- 해결 방법
- 이미지 업로드 시, 해당 이미지에 관련된 DB 테이블의 수정시간이 최신화 되고 있었음 → 해당 값을 캐시 쿼리스트링인 t에 삽입 이미지 업로드 시 캐시 쿼리스트링 t가 수정되니 기존에 캐싱된 이미지가 아닌 최신화된 컨텐츠가 서빙되게 캐시 무효화 설정을 함
- 관련 이슈
- 캐시 기간
- 1년 설정
- 캐시 쿼리 문자열 t를 사용함으로써 캐시 무효화 및 컨텐츠 최신화를 수행시켜둠
- w, h, q, f와 같은, 리사이징 & 확장자 변환 람다를 거친 데이터를 미리 캐싱함으로써 빠른 이미지 조회를 가능하게 함. (불필요한 람다 실행이 안되게 함)
- 1년 설정
'★ 프로젝트 + 트러블 슈팅 ★' 카테고리의 다른 글
[ELB WAF 이슈] ELB WAF 데이터 차단 트러블 슈팅 (0) | 2024.05.27 |
---|---|
[Base64 인코딩 이슈] CloudFront / S3 트러블 슈팅 (6) (0) | 2024.03.14 |
[이미지 보안 이슈] pre_signed_url / CloudFront / S3 트러블 슈팅 (5) (0) | 2024.01.30 |
[Cache 무효화] CloudFront / S3 트러블 슈팅 (4) (0) | 2024.01.11 |
Lambda@Edge / Secret Manager / CloudFront / S3 트러블 슈팅 (3) (0) | 2024.01.10 |
댓글