新規投稿のお知らせを受信されたい方は、サブスクリプションをご登録ください:

Pingoraのオープンソース化:プログラマブルなネットワークサービスを構築するためのRustフレームワーク

2024/02/28

5分で読了
Open sourcing Pingora: our Rust framework for building programmable network services

このたびCloudflareは、Pingoraのオープンソース化を発表いたします。Pingoraは、当社が、トラフィックの大部分を支えるサービスを構築するために使用してきたRustフレームワークで、Apache License 2.0リリースされます。

過去のブログ投稿に記述したように、PingoraはRustの非同期型マルチスレッドフレームワークで、CloudflareでのHTTPプロキシサービスの構築をサポートしています。この投稿の後、Cloudflareのグローバルネットワーク全体で一千兆件近くのインターネットリクエストがPingoraにより処理されてきました。

Cloudflareは、自社のインフラストラクチャを超えて、より良く、より安全なインターネットの構築を支援するために、Pingoraをオープンソース化いたします。私たちは、このオープンソース化により、ユーザーの皆様やその他の方々に、メモリ安全性の高いフレームワークを使って独自のインターネットインフラを構築する際の、ツール、アイデア、ヒントをご提供したいと考えています。業界米国政府でもメモリ安全性の重要性に対する認識が高まっていることを考えると、このようなフレームワークは特に重要です。この共通の目標の下、CloudflareはInternet Security Research Group(ISRG)Prossimoプロジェクトとともに、インターネットの最も重要なインフラにおけるPingora導入の促進に取り組みます。

前述のブログ投稿では、Pingoraを構築した理由と方法を説明しました。この投稿では、Pingoraを使うべき理由とその方法についてご説明します。

Pingoraは、プロキシだけでなく、クライアントとサーバーにもビルディングブロックを提供します。これらのコンポーネントに加え、イベントカウント、エラー処理、キャッシングなどの共通ロジックが実装されたユーティリティライブラリも提供されます。

詳細

Pingoraは、HTTP/1やHTTP/2、API TLS上、またはTCP/UDPの直上でサービスを構築するためのライブラリとUDPを提供します。プロキシとしては、HTTP/1およびHTTP/2エンドツーエンド、gRPC、WebSocketプロキシをサポートします(HTTP/3のサポートも予定されています)。また、カスタマイズ可能な負荷分散とフェイルオーバーの手法も付随します。コンプライアンスとセキュリティについては、一般的に使用される、FIPSコンプライアンスとポスト量子暗号を備えたOpenSSLとBoringSSLライブラリの両方をサポートします。

これらの機能の提供に加え、Pingoraで提供されるフィルタとコールバックを使用すれば、サービスがリクエストをどのように処理し、変換し、転送するべきかを完全にカスタマイズできます。これらのAPIは、その多くがOpenRestyの「*_by_lua」コールバックに直感的にマッピングされるため、OpenRestyとNGINXユーザーにとっては特に使いやすいはずです。

運用面では、Pingoraはダウンタイムゼロのグレースフルリスタートを提供し、着信リクエストを1つもドロップすることなく自身をアップグレードします。SyslogやPrometheus、Sentry、OpenTelemetry、その他必要な可観測性ツールもPingoraと簡単に統合できます。

Pingoraのメリット

以下のケースでは、Pingora導入の検討が推奨されます。

セキュリティが最優先事項となるケース:Pingoraは、C/C++で書かれたサービスにはよりメモリ安全性の高い代替手段です。プログラミング言語におけるメモリ安全性については議論の余地がありますが、私たちは、実際の経験に基づき、メモリ安全性の問題につながるコーディングミスの可能性はかなり低いと考えています。しかも、これらの問題に悩まされる時間が軽減されるため、生産的に新機能の実装に取り組むことができます。

サービスがパフォーマンス重視であるケース:Pingoraは、高速かつ効率的です。以前のブログ記事で説明したように、私たちはPingoraのマルチスレッドアーキテクチャで多くのCPUとメモリリソースを節約できました。コストやシステムの速度を重視するワークロードにとっては、時間とリソースの節約は魅力的でしょう。

広範なカスタマイズが必要なサービスであるケース:Pingoraプロキシのフレームワークが提供するAPIは、優れたプログラマブル性を有します。カスタマイズされた高度なゲートウェイやロードバランサーを構築するユーザーにとって、Pingoraは強力かつシンプルにそれを実現します。次のセクションで例を見てみましょう。

ロードバランサーを構築してみる

シンプルなロードバランサーを構築して、PingoraのプログラマブルなAPIを試してみましょう。ロードバランサーは、https://1.1.1.1/https://1.0.0.1/の間でラウンドロビン方式で上流を選択します。

まず、空のHTTPプロキシを作成しましょう。

pub struct LB();

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

ProxyHttp trait(C++やJavaのインターフェースの概念に似ている)を実装しているオブジェクトはすべてHTTPプロキシです。唯一必要なメソッドは、すべてのリクエストに対して呼び出されるupstream_peer()です。この関数は、接続先のオリジンIPと接続方法を含む HttpPeerを返す必要があります。

次に、ラウンドロビン方式の選択を実装しましょう。Pingoraフレームワークでは、すでにLoadBalancerにラウンドロビンやハッシュなどの一般的な選択アルゴリズムが提供されているので、それを使用してみましょう。ユースケースにより、より高度なサーバー選択ロジックやサーバー選択ロジックのカスタマイズが必要とされる場合は、この関数でユーザーが簡単に実装できます。

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)
    }
}

