cloudflare-containers

2 개의 포스트

cloudflare

Cloudflare Workers와 Containers, 이제 인바운드 TCP 연결 및 gRPC 지원 (새 탭에서 열림)

Cloudflare는 Workers에 인바운드 TCP 소켓을 직접 처리하는 `connect(socket)` 기능과 컨테이너 기반의 양방향 gRPC 지원을 추가했습니다. 이를 통해 클라이언트의 TCP 연결을 Worker, Durable Object, Container로 전달하고, 다양한 언어로 작성된 gRPC 서버를 Cloudflare 네트워크에서 실행할 수 있습니다. 특히 저지연·양방향 통신이 중요한 음성 AI와 실시간 애플리케이션을 클라이언트 가까이에서 처리하는 것이 목표입니다. ## Workers의 인바운드 TCP 지원 - 기존 Workers는 주로 HTTP 요청을 처리하거나 아웃바운드 TCP 연결을 생성하는 방식이었지만, 이제 `connect(socket)` 핸들러로 들어오는 TCP 연결을 받을 수 있습니다. - 소켓은 `readable`과 `writable` 스트림으로 제공되며, 다음과 같이 데이터를 읽고 쓸 수 있습니다. - `socket.writable.getWriter()`로 데이터 전송 - `socket.readable.pipeTo(...)`로 다른 소켓에 데이터 전달 - TCP 연결을 Worker에서 직접 종료하거나, 다른 Worker·Durable Object·Container로 라우팅할 수 있습니다. ## Durable Objects와 Container로 소켓 전달 - Worker는 Durable Object의 `connect()` 메서드를 호출해 인바운드 소켓을 특정 객체로 전달할 수 있습니다. - Durable Object는 양방향 스트림을 연결해 클라이언트와 서버 사이의 바이트를 그대로 중계할 수 있습니다. - Durable Object에서 Container의 TCP 포트에 연결한 뒤 다음과 같이 양방향 파이프를 구성합니다. - 클라이언트 → Container - Container → 클라이언트 - Container에서는 Python, Go 등 원하는 언어와 TCP 서버 구현을 사용할 수 있습니다. - 따라서 특정 RPC 프레임워크에 종속되지 않고, TCP를 사용하는 어떤 프로토콜이나 프로그램도 Cloudflare에서 처리할 수 있습니다. ## Spectrum을 이용한 TCP 진입점 - Cloudflare Spectrum은 HTTP가 아닌 TCP·UDP 트래픽을 Cloudflare 네트워크로 받아들이는 인그레스 프록시입니다. - 새로운 Spectrum 애플리케이션 유형에서는 유입된 TCP 연결을 지정한 Worker의 `connect(socket)` 핸들러로 전달할 수 있습니다. - 결과적으로 클라이언트부터 Cloudflare Worker, Durable Object, Container 내부 서버까지 전체 네트워크 경로를 제어할 수 있습니다. ## Cloudflare Containers의 양방향 gRPC - gRPC는 HTTP/2와 TCP를 기반으로 하는 RPC 프레임워크로, 모바일 앱·분산 시스템·음성 AI 서비스에서 널리 사용됩니다. - 실시간 음성 애플리케이션은 단일 연결에서 클라이언트와 서버가 모두 지속적으로 메시지를 보내야 하므로 양방향 스트리밍이 중요합니다. - Cloudflare의 새 기능을 사용하면 다음과 같은 gRPC 서버를 Container에 배포할 수 있습니다. - 모든 언어로 작성된 gRPC 서버 - 클라이언트와 서버 간 full-duplex 양방향 스트리밍 - 지속적인 단일 TCP 연결 - 예시 gRPC 서버는 연결 직후 `connected` 메시지를 보내고, 클라이언트 메시지마다 `echo` 응답을 보내며, 연결 종료 시 `goodbye` 메시지를 전송합니다. - Cloudflare는 330개 이상의 위치에서 요청을 처리하므로, 서버를 사용자와 가까운 위치에서 실행해 지연 시간을 줄일 수 있습니다. ## Workers 기반 gRPC API - Workers에서는 gRPC 서버를 직접 구현하거나 기존 gRPC 서버를 호출할 수 있습니다. - 개발자는 `gRPC-web` 방식으로 코드를 작성하고, Cloudflare가 요청과 응답을 실제 gRPC 형식으로 변환합니다. - 지원 범위에는 다음이 포함됩니다. - 단일 요청·응답 방식인 unary RPC - 서버가 여러 메시지를 보내는 server-streaming RPC - Container로 소켓을 직접 전달하는 양방향 스트리밍 gRPC - 이 기능을 활용하면 기존 gRPC 생태계를 유지하면서 Cloudflare의 글로벌 네트워크와 Workers의 라우팅 기능을 함께 사용할 수 있습니다. ## 음성 AI와 실시간 서비스에 대한 의미 - AI 음성 비서, 실시간 받아쓰기, 음성 기반 에이전트는 모델·클라이언트·지원 서비스 사이의 낮은 지연 시간이 필수적입니다. - WebSockets와 Durable Objects도 적합하지만, 이미 gRPC를 사용하는 기존 시스템은 새 인프라로 전면 재작성할 필요가 줄어듭니다. - Cloudflare는 TCP 연결을 직접 전달하므로 음성 데이터나 스트리밍 추론 요청처럼 연결을 오래 유지하는 서비스에 적합합니다. - 해당 기능은 현재 프라이빗 베타로 제공되며, 사용을 위해 별도 신청이 필요합니다. 실시간 음성 AI나 기존 gRPC 시스템을 Cloudflare에 배포하려는 경우, `connect(socket)`을 이용해 Worker–Durable Object–Container 간 양방향 스트림을 구성하는 방식이 유용합니다. 다만 현재는 프라이빗 베타이므로 실제 도입 전 지원 프로토콜, 연결 수명, 지연 시간, 비용 및 운영 제한을 확인하는 것이 좋습니다.

