Vercel 배포의 비밀 (부제: 인프라 뒷이야기)

·2024년 4월 10일
44

버셀

목록 보기
1/1
post-thumbnail

들어가기에 앞서

여러분은 Vercel에 프로젝트를 배포할 때 뒤에서 정확히 어떤 일이 일어나고, 플랫폼의 사이트에 요청을 하면 어떤 일이 벌어질지 상상해보신적이 있나요? 우리는 Vercel 에 프로젝트를 올리면 짜잔, 하고 마법처럼 사이트가 배포 됩니다. 하지만 제가 항상 강조하는 말이 있습니다. "프로그래밍에 마법은 없다." ..! 오늘은 Vercel이 서버리스 어플리케이션을 빌드하고 배포하는 방법에 대한 글을 작성해보려고 합니다.

Good to know skills

¹ Amazon S3 - Cloud Object Storage
² Amazon Simple Queue Service
³ Auto scaling fleet of EC2 instances powered by AWS Fargate
⁴ Amazon Global Accelerator
⁵ AWS Global Network
⁶ Amazon EKS
⁷ AWS Lambda

Build API

오늘 소개하는 Build Output API는 file system 기반 사양으로, 모든 프레임워크가 Vercel용으로 빌드하고 엣지 함수, 엣지 미들웨어, ISR, 이미지 최적화 등과 같은 Vercel의 인프라 빌딩 블록을 활용할 수 있게 해줍니다.

file system 기반, 무슨 뜻일까요?

제 생각에는 빌드의 output을 처리하는 방식이 파일을 기반으로 하는 방식이라는것 같습니다. 즉 빌드 결과물이 파일이고, vercel의 시스템은 파일을 다루게 구현되어있어서 어떠한 프레임워크도 vercel에서 사용할수 있다! 라고 이해해주시면 좋을 것 같습니다.

Building and deploying any framework

Vercel에서는 35개가 넘는 프레임워크로 작성된 코드나 Build Output API를 통한 배포를 지원합니다. 배포는 Vercel CLI를 사용하거나, 코드를 Git 리포지토리에 푸시함으로써 이루어질 수 있습니다. Vercel의 Git 통합 기능이 커밋을 자동으로 감지하여 새 배포를 시작합니다. CLI를 통해 시작된 배포 과정은 두 가지 API 요청부터 시작됩니다.

1. Uploading project files

데이터 스토리지 서비스(1.AWS S3)에, 업로드할 프로젝트 파일을해 POST 요청이 이루어집니다.
(더 간단히 말하면 POST 요청을 통해 S3에 파일을 업로드합니다.)

2. Creating the deployment

파일이 스토리지 서비스에 성공적으로 업로드가 되면 빌드 및 배포 프로세스를 시작하기 위해 또 다른 요청이 이루어집니다. 배포 전, Vercel은 먼저 사용자를 인증하고 요청의 진위 여부와 배포를 생성할 수 있는 사용자의 권한을 검사하여 무단 액세스 및 무결성 손실을 방지하기 위해 요청을 검사합니다. 또한 vercel.json 파일에서 Vercel configuration 유효성도 함께 검사합니다.

모든 것이 완료가 되면 배포가 빌드로 예약됩니다.(2.Amazon Simple Queue Service)
프로젝트의 billing 플랜에 따라 사용 가능한 빌드 동시성이 충분하다면 Vercel의 빌드 컨테이너는 즉시 빌드 프로세스를 시작할 수 있습니다. Hobby teams은 1개, Pro teams은 최대 12개, Enterprise teams은 동시성을 극대화하기 위해 빌드 슬롯을 사용자 지정 수량으로 구매할 수 있습니다.

동시성에 대한 부연 설명을 해보겠습니다. "여기서 말하는 동시성이란 무엇일까요 ?" 바로 여러 프로젝트를 동시에 빌드한다는 뜻입니다. 깃헙 레포에 push를 하게되면 vercel이 이걸 빌드해줍니다. 그때 청구 플랜에 따라 동시에 처리하는 양이 정해져있는 것이죠. queue에 빌드 & 배포를 예약해놓고 이를 빌드시스템(빌더)가 돈 낸 플랜에 맞게 처리를 합니다. 예약하는 서버와 빌드하는 서버가 각각있고 그 사이에 queue가 존재합니다.

그리고 빌드 단계에서는 소스 코드에서 "builder"를 실행하여 프로젝트를 Vercel 배포로 변환합니다. 빌더는 Vercel에서 제공하는 내부 빌더 또는 npm 레지스트리에서 설치해야 하는 사용자 지정 빌더가 될 수 있습니다. 단순 react, next같은건 그냥 있는 빌더를 쓰면 되지만..! 특별한 프로젝트들은 빌더를 직접 만들고, 그걸 npm에 려두면 우리가 install 해서 실행해주겠다. 빌더를 커스텀으로도 만들수 있다는 얘기 같습니다.

Vercel의 빌드 시스템은 35개 이상의 프론트엔드 프레임워크를 자동으로 감지하거나 Build Output API의 사양을 준수하는 사전 빌드된 프로젝트를 인식하도록 구성되어 있습니다. 이 API를 사용하면 Vercel의 배포 플랫폼과 호환되는 build output을 생성하고 플랫폼의 모든 기능을 활용할 수 있습니다.

