前回の記事を公開してから半年近く経過しましたが、最近 Cloud Run がストリーミングの gRPC に対応したので(公式ブログ記事)、早速試してみます。
前回と同様、tonic の公式サンプルを Cloud Run にデプロイしてみます。
準備
サンプルコードの取得
$ git clone https://github.com/hyperium/tonic.git
$ cp -r tonic/examples tonic-examples
$ cd tonic-examples
Cargo.toml
の書き換え
diff ../tonic/examples/Cargo.toml ./Cargo.toml
142c142
< tonic = { path = "../tonic", features = ["tls"] }
---
> tonic = { version = "0.3", features = ["tls", "tls-roots"] }
166c166
< tonic-health = { path = "../tonic-health" }
---
> tonic-health = { version = "0.2" }
170c170
< tonic-build = { path = "../tonic-build", features = ["prost"] }
---
> tonic-build = { version = "0.3", features = ["prost"] }
ディレクトリ構成変更の対応
$ fd --extension rs | xargs -I @ sed -i 's,examples/,,g' @
サンプルコードの動作確認
$ cargo run --bin routeguide-server
# 別のターミナルウィンドウで
$ cargo run --bin routeguide-client
Cloud Run へのデプロイ
IPアドレスおよびポート番号の変更
diff ../tonic/examples/src/routeguide/data.rs src/routeguide/data.rs
18c18
< let file = File::open("examples/data/route_guide_db.json").expect("failed to open data file");
---
> let file = File::open("data/route_guide_db.json").expect("failed to open data file");
diff ../tonic/examples/src/routeguide/server.rs src/routeguide/server.rs
137c137,138
< let addr = "[::1]:10000".parse().unwrap();
---
> let port = std::env::var("PORT").unwrap_or("8080".into());
> let addr = format!("0.0.0.0:{}", port).parse().unwrap();
Dockerfile
を用意
FROM rust as build-env
WORKDIR /app
ADD . .
RUN rustup component add rustfmt && cargo build --bin routeguide-server
FROM gcr.io/distroless/cc
COPY --from=build-env /app/data/route_guide_db.json /data/route_guide_db.json
COPY --from=build-env /app/target/debug/routeguide-server /
CMD ["./routeguide-server"]
ビルド
$ echo 'target/' > .gcloudignore
$ gcloud builds submit --machine-type=n1-highcpu-32 --tag gcr.io/$PROJECT_ID/routeguide
デプロイ
$ gcloud config set run/region asia-northeast1
$ gcloud run deploy routeguide \
--image=gcr.io/$PROJECT_ID/routeguide \
--allow-unauthenticated \
--platform managed
デプロイされたサービスの動作確認
デプロイされたサービスに接続するよう変更。
双方向ストリーミングは記事執筆時点で対応していないためコメントアウトした。
diff ../tonic/examples/src/routeguide/client.rs src/routeguide/client.rs
8c8
< use tonic::transport::Channel;
---
> use tonic::transport::{Channel, ClientTlsConfig};
94c94,97
< let mut client = RouteGuideClient::connect("http://[::1]:10000").await?;
---
> let tls = ClientTlsConfig::new().domain_name("デプロイ先");
> let channel = Channel::from_static("https://デプロイ先")
> .tls_config(tls)?.connect().await?;
> let mut client = RouteGuideClient::new(channel);
111,112c114,115
< println!("\n*** BIDIRECTIONAL STREAMING ***");
< run_route_chat(&mut client).await?;
---
> // println!("\n*** BIDIRECTIONAL STREAMING ***");
> // run_route_chat(&mut client).await?;
動作確認
$ cargo run --bin routeguide-client
まとめ
Cloud Run は Docker コンテナさえ用意できればデプロイできるため自由度の高いサービスである。
今回 Cloud Run がストリーミングに対応したことで、クライアントに大きなサイズのデータを送信したり、長期プロセスの途中経過を通知したりすることが可能となり、更に活用の幅が広がった。