Webアプリケーションを動かすときの基盤選定の勘所

この記事は、[LAPRAS Advent Calendar 2020](https://qiita.com/advent-calendar/2020/lapras) ９日目の記事です。

業務委託にてLAPRAS SCOUTのお手伝いをさせて頂いております。
普段は、[Joolen](https://www.joolen.co.jp/)という会社で、**エンジニア** 兼 **マーケテイング担当** 兼 **営業担当** 兼 … という仕事をしており、もはや自分が何者かを見失っています:sweat_smile:

今回は私のもう一つの顔である、[IBM Champion](https://developer.ibm.com/jp/blogs/about-ibmchampions/)として登壇させて頂いた[イベント](https://ibm-developer.connpass.com/event/196143/)でお話しした内容をまとめています。IBMのテクノロジーに限らず、クラウド初心者の、プラットフォーム選定の手助けになれば幸いです。

## どんな時にどんな基盤を使うのが良い?
今日、クラウドサービスの充実によりアプリケーションを稼働させるためのプラットフォームは多岐に渡っています。どの様なシチュエーションの時に、どの様なプラットフォームを選定するのが良いかお悩みではありませんか?(私はよく悩みます:sweat_smile:)
本記事では、IBM Cloudで提供されているサービスを中心にしながら、どの様にアプリケーション基盤を選定すれば良いかまとめていきます。:+1:

## 今回の分類
* Iaas (Infrastructure as a Service)
* Paas (Platform as a Service)
* Faas(Function as a Service)
* Managed Kubernetes Service
* Kubernetes ディストリビューション (Red Hat OpenShiftなど)
* Knativeベースのサーバレスサービス

## 早速、まとめ
表形式にすると情報が丸まりすぎて賛否あると思いますが…

| |IaaS|PaaS|FaaS|Managed K8s Service|K8s ディストリビューション|Serverless on Knative|
|:----|:----:|:----:|:----:|:----:|:----:|:----:|
|レスポンスを20ms以内に返すなどの特殊要件がある|○|×|×|△|△|×|
|既存のオンプレの資産をそのまま移行したい|○|×|×|×|×|×|
|ちょっと複雑なアプリケーションを、さくっと動かしたい|×|○|×|×|×|○|
|インフラに詳しいエンジニアがいないがサービスを始めたい|×|○|○|×|△|○|
|スケジュールやイベント駆動で小さなアプリを最適なコストで動かしたい|×|×|○|×|×|○|
|基盤にコストをかけられない|×|○|○|×|×|○|
|複数のコンテナを安定して稼働させたい|×|×|×|○|○|×|
|GUIベースでわかりやすくK8sのメリットを受けたい|×|×|×|×|○|×|
※ △は要件や状況次第で使えるかな、というニュアンス


## 各基盤サービスごとのまとめ

### IaaS

#### 代表的なサービス
* [IBM Cloud Bare Metal Servers](https://www.ibm.com/jp-ja/cloud/bare-metal-servers)
* [AWSのEC2](https://aws.amazon.com/jp/ec2/)

#### pros :thumbsup: 
* 物理サーバを所有していた時と同じ様に、OSレベルからのアクセス権限を持つことができる。
* ディスク故障などの物理的なメンテナンスから解放される。
* リソース専有できるサービスを選ぶと、安定した性能を確保することもできる
* 元々あるオンプレの仕組みをそのままクラウド上に持っていくことができる

#### cons :thumbsdown: 
* ユーザはアプリケーションを稼働するために、各種ミドルウェアのセットアップやメンテナンスが必要になる
* OSの脆弱性が発見されたなども、全て自分でアップデート対応を行う必要がある。
* 開発環境・ステージング環境・本番環境…と複数の環境を管理するときに、全く同じ環境にするのが大変。。。

#### どんな時にオススメ？
* レスポンスを20ms以内に返すなどの特殊要件がある
* 既存のオンプレの資産をそのまま移行したい

### PaaS

#### 代表的なサービス

* [Cloud Foundry](https://www.ibm.com/jp-ja/cloud/cloud-foundry)
* [Google App Engine](https://cloud.google.com/appengine?hl=ja)

#### pros:thumbsup: 
* OSやミドルウェアなど、アプリケーションを動かす為のプラットフォームを自分でセット アップする必要がない
* 一度、型にハマってしまえばすぐにアプリケーションをデプロイすることができる
* ソース管理やCI/CDの仕組みが、簡単に統合できる (IBM Cloud Continuous Delivery[https://www.ibm.com/jp-ja/cloud/continuous-delivery] みたいに)
* 小さく始めることもできる上、自動でスケールするのでバズったりした時にも安心

#### cons :thumbsdown:
* PaaSにデプロイするための手順など、学習は必要になる
* 専門外の人にこの仕組みを理解してもらうのが大変
* 作りたいアプリケーションの要件によって、どのプラットフォームを選ぶかも変わってくるので、選定が難しい。

#### どんな時にオススメ？
* モバイルゲームのAPIサーバとして(自動スケールを活用)
* 比較的小規模なアプリケーションを運用する時
* 一時的なイベントサイトの運用先として

### Faas

#### 代表的なサービス
* [IBM Cloud Functions](https://www.ibm.com/jp-ja/cloud/functions)
* [Microsoft Azure Functions](https://azure.microsoft.com/ja-jp/services/functions/)

#### pros:thumbsup:
* 実際にコードが動いた分しか課金されない
* コードを書くだけで処理を動かすことができる
* フレームワークすら不要で、書きたい処理だけ書くことができる

#### cons:thumbsdown:
* 複数Classを継承したりするような、大きなソースコードを扱うには不向き。npmとかライブラリを使おうとするとそれだけで、ちょっと面倒。
* PHP,Node.jsなど、対応できる言語が限られている(IBM Cloud Functionsでは、Dockerイ メージを使えますが、パブリックなリポジトリのみ利用可能)
* 状態を持てないので(ステートレス)、ストレージやセッション管理などは他のサービスを使う必要がある。

#### どんな時にオススメ？
* 定期的にどこかにリクエストを投げたい時(メールを投げたり、Slackに通知したり…)
* Watson Assistantなどと連携するための、エンドポイントとして

### Managed Kubernetes Service

#### 代表的なサービス
* [IBM Cloud Kubernetes Service](https://www.ibm.com/jp-ja/cloud/container-service)
* [Amazon EKS](https://aws.amazon.com/jp/eks/)

#### pros
* 自分でオンプレで構築しようとすると大変なK8sの環境を簡単に手に入れることができる。(やったことないけど、かなり大変らしい)

#### cons
* 使うにはK8sに関する知識 (`kubectl` コマンドの打ち方やコンテナ運用に対する専門知識など)が必要

#### どんな時にオススメ？
* 複数コンテナを安定して運用したい時
* 既にK8sに詳しいエンジニアがいる、もしくは学習・検証する時間やコスト的な余裕がある時。無策で突っ込むのは、ちょっと大変カモ。


### Kubernetes ディストリビューション

#### 代表的なサービス
* [Red Hat OpenShift](https://www.ibm.com/jp-ja/cloud/openshift)
* [Anthos GKE](https://cloud.google.com/anthos/gke/?hl=ja)

#### pros
* Webコンソールが充実していて、生のK8sを使うより、圧倒的に簡単にK8sクラスタを組むことができる。
* K8s上で動いているので、K8sで提供されている機能は基本的に利用可能

#### cons
* 導入して動かしているだけで、かなり大きめなコストが必要になる。

#### どんな時にオススメ？
* 開発資金に余裕がある時
* 大きな規模のプロダクトを安定して運用＆拡張していきたい時

### Knativeベースのサーバレスサービス

#### 代表的なサービス

* [Code Engine](https://cloud.ibm.com/docs/codeengine?topic=codeengine-about)(現在β 英語ドキュメントのみ) ※[β版を試したときの記事](https://qiita.com/motuo/items/b4127ae23ff5dc3ba6a4)
* [Cloud Run (GCP)](https://cloud.google.com/run)

#### pros
* FaaSと同じ様に実際に稼働した分だけ課金される
* コンテナサービスがあれば簡単に動かすことができる
* 好きな言語・フレームワークで稼働させることができる
* サーバレスなので、スケールについても柔軟に対応できる。

#### cons
* FaaSと同じようにステートレスなサービスになる。そのため、Webアプリケーションでセッション管理などを行おうとするとRedisなど外部サービスが必要になる。その結果、思ったほどコストが下がらない、なんてことも:scream:

#### どんな時にオススメ？
* 使い慣れているフレームワークでサーバレスな開発をしたい時。

##### ちなみにCloud Runなら…
* リビジョンごとのトラフィックの割合の変更が簡単にできる。さらに、リビジョン毎にURLが発行できる！(Kubernetesに基づいた機能が簡単に使えるのでβ版リリースなどに簡単に使えて便利！！)

## 最後に
どんな時にでも対応できる万能なプラットフォームは存在しないので、自分のプロダクトに求められる要件を見極めた上でプラットフォームを選定していきましょう！
各ベンダーのクラウドサービスも日々、進化しているので昨日できなかったことが、今日できてるなんてことも…！
うまく使って最適なコストでサービスを運営していきたいな、と思います！