Serverless Frameworkことはじめ
Serverless Applicationを構成管理デプロイするためのツール。
興味のきっかけ
上記の記事を読んで、コスト削減削減が見込めるうという点でサーバレスに興味を持った。
そもそもサーバーレスって
以下の記事の言葉を借ります^^。
メリットデメリットに関しては、この記事も参考
簡潔にいうと、「常時起動しているサーバーを使わずにアーキテクチャ(仕組み)が実現できている状態」というニュアンスが近いです。 メリットとしては、常時起動サーバーがなくなり、以下のサーバーあるあるの問題がなくなることです。
サーバーのリソースを意識しない(サーバーの管理・運用が不要)という意味でサーバーレス
サーバーレスのメリット
- コスト減
- サーバーの管理を意識しなくてもいい
- Lambdaであればamazonがソフトウェア・セキュリティを設定したり・ハードウェアを管理してくれる
- ビジネスロジックに集中
- インフラ設計に頭を悩ませないで済む(勝手にスケールしてくれる)
- 負荷分散やオートスケーリングの設定
サーバーレスのデメリット
- まだまだ一般的な運用方法とはいえない
- 誰がやんのか
- ベンダーに依存する
- ベンダーロックインとなり、クラウドベンダーが異なれば、機能性や実装方法も大きく異なる
- 例えばAWSからGCPへの移行する場合など
- 監視が難しい場合がある
-
サーバーレスでは、幾つものサービスが連動するので、一般のアプリケーションよりモニタリングなどが複雑となります。そして、ランタイムの大半がクラウドの内部に隠れているので問題の解析が簡単ではありません。
-
- ランタイムの大部分がクラウド内部に隠蔽されているため、問題解析が難しくなる
- コールドスタート問題
コールドスタート問題について補足。。。
例えば「Lambda」 が「Lambda 関数」の実行をする際、「Amazon Linux」が動作するコンテナが使用されます。この環境を「実行コンテキスト」といいます。
この「実行コンテキスト」の起動から行うことをコールドスタートといい、立ち上げる際に多少の待ち時間が生じます。そのため、低レイテンシーを求める場合「Lambda」は向きません。
コールドスタートが許容できない場合、使うべきじゃない
安定的にリクエストが来ているならば、コールドスタートはほとんど発生しない
対策は、、、
- ウォームアップ
- 定期的にリクエストを送って、Lambda関数を実行させておくこと
- データ更新が不整合になったりしないかなどの考慮が必要
- インスタンスが寝るまでの時間は決まってないので、あくまでコールドスタートの確率を下げるための対応
- Provisioned Concurrency
- Lambdaの同時実行数を事前にプロビジョニングする
- 金がかかる
- AWSはこっち推してるらしい(参考)
Serverless Frameworkとは
Serverlessはサーバーレスなアプリケーションを簡単に開発、デプロイするためのNode.js製のツールです。
AWS、Azure、GCP等のクラウドサービスによらず利用することができ、ランタイムの言語もクラウドサービス側で許されているものであれば利用することができます。(フォースタはAWSを利用しているため、この記事ではAWSを例に説明します。)
デプロイコマンドを実行すると、各クラウドサービスのリソース構築処理が実行されます。AWSを例に挙げると、デプロイコマンド実行時にCloudFormationのテンプレートが作成され、Lambdaおよびその他必要なリソースが作成されます。
メリット
- インフラのコード化ができる
- サーバーレスアーキテクチャの管理・構築が楽になる
- デプロイがコマンド一発
- プラグインで楽できる
- サーバーレスアプリケーション構築の幅を広げてくれるプラグインが1000以上
デメリット
- デプロイに時間かかるので、慣れてるんだったら手作業でやった方が構築が早い場合がある
- ローカルでの関数実行の起動が遅い
説明とかデモとか
初期設定まで
serverlessの管理画面のアカウント設定が必要。それ済ませた前提。
$ npm install -g serverless
$ serverless
(node:2285) ExperimentalWarning: The fs.promises API is experimental
(node:2285) ExperimentalWarning: The dns.promises API is experimental
Serverless: No project detected. Do you want to create a new one? Yes
Serverless: What do you want to make? AWS Node.js
Serverless: What do you want to call this project? FollowerTracking
Project successfully created in 'FollowerTracking' folder.
You can monitor, troubleshoot, and test your new service with a free Serverless account.
Serverless: Would you like to enable this? Yes
You are not logged in or you do not have a Serverless account.
Serverless: Do you want to login or register? register
Serverless: email: hogehoge@gmail.com
Serverless: password: [hidden]
Successfully registered your new account
Your project is setup for monitoring, troubleshooting and testing
Serverless: Would you like the Framework to update automatically? Yes
Auto updates were succesfully turned on.
You may turn off at any time with "serverless config --no-autoupdate"
Serverless: Would you like to setup a command line <tab> completion? Yes
Serverless: Which Shell do you use ? bash
Serverless: We will install completion to ~/.bashrc, is it ok ? Yes
Command line <tab> completion was successfully setup. Make sure to reload your SHELL.
You may uninstall it by running: serverless config tabcompletion uninstall
Deploy your project and monitor, troubleshoot and test it:
- Run “serverless deploy” to deploy your service.
- Run “serverless dashboard” to view the dashboard.
$ ll
total 0
drwxr-xr-x 5 shlia staff 160 5 2 20:30 FollowerTracking
上記で、初期のプロジェクトが作成された。
インストールは公式のここから
オプションの意味はこちらで確認
service: followertracking
app: followertracking-app
org: hogehoge
frameworkVersion: '2'
provider:
name: aws
runtime: nodejs12.x
lambdaHashingVersion: 20201221
functions:
hello:
handler: handler.hello
以下でローカルでの実行ができちゃう。
serverless invoke local --function hello
デプロイするためには、プロバイダーアカウントのセットアップが必要、
今回はAWSのアカウント。administorator権限のIAMを作成してAWS CLiのセットアップをする。
んで、serverless deploy
したらもうデプロイできてる。
layerのデプロイ
slsプロジェクトの配下でsls plugin install --name serverless-layers
をうった。
S3のバケットを作成する。
serverless.ymlに以下を追加。
package.jsonをみて。勝手にデプロイしてくれる。
custom:
serverless-layers:
layersDeploymentBucket: ${env:LAYER_BUCKET}
参考記事
この記事にかなり頼った。
API Gatewayの設定
DynamoDBのymlの設定はここから。
API Gatewayのcorsの設定
補足
Terraformとの使い分け
今はDockerで Lambdaイメージがある。
Terraformでデプロイ、Dockerで開発環境も似たようなことができはする。
Conclusion
Terraform is best suited for managing more persistent shared infrastructure, while Serverless is a good fit to manage the application-specific infrastructure.
結論
Terraformは、より永続的な共有インフラストラクチャの管理に最適ですが、サーバーレスは、アプリケーション固有のインフラストラクチャの管理に適しています。
サーバーレスフレームワークは、Cloudformationテンプレートを生成するための中間層であり、主にサーバーレス関連のリソース用であり、awsでは、ラムダ、APIゲートウェイ、dynamodbなどに焦点を当てています。
すべてをCloudformationテンプレートに直接書き込むことができますが、テンプレートファイルは巨大になり、JSON /Yamlテンプレートでも維持するのは困難です。 serverless.yml に数十行あるサーバーレスフレームワークは、数千行または数千行のクラウドフォーメーションテンプレートを生成できます。クラウドフォーメーションコーディングを処理するために多くの時間を節約できます。ちなみに、cloudformation構文を既に知っている場合は、同じcloudformationyamlコードをresources 部分に直接簡単に配置でき、サーバーレステンプレートはそれらの作成方法を知っています。
Terraformコードを記述して、ラムダ、APIゲートウェイ、Dynamodbも管理できます。 Cloudformationテンプレートよりも少ないコードを取得できるかもしれませんが、それでも複雑すぎます。
別の方法では、サーバーレスフレームワークにすべてのAWSリソースを処理させることは意味がありません。これは、EC2、VPC、ECSなどの他のツールがすでに最もうまく機能していることです。
要は、Lambda、API Gateway、DynamoDBの設定が楽にできるということ。
LambdaとRDSの相性が悪いってのは過去の話
RDSプロキシの登場
DynamoDBのテーブル設計について
スキーマレス、非正規のため。RDSのテーブル設定とは全然違う。ので改めて勉強しなくちゃいけない。テーブルは一個なのが優れた設計とのこと。
以下ではあんまり使わない方がいい
- リレーションを重要としデータ整合性保証をしなければならないケース
- 強い整合性を持った読み込みを常に必要とされるケース( 読み込み時に書き込みされていることを常に保証しなければいけないケース )
以下では使うのもあり
- 安くしたい
- ゲームなどのカラム増減が激しいプロダクト
- リーンスタートアップなどでデータ構造がバシバシ変わるようなプロダクトケース
設計のために考慮すること
- パーティションキーによる完全一致と、パーティションキーとソートキーの組み合わせでしか効率良い絞り込みが行えません。
- GSIを使えば割と自由度の高い検索も可能ではある(https://qiita.com/uenohara/items/c52c2eef991fd6c8a405)
- 多対多の設計(https://hack-le.com/dynamodb-many-to-many/)
- 設計をする前に、まずクエリパターンを弾き出す。そこからじゃないと作ってはいけない
チュートリアル
参考
Discussion