LoginSignup
13
8

More than 3 years have passed since last update.

serverlessとLambda

Last updated at Posted at 2020-04-01
1 / 37

serverlessとLambda


話すこと

  • lambdaでできること
  • serverless frameworkでできること

Lambdaのusecase

  • web application
  • 定期的なtask処理
  • Event処理

Faas

  • Function as a serviceの略
  • AWS Lambdaが一番有名なFaasだが他にもいっぱいある
    • cloud functions(GCP)
    • Azure Functions(microsoft)

Lambdaで使用可能な言語


Lambdaの主な制限

  • package size
    • 250MB(Layer含む)
    • 50MB(Layer含まない)
  • functionのtimeout
    • 900秒(15分)
  • accountごとの同時実行数
    • 1000

アーキテクチャ設計における優先順位(推奨)

  1. LambdaでできることはLambda(faas)でやる
  2. Lambdaでできない(もしくは難しい)なら、ECSやsagemakerなどmanagedなコンテナ技術を使う
  3. それでも難しい場合はec2を選択

Common problems

  • package sizeが大きくなってしまい50MBに収まらない
    • numpyやpandasのようなpackageを使う際によく起きる
    • 後述のlayerである程度解決
  • 一つのfunctionで同時実行数を専有してしまい、他のfunctionが動かない
  • cross compile問題
    • macでinstallしたpackageをそのままdeployしても動かない
    • lambdaが動作しているamazon linux用のbuildが必要

LambdaのCost

  • request
    • 1000000件/0.20 USD で、無料利用枠は 1 か月に1000000
  • compute
    • 1GB-秒につき 0.00001667 USD で、無料利用枠は 400000GB-秒
    • 1GBのmemoryなら400000/86400=4.62962963なので4-5日間は絶えず処理していても無料

Lambda layer

  • 2018年のre:inventで発表された機能
  • lambda functionを機能単位でlayerに切り出せる
  • これまであったfat moduleの容量問題はこれで解決
  • 1 functionにつけられるlayerは5まで

Layer前

slidescreenshot.jpeg


Layer後

slidescreenshot.jpeg


Frameworkがやってくれること

  • faasのorchestration
  • faasといっても、functionだけでsystemが成立することはほぼありえない
  • web applicationでもendpointだったりstorageだったりが必要になる

各種Framework

  • AWS SAM
  • zappa
  • Apex
  • serverless framework

AWS SAM

  • AWSが公式で提供しているFramework
  • Serverless Application Model
  • iaasにおけるterraformとcloudformationの関係性に近い

zappa

  • aws で serverless python web serviceを実現するflaskベースのOSSフレームワーク
  • apigateway + LambdaのよくあるパターンをFlaskで書く
  • GCPは対応していない
  • 事例があんま多くなさそう

Apex

  • Lambdaのorchestration tool
  • 面白い機能として、terraform integrationがある
    • apex infra applyでterraformを実行できる
  • 事例があんま多くなさそう
  • No longer maintainedと書いてありもう長くなさそう、、

serverless framework


serverless frameworkのいいところ

  • コミュニティが強力
    • ググれば情報がたくさん出てくる
  • pluginが多数あり、大抵のことはpluginを使えば実現できる
    • いざというときは自分でpluginを作ればいい
    • serverlessはnode製なのでnodeで実装
  • eventから処理までがseamlessに書ける
  • lambda+api gatewayというよくある組み合わせを爆速で作れる

get start

$ npm install -g serverless
$ sls create -t aws-python3

serverless frameworkのyamlに書けること

  • provider
    • 環境変数
    • iam role
  • cloudformationのstack
  • custom
  • layer
  • function

provider

provider:
  name: aws
  runtime: python3.7
  stage: ${opt:stage, self:custom.defaultStage}
  environment: ${file(config/environments/${self:provider.stage}.yml)}
  region: ${self:provider.environment.REGION}
  timeout: ${self:provider.environment.TIMEOUT, "120"}
  memorySize: ${self:provider.environment.MEMORY_SIZE, "256"}
  # bucketの設定だが、serverSideEncryptionはserverless-deployment-bucketが必要
  deploymentBucket:
    name: ${self:provider.stage}-${self:service}-deployment
    serverSideEncryption: AES256
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "iam:ListAccountAliases"
      Resource: "*"

function

  • 呼び出す関数とその発火するeventを定義
  • eventから処理までseamlessに書ける

function

# spotのeventを処理する
ec2_spot:
  handler: handlers/main.spot_notify
  events:
    - cloudwatchEvent:
        event:
          source:
            - "aws.ec2"
          detail-type:
            - "EC2 Spot Instance Interruption Warning"

# 定期的に処理する
cost_service:
  handler: handlers/main.cost_notify
  events:
    - schedule: "cron(0 0 2 * ? *)"

function


def spot_notify(event, context):
    instance_id = event.get("detail").get("instance-id")
    ...
    return


def cost_notify(event, context):
    ...
    return
  • eventの中にserviceから送信される情報が入っている

ここまで書くとlocalで関数をdebug実行可能

$ sls invoke local --function ${関数名} -d '${callbackされるjson}'
  • 静的言語だとできない模様(javaとか)

custom

  • yaml内で使う変数の定義
    • ${self:custom.XXXXX}でyaml内で参照できる
  • pluginの設定

custom

custom:
  defaultStage: dev
  pythonRequirements:
    ...
  localstack:
    ...
  rust:
    ...


Layer

layers:
  lib:
    name: ${self:service}-lib-lambda-layer-${self:provider.stage}
    path: layers/lib
    package:
      exclude:
        - 'python/lib/__pycache__/**'

func_a:
  handler: handlers/hoge.func_a
  layers:
      # ↑で独自で作ったlayer
    - {Ref: LibLambdaLayer}
      # serverless-python-requirementsが自動で作ってくれるlayer
    - {Ref: PythonRequirementsLambdaLayer}
  ...

鉄板のplugin

  • serverless-python-requirements
    • pipの管理をうまくやってくれる
    • requirements.txtからzipを生成してくれたり
    • pipenvにも対応している
    • layer化すると便利(packageを共通化できる)
  • serverless-offline
    • apigateway+lambdaに類似したセットをlocalで実行できる
  • serverless-iam-roles-per-function
    • lambda関数ごとに権限を分離できる

その他の使ってるplugin

  • serverless-deployment-bucket
    • deployに必要なbucketの暗号化
  • serverless-rust
    • serverlessでrustのcodeをbuild, deployしてくれる
  • serverless-localstack
    • localstack(仮想aws)を使ったtestを実行

web apiを作る際の組み合わせ例


awsgiとflaskでweb api(yaml)

functions:
  flask:
    handler: handlers/flask.handler
    events:
      - http:
          path: /{any+}
          method: ANY

awsgiとflaskでweb api(コード)

import awsgi
from flask import (
    Flask,
    jsonify,
)

app = Flask(__name__)


@app.route('/index')
def index():
    return jsonify(status=200, message='OK')

@app.route('/submit', methods=['POST'])
def submit():
    return request.get_data()

def handler(event, context):
    return awsgi.response(app, event, context)

awsgiとflaskでweb api

  • ANYにすることで、許可するpathやmethodをApplication側でハンドリングできる
  • Lambda関数を量産する必要がない
  • local開発ではserverless-offlineを使えばapi gatewayのendpointをlocalで起動できる
  • RestのAPIを作る場合はこれが一番ラクだと思う
    • もちろんgraphqlも使える
plugins:
  - serverless-python-requirements
  - serverless-offline
  ...

時間があったらdemoします

13
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
8