HTTPSサーバーに接続するので、SNIも設定する必要があります。必要に応じて、証明書、タイムアウト、その他の接続オプションも、HttpPeerオブジェクトで設定することができます。

最後に、サービスを実行してみましょう。この例では、オリジンサーバーのIPをハードコードします。実際のワークロードでは、オリジンサーバーのIPは、 upstream_peer()が呼び出される際、あるいはバックグラウンドで動的に検出することもできます。サービスが作成されたら、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();
}

試してみましょう。

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

プロキシが機能しているのに、オリジンサーバーが403で拒否していることがわかります。これは、curlによって設定されたHostヘッダー(127.0.0.1:6188)を単純にプロキシしていることが原因で、これがオリジンサーバーに不都合を引き起こしています。この問題を修正するために、upstream_request_filterと呼ばれるフィルタを追加します。このフィルタは、オリジンサーバーに接続された後、HTTPリクエストが送信される前に各リクエストで実行されます。このフィルタ内でHTTPリクエストヘッダーを追加、削除、変更できます。

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は産業利用の本番環境に対応していますが、バッテリー付きでローコードまたはノーコードの設定オプションを備えた、すぐに使えるWebサービスを求める人が多いことも私たちは把握しています。Pingora上にそのアプリケーションを構築することが、Pingoraのリーチ拡大に向けたISRGとの協力のテーマです。このプロジェクトに関する今後の発表に引き続きご注目ください。

その他の注意事項

  • 現在、APIの安定性は保証されていません。破壊的な変更を行う頻度は最小限に抑える予定ですが、特にこの1.0以前の期間中は、ライブラリの進化に伴ってリクエストやレスポンスフィルタなどのコンポーネントを追加、削除、変更する権利を留保します。
  • Unixベースでないオペレーティングシステムのサポートは、現在予定されていません。将来的には変更される可能性があります。

ご協力をお願いします

バグレポート、ドキュメントの問題、機能リクエストは、GitHubのIssue Trackerでお気軽にお寄せください。プルリクエストを開く前に、Cloudflareのコントリビュートガイドをご覧いただくことをおすすめします。

まとめ

このブログ投稿では、Pingoraフレームワークのオープンソース化をお知らせして、インターネットエンティティとインフラストラクチャにとって、Pingoraのセキュリティ、パフォーマンス、カスタマイズ可能性が価値となることを説明しました。また、Pingoraの使いやすさやカスタマイズ可能性を実証しました。

本番Webサービスの構築中の方々、あるいはネットワークテクノロジーを試してみようと思っている方々に、Pingoraを利用する価値を感じていただければと思います。長い道のりでしたが、このプロジェクトをオープンソースコミュニティと共有することは、当初からの目標でした。Rustコミュニティに感謝いたします。Pingoraは多くの素晴らしいオープンソースのRustクレートで構築されています。メモリ安全性の高いインターネットへの移行は不可能とも思える道のりかもしれませんが、ご参加いただければ幸いです。

Cloudflareは企業ネットワーク全体を保護し、お客様がインターネット規模のアプリケーションを効率的に構築し、あらゆるWebサイトやインターネットアプリケーションを高速化し、DDoS攻撃を退けハッカーの侵入を防ぎゼロトラスト導入を推進できるようお手伝いしています。

ご使用のデバイスから1.1.1.1 にアクセスし、インターネットを高速化し安全性を高めるCloudflareの無料アプリをご利用ください。

より良いインターネットの構築支援という当社の使命について、詳しくはこちらをご覧ください。新たなキャリアの方向性を模索中の方は、当社の求人情報をご覧ください。
Developer Platform (JP)Developers (JP)Rust (JP)Open Source (JP)Performance (JP)日本語

Xでフォロー

Cloudflare|@cloudflare

関連ブログ投稿

2024年6月20日 13:00

Workers AIを搭載したStream Generated Captionsの紹介

Streamの最新機能であるオンデマンド動画やライブストリーミングの録画用のAI生成キャプションを使って、ユーザーはワンクリックで動画キャプションを簡単に生成できるようになりました...

2024年5月22日 13:00

AI Gatewayの一般提供を開始:生成AIワークロードの管理とスケーリングのための統合インターフェース

AI Gatewayは、AIアプリに速度、信頼性、可観測性を提供するAI運用プラットフォームです。ごくわずかなコードで、レート制限、カスタムキャッシング、リアルタイムログ、複数のプロバイダにわたる集約分析などの強力な機能が利用できるようになります...

2024年4月05日 13:01

Browser Rendering APIのGA化、そしてCloudflare Snippets、SWRの展開、Workers for Platformsの全ユーザーへの提供

Browser Rendering APIをセッション管理の改善と共にすべての有料Workers顧客に提供開始...

2024年4月03日 13:30

R2に、「イベント通知」、「Google Cloud Storageからの移行のサポート」、「低頻度アクセスストレージ階層」が追加されました

Cloudflare R2の3つの新機能である、「イベント通知」、「Google Cloud Storageからの移行のサポート」、「低頻度アクセスのストレージ階層」を発表できることを嬉しく思います...