빌드 컨테이너는 파일을 처리하는 동안 배포 상태를 추적하는 API 엔드포인트를 ping 합니다. ping은 상태를 알리는것을 말합니다. 빌드가 얼마나 되었는지를 지속적으로 빌더가 다른 vercel 서버에 알려준다는 이야기입니다. CLI와 대시보드는 이 엔드포인트를 사용하여 사용자에게 올바른 상태를 표시합니다. 그럼 이것을 왜 하는 것일까요! 사용자에게 빌드가 어떻게 되고 있는지 보여주기 위해서 상태를 업데이트 한다고 생각해주시면 됩니다. 빌드를 요청하면 제가 빌드가 얼마큼 되고있나, 또는 실패했나? 이런 것을 vercel홈페이지에서 볼수 있게 전송하는 것입니다.

빌드 컨테이너는 Vercel에서 지원하는 런타임 중 하나에서 실행되는 build output을 생성하고 다음 중 하나로 구분을 합니다.

  • Serverless Functions for handling API routes and server-side rendered pages

  • Edge Functions for Middleware and other functions using the edge runtime

  • Optimized Images

  • Static output

(아웃풋 내에는 이처럼 여러 종류의 리소스가 포함되어 사용자의 다양한 요구를 만족시킬 수 있도록 준비되있습니다.)

필요한 리소스가 준비되고 나면, 배포를 위한 데이터베이스 문서가 생성되며 배포 메타데이터가 정적 스토리지에 업로드됩니다. 이 메타데이터는 추후 요청 단계에서 사용자를 정확한 위치로 안내하고, 들어오는 요청 경로에 따라 적절한 리소스를 호출하는 데 필요합니다.

이제 새로 완성된 배포는 Vercel CDN을 통해 사용자에게 서비스될 준비가 되었습니다. 즉, 웹사이트가 전 세계 여러 위치에 있는 서버에 저장되어, 사용자가 웹사이트에 접속할 때 가장 가까운 서버에서 웹사이트 콘텐츠를 빠르게 받아볼 수 있게 되었다는 것입니다.

Request phase (요청단계)

사용자가 Vercel을 통해 호스팅되는 웹사이트에 접속하는 과정은 "요청 단계"에 해당합니다.

브라우저에서 배포 URL의 웹사이트를 표시하려면 먼저 DNS 조회를 수행하여 IP 주소를 찾아야 합니다. 사용자가 웹사이트 주소(URL)를 입력하면, 웹 브라우저는 해당 웹사이트의 IP 주소를 찾기 위해 DNS(Domain Name System) 조회를 수행합니다. DNS는 웹사이트의 URL을 IP 주소로 변환하는 역할을 합니다. 예를 들어, "www.example.com"을 웹 브라우저가 실제로 접속할 수 있는 숫자로 된 주소로 바꿔줍니다.

DNS 조회 과정은 Vercel이 소유한 anycast IP 주소로 해결됩니다. Anycast는 하나의 IP 주소가 전 세계 여러 서버에 할당되어 있어, 사용자는 자신에게 가장 가까운 서버로 자동으로 연결되는 방식입니다. 이 과정에서 Vercel의 DNS 설정은 "cname.vercel-dns.com"이라는 CNAME(Canonical Name) 레코드를 사용하여 처리됩니다. 이는 실제 서버의 주소 대신에 사용되는 별칭 주소로, 사용자의 요청을 Vercel의 인프라로 라우팅합니다.

GeoDNS는 사용자의 위치에 따라 사용자를 고유한 엔드포인트로 라우팅하는 반면, Vercel은 anycast 라우팅을 사용하는 네트워킹 서비스를 사용하여 최적의 데이터 센터로 트래픽을 라우팅합니다. 이는 가장 가까운 목적지로 트래픽을 라우팅하여 네트워크의 성능을 향상시켜 전 세계 사용자가 low-latency connections 혜택을 누릴 수 있도록 합니다.

anycast 라우팅의 이점 외에도 네트워킹 서비스(4. Amazon Global Accelerator) 를 통해 Vercel에서 호스팅되는 애플리케이션은 자동 장애 조치 및 DDoS 와 같은 공격에도 효과적으로 방어할 수 있고, 탄력적인 대응이 가능합니다.


사용자가 Vercel을 통해 호스팅되는 웹사이트에 접속하면, Vercel의 IP 주소는 사용자를 가장 가까운 'edge location'로 연결합니다. edge location란, 전 세계적으로 분포된 서버 중 하나로, 사용자에게 더 빠른 서비스를 제공하기 위한 진입점(게이트웨이) 역할을 합니다.

웹사이트에 접속할 때 가장 빠른 경로를 찾아주는 것과 비슷합니다. 요청이 Vercel의 시스템에 들어오면, 먼저 Kubernetes 클러스터를 통해 처리됩니다. 요청은 먼저 악의적인 사용자가 있는지 검사 및 필터링된 다음 역방향 프록시 역할을 하는 가상 머신(Amazon EKS)으로 라우팅됩니다. Kubernetes는 여러 서버(또는 컨테이너)를 관리하고, 애플리케이션의 배포와 운영을 자동화하는 시스템입니다. Vercel은 이 시스템을 사용하여 웹사이트의 트래픽을 관리하고, 자원을 효율적으로 배분합니다.

