구독해서 새 게시물에 대한 알림을 받으세요.

Pingora 오픈 소싱: 프로그래밍 가능한 네트워크 서비스 구축을 위한 Cloudflare의 Rust 프레임워크

2024-02-28

5분 읽기
이 게시물은 English, 繁體中文, Français, Deutsch, 日本語, Português, Español简体中文로도 이용할 수 있습니다.

오늘, Cloudflare에서 Cloudflare 트래픽의 상당 부분을 구동하는 서비스 구축에 사용하고 있는 Rust 프레임워크인 Pingora를 오픈 소스화하게 된 것을 자랑스럽게 알려드립니다. Pingora는 Apache 라이선스 버전 2.0에 따라 출시되었습니다.

Open sourcing Pingora: our Rust framework for building programmable network services

이전 블로그 게시물에서 언급했듯이 Pingora는 HTTP 프록시 서비스 구축을 지원하는 Rust 비동기 멀티 스레드 프레임워크입니다. 블로그에 올린 지난번 게시물 이후 Pingora는 전역 네트워크에서 거의 1,000조 개의 인터넷 요청을 처리했습니다.

Cloudflare에서는 Pingora를 오픈 소싱하여 자체 인프라를 넘어 더 나은 환경을 구축할 수 있도록 하고 있습니다. 저희는 고객, 사용자 등 다른 사람들이 메모리 안전 프레임워크를 사용하여 자신만의 인프라를 구축할 수 있도록 도구, 아이디어, 영감을 제공하고자 합니다. 업계미국 정부에서 메모리 안전의 중요성에 대한 인식이 높아지고 있는 상황에서 이러한 프레임워크를 갖추는 것은 특히 중요합니다. 이러한 공통의 목표에 따라, 저희는 Internet Security Research Group(ISRG)의 Prossimo 프로젝트와 협력하여 인터넷의 가장 중요한 인프라에 Pingora 채택을 진전시킬 수 있도록 지원하고 있습니다.

이전 블로그 게시물에서 Pingora를 구축한 이유와 방법을 논의했습니다. 이번 게시물에서는 여러분이 Pingora를 사용할 수 있는 이유와 방법에 대해 알아보겠습니다.

Pingora는 프록시뿐만 아니라 클라이언트와 서버의 구성 요소도 제공합니다. Cloudflare에서는 이들 구성 요소와 더불어 이벤트 카운팅, 오류 처리, 캐싱 등 일반적인 로직을 구현하는 몇 가지 유틸리티 라이브러리도 제공합니다.

제공 내용

Pingora는 HTTP/1과 HTTP/2, TLS 또는 TCP/UDP를 기반으로 서비스를 구축할 수 있는 라이브러리와 API를 제공합니다. 프록시로서 Pingora는 HTTP/1 및 HTTP/2 엔드투엔드, gRPC, 웹소켓 프록시를 지원합니다(HTTP/3 지원은 로드맵에 있습니다). 또한 사용자 정의 가능한 부하 분산 및 장애 조치 전략도 함께 제공합니다. 규제 준수와 보안을 위해, 일반적으로 사용되는 OpenSSL 및 BoringSSL 라이브러리를 모두 지원하여 FIPS 규제 준수 및 포스트 퀀텀 암호화가 함께 제공됩니다.

이러한 기능 제공 외에도, Pingora는 필터와 콜백을 제공하여 서비스가 요청을 처리하고 변환하며 전달하는 방법을 완전히 사용자 지정할 수 있도록 합니다. 이러한 API는 OpenResty 및 NGINX 사용자에게 특히 친숙할 것입니다. 왜냐하면 많은 API가 OpenResty의 "*_by_lua" 콜백에 직관적으로 매핑되기 때문입니다.

운영 측면에서 Pingora는 수신되는 요청을 단 한 번도 삭제하지 않고도 다운타임 없이 부드럽게 재시작하여 스스로 업그레이드할 수 있습니다. Syslog, Prometheus, Sentry, OpenTelemetric, 기타 필수 관찰 도구도 Pingora와 쉽게 통합될 수 있습니다.

Pingora의 혜택을 받을 수 있는 사용자

다음과 같은 경우에는 Pingora를 고려해야 합니다.

보안이 최우선인 경우: Pingora는 C/C++로 작성된 서비스에 대한 메모리 안전성이 뛰어난 대안입니다. 일부에서는 프로그래밍 언어의 메모리 안전성에 대해 논쟁을 벌일 수도 있지만, 실제 경험상 메모리 안전 문제로 이어지는 코딩 실수를 저지를 확률은 훨씬 낮습니다. 게다가 이러한 문제로 고민하는 시간이 줄어들면서 새로운 기능을 구현하는 데 더 많은 생산성을 발휘할 수 있게 되었습니다.

서비스가 성능에 민감한 경우: Pingora는 빠르고 효율적입니다. 이전 블로그 게시물에서 설명한 것처럼, Cloudflare에서는 Pingora의 멀티 스레드 아키텍처 덕분에 CPU와 메모리 리소스를 많이 절약했습니다. 시간과 리소스 절약은 시스템 비용 및/또는 속도에 민감한 워크로드의 경우 강력할 수 있습니다.

