「CNCF Serverless Whitepaper v1.0」から、３種のクラウドネイティブアプリケーションプラットフォームを知ろう

# これについて
「CNCF Serverless Whitepaper v1.0」を読んだ上で、CaaS、PaaS、FaaSについて整理してみました。

[原文](https://github.com/cncf/wg-serverless/tree/master/whitepaper)
[和訳](http://www.atmarkit.co.jp/ait/series/9263/)

上記の翻訳ではなく、個人的な解釈や考えが盛り込まれている点に注意してください。

### このホワイトペーパーについての雑な説明
サーバーレスと、CaaS/PaaSのようなその他のモデルとの違いなどをまとめた資料です。
サーバーレスを中心に解説されています。

---

# CNCFって？
https://www.cncf.io/projects/
Cloud Native Computing Foundationの略です。

> The Cloud Native Computing Foundation builds sustainable ecosystems and fosters a community around a constellation of high-quality projects that orchestrate containers as part of a microservices architecture.

マイクロサービスアーキテクチャやコンテナ技術の促進をするプロジェクトの集合体な感じです。

--- 

## プロジェクトの例
* Kubernetes (Graduated)
* Prometheus
* Fluentd
* gRPC
* containerd
* rkt
* Envoy

---

# サーバーレスとは
「サーバー管理を必要としない、アプリケーションの構築と実行の概念」です。

主にFaaSもしくはBaaSをサポートしており、以下の特徴があります。

1. サーバー運用が不要
1. 柔軟なスケーラビリティ
1. アイドル時の計算コストがない

---

## サーバーレスのユースケース
以下のような特性を持つワークロードがサーバーレスに向きます。

1. 非同期処理や並行処理のように、独立した作業単位に分解して並行処理が可能
1. 利用が散発的で、スケーリング要件に予測できない大きな変動がある
1. ステートレスで、瞬時のコールドスタートを必要としない
1. ビジネス要件が非常に動的で、開発速度が必要

ユースケースとしては以下のようなものがあります。

* DBの変更に応じてロジックを実行(1)
* IoTセンサーメッセージの処理(1)
* ストリーム処理(1)
* 短時間のうちに大量の処理をするETL(2,3)
* cronなど短時間で実行されるスケジュール化されたバッチ処理(2,3)
* 機械学習モデルの提供（学習済みモデルを使って異常などを特定する処理）(4)
* CIパイプラインで、オンデマンドにリソースをプロビジョニングする(1,2,3)

---

# ３種のクラウドネイティブアプリケーションプラットフォーム
クラウドネイティブなアプリケーションを展開するプラットフォームとして、CaaS, PaaS, FaaSの三種類が検討対象としてあります。

---

### CaaS
Containers-as-a-Serviceの略。

汎用的なコンテナアプリケーションを相互に協調させるオーケストレーションツールで、インフラも管理する。例はKubernetesやDocker Swarm。

### PaaS
Platform-as-a-Serviceの略。

ランタイムやスケーラビリティといった面は隠蔽され、開発チームはアプリケーション開発に注力する。

例はHerokuやGAEなど。

### FaaS
Functions-as-a-Serviceの略。サーバーレスのこと。

イベントベースで実行される小さなコードベース（関数）を作り、それぞれを組み合わせてアプリケーションを構築する。イベントに応じて関数をトリガーする処理や、関数間の情報の受け渡し、プロビジョニングやスケーリングなどはプラットフォームが管理します。

例はAWS Lambda、Google Cloud Functionsなど。

---

## 特徴の比較

---

### ターゲットユーザー
#### CaaS
* アプリケーションがどのようにパッケージングされ、どの様な環境で実行されるかをコントロールしたい
* 開発プラットフォーム間のポータビリティを確保したい
* 相互に依存するが独立してスケールするマイクロサービス群を管理したい

#### PaaS
* OSなどのランタイムを管理せずにアプリケーション開発に集中したい
* HTTPベースのアプリケーションやAPIを作りたい

#### FaaS
* イベントドリブンなアプリケーションを作成したい
* 標準やベストプラクティスがない尖った技術を採用したい
* ビジネスロジックの開発に集中したい

---

### 開発フロー
#### CaaS
* コンテナオーケストレーションのクラスタ作成
* 反復的にイメージをローカルビルドしながら開発
* コンテナイメージを作ってレジストリにプッシュ
* コンテナをクラスタにデプロイ

#### PaaS
* ローカル環境で開発・テストをイテレーション
* PaaSにアプリケーションをデプロイ
* 本番環境でアプリケーションをテスト・監視
* 十分な可用性・スケーラビリティをとれるように設定をする

#### FaaS
* 関数を対象にローカルで開発・テスト
* 個々の関数をFaaSにデプロイ
* イベントルールやランタイムの設定
* 本番環境でアプリケーションをテスト・監視
* 可用性やスケーラビリティの設定は不要

---

### メリット
#### CaaS
* デプロイされるアプリケーションや実行環境について大きなコントロールと責任を持てる
* コンテナの再利用性とポータビリティ
* すでにコンテナ化されているアプリをクラウドに持っていく良い選択肢

#### PaaS
* OSの管理不要
* アプリケーションビルドの手間が少ない
* スケーリングやデプロイについて選択できる

#### FaaS
* 実際に処理が行われただけ課金される（Pay as you go）
* OS,ランタイム、コンテナのライフサイクルが完全に抽象化される
* イベントドリブンで予測不可能なワークロードに対応できる
* 自動的にチューニング、最適化され、時間の経過とともにアプリケーションのパフォーマンスが向上する
* 実行環境に制約があるので、マイクロサービス化が強制される

---

### デメリット
#### CaaS
* セキュリティパッチなど実行環境のメンテナンス
* スケーリングや負荷分散、キャパシティの管理
* 設計の自由度が高いので考えることが多い
* 監視・ロギングなど

#### PaaS
* プラットフォームが提供するランタイムに縛られる
* [12factor app](https://12factor.net/)を指向しており、設計の自由度は高くない
* プラットフォームへのロックイン

#### FaaS
* 全体的に枯れておらず進化が続いているので、安定したドキュメントやベストプラクティスはなく、エコシステムやプラットフォームも未成熟
* ランタイムのダイナミックな性質によりデバッグが大変
* コールドスタートのパフォーマンス問題がある
* 関数の依存関係の管理が大変
* プラットフォームへのロックイン

---

## 3種類のうちどれを選択すべきか
複数の観点で評価する必要があります。

---

### 機能面
* サーバーレスの価値が活かせるワークロードに適合しているか？
* ランタイムや環境をどのくらいコントロールしたいか？
* 使いたい開発言語のライブラリや機能がしっかり活用できるか？
* セキュリティにどの程度敏感になるか？

---

### 運用面
#### 回復性
* データセンター障害にどのように対応するか？
* デプロイ時のサービス継続性をどう保証するか？
* サービスに障害が発生した場合、プラットフォームが自動的にリカバリするか？ユーザーに影響はないか？

#### スケーラビリティ
* 急な需要変化に対応できるか？
* アプリケーションはステートレスなスケーリングを活用できるよう設計されているか？
* サーバーレスプラットフォームはDBのような別のコンポーネントを圧迫しないか？

#### パフォーマンス
* インスタンスごと、HTTPクライアントごとの秒間リクエスト（関数呼び出し）はどの程度か？
* ワークロードにはどのくらいのインスタンスが必要か？
* コールドスタート、ウォームスタート時のレスポンスの遅延はどの程度か？

---

### その他の観点
* 費用や移植性
* ワークロードに応じた併用