먼저, 들어오는 요청의 호스트 이름과 같은 데이터를 기반으로 사용자에게 제공해야 할 배포 버전을 결정하고 배포의 메타데이터를 가져옵니다. 그리고 요청이 특정 경로와 매치되는지 확인합니다. 만약 매치되는 경로가 없다면, 사용자에게는 404 오류 페이지가 표시됩니다. 매치되면 해당 요청에 대한 적절한 응답을 생성하기 시작합니다.

Vercel Edge Middleware가 활성화되어 있으면, 요청은 먼저 엣지 함수를 실행하는 플랫폼으로 전달됩니다. 엣지 미들웨어는 사용자에게 더 빠르게 콘텐츠를 제공하기 위해 사용되며,예를 들어 사용자 위치에 따라 다른 콘텐츠를 보여주거나 특정 요청을 처리하는 등의 작업을 할 수 있습니다.

리소스 유형에 따라 다른 응답 단계

For static resources : gateway는 정적 페이지, 글꼴, 최적화되지 않은 이미지와 같은 리소스를 static storage에서 다운로드합니다.

For Vercel Serverless Functions: server-rendered pages 또는 API routes와 같은 Serverless Function가 배포된 지역에서 gateway가 서버리스 함수 실행을 트리거합니다.

For Edge Functions: server-rendered page, 엣지 런타임을 사용하는 API Route와 같이 gateway가 엣지에서 엣지 함수 실행을 호출하도록 요청 형식을 지정합니다.

For pages using Incremental Static Regeneration: 게이트웨이는 먼저 이 페이지가 이전에 렌더링된 적이 있는지 확인하여 저장소에서 정적 출력을 사용할 수 있는지 확인합니다. 그렇지 않은 경우 게이트웨이는 서버리스 함수(7.AWS Lambda)를 호출하여 콘텐츠를 동적으로 생성합니다. 이 함수의 호출은 정적 리소스가 이전에 캐시되었지만 TTL(Time-to-Live)이 경과한 오래된 콘텐츠의 경우에도 발생합니다. 이 경우 오래된 콘텐츠가 사용자에게 제공되는 동안 백그라운드에서 함수가 호출되어 콘텐츠가 다시 생성됩니다.

For optimized images: 최적화 서비스로 전달되어 즉시 이미지를 최적화하고 추후 요청을 위해 엣지에 캐시되어 파일 크기를 줄이고 요청하는 클라이언트의 브라우저에서 지원하는 최신 형식을 사용합니다. 최적화된 이미지는 만료될 때까지 제공되며, 그 이후에는 이미지가 백그라운드에서 다시 최적화되는 동안 구버전의 이미지가 제공됩니다. 이미지의 만료 시간은 구성 설정 또는 업스트림 이미지의 Cache-Control에 의해 결정됩니다.

Conclusion

자체 인프라를 설정하고 유지 관리하려면 적절한 서버 하드웨어와 운영 체제를 선택하고 구성하며, 네트워크 인프라를 설정하고 구성하고, 필요한 소프트웨어 스택을 구성하고 유지 관리하는 등의 작업이 필요합니다. 인프라의 보안과 확장성을 유지하려면 지속적인 모니터링, 유지관리, 업데이트가 필요합니다. 여기에는 위협과 취약성으로부터 보호하기 위한 보안 프로토콜과 솔루션을 구현하고 인프라가 트래픽 급증을 효율적으로 처리할 수 있도록 보장하는 것도 포함됩니다. 이러한 모든 작업은 시간이 많이 걸리고 복잡하며 대규모로 처리하려면 숙련된 엔지니어로 구성된 전담 팀이 필요합니다.

Vercel을 이용해 배포하면 자체 인프라를 설정하고 유지 관리할 필요 없이 배포 프로세스를 간소화하여 프로젝트 개발에만 집중할 수 있습니다!

마지막으로

원본글을 제가 정말 존경하는 회사 코딩메이트분에게 공유했습니다. 절 이해시키는데에 정말 많은 도움을 주셨고, 이렇게 멋지게 요약정리를 해주셨습니다.

또 한가지, 저의 블로그 글은 그저 원본 글을 읽고, 해석하고, 사견을 덧붙인 글입니다. 여러분이 원본글을 읽는데 도움을 줄 발판일뿐입니다. 오로지 원본만이 공식 효력이 있다는 사실을 잊으시면 안됩니다.

profile
My Island

4개의 댓글

comment-user-thumbnail
2024년 4월 11일

수많은 과정속에서 배포되네여 정말 신기해여. 좋은 블로그글 감사합니다.

1개의 답글
comment-user-thumbnail
2024년 4월 11일

와 정말 어렵고 복잡하네요... 프론트에서 이제 오픈소스, 네트워크, 인프라 지식까지 확장하시는 건가요!

1개의 답글