서비스에 대해서 광범위한 사용자 지정이 필요한 경우: Pingora 프록시 프레임워크가 제공하는 API는 고도로 프로그래밍 가능합니다. 맞춤형 고급 게이트웨이 또는 로드 밸런서를 구축하려는 사용자를 위해 Pingora는 이를 구현하는 강력하면서도 간단한 방법을 제공합니다. 다음 섹션에서 예제를 제공합니다.

로드 밸런서를 구축해 봅니다

간단한 로드 밸런서를 구축하며 Pingora의 프로그래밍 가능한 API를 살펴보겠습니다. 로드 밸런서는 https://1.1.1.1/https://1.0.0.1/ 사이에서 라운드 로빈 방식으로 업스트림으로 선택합니다.

먼저 빈 HTTP 프록시를 만들어 보겠습니다.

ProxyHttp 특성(C++이나 Java의 인터페이스 개념과 유사)을 구현하는 모든 개체는 HTTP 프록시입니다. 여기에는 모든 요청마다 호출되는 upstream_peer() 메서드만 있으면 됩니다. 이 함수는 연결할 원본 IP 및 해당 원본 IP와의 연결 방법이 포함된 HttpPeer를 반환해야 합니다.

pub struct LB();

#[async_trait]
impl ProxyHttp for LB {
    async fn upstream_peer(...) -> Result<Box<HttpPeer>> {
        todo!()
    }
}

이제 라운드 로빈 선택을 구현해 보겠습니다. Pingora 프레임워크는 이미 라운드 로빈 및 해싱 등의 공통 선택 알고리즘을 LoadBalancer에 제공하고 있으니 그냥 사용해 보겠습니다. 보다 정교하거나 사용자 지정된 서버 선택 로직이 필요한 사용 사례의 경우, 사용자가 이 함수로 직접 구현할 수 있습니다.

HTTPS 서버에 연결하고 있으므로 SNI도 설정해야 합니다. 필요한 경우 여기 HttpPeer 개체에서 인증서, 제한 시간 초과, 기타 연결 옵션도 설정할 수 있습니다.

pub struct LB(Arc<LoadBalancer<RoundRobin>>);

#[async_trait]
impl ProxyHttp for LB {
    async fn upstream_peer(...) -> Result<Box<HttpPeer>> {
        let upstream = self.0
            .select(b"", 256) // hash doesn't matter for round robin
            .unwrap();

        // Set SNI to one.one.one.one
        let peer = Box::new(HttpPeer::new(upstream, true, "one.one.one.one".to_string()));
        Ok(peer)
    }
}

마지막으로, 서비스를 실행하겠습니다. 이 예에서는 원본 서버 IP를 하드 코딩합니다. 실제 워크로드에서는 upstream_peer()가 호출될 때 또는 백그라운드에서 원본 서버 IP를 동적으로 검색할 수도 있습니다. 서비스가 생성된 후 LB 서비스에 127.0.0.1:6188을 수신하도록 지시합니다. 마지막으로 우리는 Pingora 서버를 만들었고, 서버는 부하 분산 서비스를 실행하는 프로세스가 될 것입니다.

시도해 보겠습니다.

fn main() {
    let mut upstreams = LoadBalancer::try_from_iter(["1.1.1.1:443", "1.0.0.1:443"]).unwrap();

    let mut lb = pingora_proxy::http_proxy_service(&my_server.configuration, LB(upstreams));
    lb.add_tcp("127.0.0.1:6188");

    let mut my_server = Server::new(None).unwrap();
    my_server.add_service(lb);
    my_server.run_forever();
}

프록시가 작동하고 있지만, 원본 서버가 403과 함께 이를 거부하는 것을 확인할 수 있습니다. 이는 우리 서비스가 단순히 컬에 의해 설정된 Host 헤더 127.0.0.1:6188을 프록시하여 원본 서버를 혼란시키기 때문입니다. 프록시가 이를 수정하도록 하려면 어떻게 해야 할까요? upstream_request_filter라는 또 다른 필터를 추가하면 됩니다. 이 필터는 원본 서버가 연결된 후 HTTP 요청이 전송되기 전에 모든 요청에 대해 실행됩니다. 이 필터에서 http 요청 헤더를 추가, 제거, 변경할 수 있습니다.

