domain-cloud-native について
Rust によるクラウドネイティブ開発向けのドメイン資料です。ステートレス設計、可観測性、グレースフルシャットダウンなどの制約を設計パターンや実装方法に結び付けています。サービスや Kubernetes ワークロードの開発者向けです。
主な機能
- 01クラウドネイティブの制約を解説
- 02制約と Rust の実装を対応付け
- 03よく使う Crate を掲載
- 04ヘルスチェックと終了処理のパターン
活用シーン
- 01ステートレスなサービス構成の計画
- 02サービスへのトレースとヘルスチェックの追加
- 03SIGTERM 時のグレースフルシャットダウン設計
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ actionbook/ rust-skills --skill domain-cloud-nativeインストール後、Claude Code で/domain-cloud-nativeを入力して読み込まれたか確認します。
詳細
クラウドネイティブドメイン
レイヤー 3:ドメイン制約
ドメイン制約 → 設計への影響
| ドメインルール | 設計上の制約 | Rust への影響 |
|---|---|---|
| 12-Factor | 環境変数から設定 | 環境ベースの設定 |
| 可観測性 | メトリクス + トレース | tracing + opentelemetry |
| ヘルスチェック | ライブネス/レディネス | 専用エンドポイント |
| グレースフルシャットダウン | クリーンな終了 | シグナル処理 |
| 水平スケーリング | ステートレス設計 | ローカル状態なし |
| コンテナ対応 | 小さなバイナリ | リリース最適化 |
重要な制約
ステートレス設計
RULE: No local persistent state
WHY: Pods can be killed/rescheduled anytime
RUST: External state (Redis, DB), no static mut
グレースフルシャットダウン
RULE: Handle SIGTERM, drain connections
WHY: Zero-downtime deployments
RUST: tokio::signal + graceful shutdown
可観測性
RULE: Every request must be traceable
WHY: Debugging distributed systems
RUST: tracing spans, opentelemetry export
さかのぼる ↓
制約から設計へ(レイヤー 2):
"Need distributed tracing"
↓ m12-lifecycle: Span lifecycle
↓ tracing + opentelemetry
"Need graceful shutdown"
↓ m07-concurrency: Signal handling
↓ m12-lifecycle: Connection draining
"Need health checks"
↓ domain-web: HTTP endpoints
↓ m06-error-handling: Health status
主要なクレート
| 用途 | クレート |
|---|---|
| gRPC | tonic |
| Kubernetes | kube, kube-runtime |
| Docker | bollard |
| トレーシング | tracing, opentelemetry |
| メトリクス | prometheus, metrics |
| 設定 | config, figment |
| ヘルス | HTTP エンドポイント |
設計パターン
| パターン | 用途 | 実装 |
|---|---|---|
| gRPC サービス | サービスメッシュ | tonic + tower |
| K8s オペレーター | カスタムリソース | kube-runtime Controller |
| 可観測性 | デバッグ | tracing + OTEL |
| ヘルスチェック | オーケストレーション | /health, /ready |
| 設定 | 12-factor | 環境変数 + シークレット |
コードパターン:グレースフルシャットダウン
use tokio::signal;
async fn run_server() -> anyhow::Result<()> {
let app = Router::new()
.route("/health", get(health))
.route("/ready", get(ready));
let addr = SocketAddr::from(([0, 0, 0, 0], 8080));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.with_graceful_shutdown(shutdown_signal())
.await?;
Ok(())
}
async fn shutdown_signal() {
signal::ctrl_c().await.expect("failed to listen for ctrl+c");
tracing::info!("shutdown signal received");
}
ヘルスチェックパターン
async fn health() -> StatusCode {
StatusCode::OK
}
async fn ready(State(db): State<Arc<DbPool>>) -> StatusCode {
match db.ping().await {
Ok(_) => StatusCode::OK,
Err(_) => StatusCode::SERVICE_UNAVAILABLE,
}
}
よくある間違い
| 間違い | ドメイン違反 | 修正方法 |
|---|---|---|
| ローカルファイルの状態 | ステートレスではない | 外部ストレージ |
| SIGTERM の処理がない | 強制終了 | グレースフルシャットダウン |
| トレーシングがない | デバッグできない | tracing スパン |
| 静的な設定 | 12-factor ではない | 環境変数 |
レイヤー 1 までさかのぼる
| 制約 | レイヤー 2 のパターン | レイヤー 1 の実装 |
|---|---|---|
| ステートレス | 外部状態 | 外部向けの Arc |
| グレースフルシャットダウン | シグナル処理 | tokio::signal |
| トレーシング | スパンのライフサイクル | tracing + OTEL |
| ヘルスチェック | HTTP エンドポイント | 専用ルート |
関連スキル
| 該当する場合 | 参照先 |
|---|---|
| 非同期パターン | m07-concurrency |
| HTTP エンドポイント | domain-web |
| エラー処理 | m13-domain-error |
| リソースのライフサイクル | m12-lifecycle |
コメント
Markdown 対応