cloudflare

Browser Run: 이제 Cloudflare Containers에서 실행되어 더 빠르고 확장성이 뛰어납니다 (새 탭에서 열림)

Browser Run은 Cloudflare Containers 기반으로 재구축되면서 더 높은 처리량, 낮은 지연 시간, 향상된 안정성을 확보했다. 분당 브라우저 생성 한도는 60개, 동시 실행 수는 120개로 늘어 기존보다 4배 향상됐고, Quick Action 응답 시간은 50% 이상 단축됐다. 이 성능 개선의 핵심은 지역별 사전 준비 컨테이너 풀, D1의 트랜잭션 기반 상태 관리, Queues를 활용한 배치 쓰기다. ## Browser Run의 역할 - Cloudflare의 글로벌 네트워크에서 실행되는 헤드리스 브라우저를 프로그래밍 방식으로 제어한다. - 주요 활용 사례: - 웹 애플리케이션의 엔드투엔드 테스트 - 의심스러운 URL의 안전한 조사 - PDF 렌더링 - 스크린샷 캡처와 콘텐츠 추출 - AI 에이전트의 웹 브라우징 - 목표는 자동화 브라우저를 안전하고 대규모로 활용할 수 있는 플랫폼이 되는 것이다. ## 기존 Browser Isolation 인프라의 한계 - 이전에는 Browser Run과 Browser Isolation(BISO)이 인프라를 공유했다. - BISO의 큰 컨테이너 이미지는 브라우저 시작 시간과 개발 속도를 저하시켰다. - BISO 브라우저의 글로벌 분산이 충분하지 않아 지연 시간과 복원력에도 문제가 있었다. - BISO의 장시간·지속적 세션과 Browser Run의 짧고 급격한 트래픽 패턴이 서로 맞지 않아 확장 병목이 발생했다. ## 점진적인 Containers 마이그레이션 - 요청 경로에 Worker를 추가해 일부 사용자에게만 Container 기반 브라우저를 제공하며 마이그레이션을 시작했다. - 기존 BISO 브라우저와 병행 운영하면서 성능을 비교하고 구현 오류를 검증했다. - 적용 순서는 다음과 같았다. - Quick Actions 엔드포인트 - 무료 계정의 Workers 브라우저 바인딩 - 종량제 계정 - 나머지 계약 고객 - 고객이 별도 설정을 변경하거나 Worker를 재배포하지 않아도 전환되도록 했다. ## 지역별 사전 준비 컨테이너 풀 - Durable Object(DO)는 요청에 가까운 위치에 생성될 수 있지만, 연결되는 Container는 지구 반대편에 배치될 수 있다. - 단일 메시지에서는 문제가 작지만, 스크린샷 요청처럼 WebSocket으로 수십 개 메시지를 주고받는 작업에서는 왕복 지연이 누적된다. - 이를 해결하기 위해: - 지역별로 DO 기반 브라우저 컨테이너를 미리 실행해 둔다. - 요청이 들어오면 해당 지역에서 사용자와 가장 가까운 DO-Container 쌍을 선택한다. - 사용자-DO, DO-Container 양쪽의 네트워크 거리를 줄인다. - 브라우저별 글로벌 상태를 관찰하고 수요에 따라 용량을 재배치해야 하므로 추가적인 아키텍처 복잡성이 생겼다. ## Workers KV의 일관성 문제 - 초기에는 각 컨테이너 상태를 Workers KV에 저장했다. - KV는 최종적 일관성을 사용하며, 캐시 TTL 때문에 최대 약 30초 또는 그 이상 오래된 상태를 읽을 수 있었다. - “사용 가능”으로 읽은 컨테이너가 실제 라우팅 시점에는 이미 다른 요청에 할당되는 경쟁 조건이 발생했다. - 이로 인해: - 동일 브라우저의 중복 할당 - 과도한 브라우저 예약 - 급격한 수요 증가에 대한 확장 지연 문제가 생겼다. ## D1을 이용한 원자적 브라우저 할당 - 컨테이너 상태를 KV에서 D1 데이터베이스로 이전했다. - D1은 SQLite 기반 트랜잭션을 제공하므로 브라우저 할당을 원자적으로 처리할 수 있다. - 브라우저는 사용자 간 공유 자원이 아니므로, 한 번 할당되면 독점적으로 사용되어야 한다. - 후보 컨테이너를 선택하고 상태를 `picked`로 변경하는 작업을 하나의 트랜잭션으로 수행해 동시에 두 요청이 같은 브라우저를 차지하는 문제를 방지한다. - 지역별로 D1 샤드를 구성해 위치 기반 컨테이너 관리도 유지했다. ## Queues를 활용한 상태 업데이트 배치 처리 - 수천 개 컨테이너가 5초마다 상태를 갱신하면 데이터베이스 쓰기 부하가 커진다. - 개별 쓰기만 사용하면 초당 약 1,000회 쓰기라는 한계로 인해 지역당 약 5,000개 컨테이너 수준에서 병목이 발생할 수 있다. - 상태 업데이트를 Queues에 모은 뒤 100개 단위로 배치 처리했다. - 배치 쓰기는 개별 쓰기보다 처리 시간이 크게 늘지 않으므로 처리량을 크게 높일 수 있다. - 100개 단위 배치 기준으로 지역당 최대 약 500,000개 컨테이너까지 업데이트할 수 있는 여유를 확보했다. - 각 컨테이너는 5초마다 자신의 상태를 지역별 큐에 기록한다. - 큐 소비자는 다음과 같이 설정했다. - 최대 배치 크기: 100개 - 최대 배치 대기 시간: 1초 - 최대 재시도 횟수: 1회 - 배치 쓰기의 현재 P95 지연 시간은 0.1ms다. ## 성능 개선 결과 - Workers 바인딩을 통한 브라우저 생성량: - 분당 최대 60개 - 동시 실행 브라우저: - 최대 120개 - 이전보다 4배 증가 - Quick Action 응답 시간: - 50% 이상 단축 - 개선 사항은 기존 고객의 코드 변경이나 Worker 재배포 없이 즉시 적용됐다. Cloudflare의 사례는 짧고 급격한 트래픽을 처리하는 시스템에서 최종적 일관성 저장소를 핵심 할당 경로에 사용할 때 발생할 수 있는 문제를 보여준다. 실시간 자원 예약에는 트랜잭션 기반 DB를 사용하고, 빈번한 상태 갱신은 큐와 배치 쓰기로 분리하는 설계가 효과적인 접근이다.