curl 127.0.0.1:6188 -svo /dev/null
> GET / HTTP/1.1
> Host: 127.0.0.1:6188
> User-Agent: curl/7.88.1
> Accept: */*
> 
< HTTP/1.1 403 Forbidden

다시 시도해 보겠습니다.

async fn upstream_request_filter(…, upstream_request: &mut RequestHeader, …) -> Result<()> {
    upstream_request.insert_header("Host", "one.one.one.one")
}

이번에는 성공했습니다! 전체 예제는 여기에서 확인할 수 있습니다.

curl 127.0.0.1:6188 -svo /dev/null
< HTTP/1.1 200 OK

아래 이 요청이 이 예시에서 사용한 콜백과 필터를 통해 어떻게 전달되는지를 보여주는 간단한 다이어그램이 나와 있습니다. Pingora 프록시 프레임워크는 현재 사용자가 요청(및 응답)을 수정, 거부, 라우팅 및/또는 기록할 수 있도록 요청의 다양한 단계에서 더 많은 필터와 콜백을 제공합니다.

배후에서는 Pingora 프록시 프레임워크가 연결 풀링, TLS 핸드셰이크, 읽기, 쓰기, 요청 구문 분석, 기타 일반적인 프록시 작업을 처리하므로 사용자는 중요한 로직에 집중할 수 있습니다.

오픈 소스, 현재와 미래

Pingora는 실행 가능한 바이너리가 아닌 라이브러리 및 도구 세트입니다. 다시 말해, Pingora는 자동차 자체가 아니라 자동차에 동력을 공급하는 엔진입니다. Pingora는 산업용으로 프로덕션 준비가 완료되었지만, 저희는 많은 사람이 배터리가 포함되고 코드가 적거나 없는 구성 옵션을 갖추고 즉시 사용할 수 있는 웹 서비스를 원한다는 것을 이해합니다. Pingora 위에 해당 앱을 구축하는 것은 Pingora의 도달 범위를 확장하기 위한 Cloudflare와 ISRG 간 협력의 초점입니다. 해당 프로젝트에 대한 향후 발표를 기대해 주세요.

기타 유의 사항:

  • 현재는 API 안정성이 보장되지 않습니다. 주요 변경 빈도를 최소화하려고 노력하겠지만, 특히 1.0 이전 기간에 라이브러리가 발전함에 따라 저희는 요청 및 응답 필터와 같은 구성 요소를 추가, 제거, 변경할 권리를 보유하게 됩니다.

  • Unix 기반이 아닌 운영 체제에 대한 지원은 현재 로드맵에 포함되어 있지 않습니다. 이러한 시스템을 지원할 즉각적인 계획은 없지만, 향후 변경될 수 있습니다.

기여 방법

GitHub 이슈 트래커에 버그 보고서, 문서화 문제, 기능 요청 등을 자유롭게 제기할 수 있습니다. 풀 요청을 하기 전에, 저희 기여 가이드를 살펴보실 것을 강력히 권장합니다.

결론

이 블로그에서는 Pingora 프레임워크의 오픈 소스를 발표했습니다. 저희는 인터넷 개체와 인프라가 Pingora의 보안, 성능, 사용자 지정 기능에서 이점을 얻을 수 있음을 설명했습니다. 또한 Pingora의 사용이 얼마나 쉬운지, 얼마나 사용자 정의할 수 있는지도 시연했습니다.

프로덕션 웹 서비스를 구축하시든, 네트워크 기술을 실험하시든, Pingora에서 가치를 찾으시길 바랍니다. 긴 여정이었지만, 이 프로젝트를 오픈 소스 커뮤니티와 공유하는 것이 처음부터의 목표였습니다. Pingora는 훌륭한 오픈 소스 Rust 크레이트로 구축되어 있습니다. Rust 커뮤니티에 감사의 말씀을 전하고 싶습니다. 메모리가 안전한 인터넷으로 이동하는 것이 불가능한 여정처럼 느껴질 수도 있지만, 여러분도 저희와 그 여정에 함께하기를 바랍니다.

Cloudflare에서는 전체 기업 네트워크를 보호하고, 고객이 인터넷 규모의 애플리케이션을 효과적으로 구축하도록 지원하며, 웹 사이트와 인터넷 애플리케이션을 가속화하고, DDoS 공격을 막으며, 해커를 막고, Zero Trust로 향하는 고객의 여정을 지원합니다.

어떤 장치로든 1.1.1.1에 방문해 인터넷을 더 빠르고 안전하게 만들어 주는 Cloudflare의 무료 앱을 사용해 보세요.

더 나은 인터넷을 만들기 위한 Cloudflare의 사명을 자세히 알아보려면 여기에서 시작하세요. 새로운 커리어 경로를 찾고 있다면 채용 공고를 확인해 보세요.
Developer Platform개발자RustOpen SourcePerformance

X에서 팔로우하기

Cloudflare|@cloudflare

관련 게시물

2024년 10월 31일 오후 1:00

Moving Baselime from AWS to Cloudflare: simpler architecture, improved performance, over 80% lower cloud costs

Post-acquisition, we migrated Baselime from AWS to the Cloudflare Developer Platform and in the process, we improved query times, simplified data ingestion, and now handle far more events, all while cutting costs. Here’s how we built a modern, high-performing observability platform on Cloudflare’s network. ...

2024년 10월 25일 오후 1:00

Elephants in tunnels: how Hyperdrive connects to databases inside your VPC networks

Hyperdrive (Cloudflare’s globally distributed SQL connection pooler and cache) recently added support for directing database traffic from Workers across Cloudflare Tunnels. We dive deep on what it took to add this feature....