1日1%成長する ~Aws Lambda Part2~

AWSの学習メモ

Aws Lambda Part2

基本
    メモリ
    - 64MBごとに128MB~3008MB
    - メモリ容量に応じてCPU能力なども比例
    - メモリ容量が一定を超えるとコア数増加

    タイムアウト
    - MAX900秒(15分)

プログラムモデルの基本
    ハンドラー
        - エントリポイント
        - パラメータはJson形式

    コンテキスト
        - ランタイムに関する情報が含まれ、ハンドラー内部からアクセス可
        - コンテキストオブジェクトが2つめのパラメータとして渡される
        - コールバックを使用する言語の場合、コールバックメソッドの振る舞いを設定可能

    ロギング
        - AWS CloudWatch Logs
            - CloudWatch Logsの制限があるのでそれに影響される場合もある

    例外
        - 各言語ごと
        - Lambda関数を同期的に呼び出している場合はクライアントへのエラーがレスポンスされる

    - ステートレスで作成
    - 関数はリクエストのたび違うコンピューティングリソースになる可能性がある
    - ローカルファイルシステムへのアクセス等は制限される
    - 永続化にはs3、dynamodbまたはクラウドストレージサービスへ保存

設計図
    - Python、Nodeはサンプルレコード集がある
    - Serverless Application Responsitoryというものがある
        - 作成したサーバレスアプリケーションを公開、共有するための機能
        - 設計図はサービスチームによるメンテナンス、ユーザによる追加登録は不可能

VPC
    VPC内のリソースインターネットを経由せずにアクセス可能
    AZごとに1つ以上のサブネットを指定しておくのがおすすめ
        ※AZ障害発生時やIPアドレス枯渇時にも別のAZでLambda関数を実行可能

    ENIを利用
        - 作成・削除はLambdaが完全コントロール
        - ENIにはサブネットのIPがDHCPで動的に割り当てられる
        - IAM roleにAWSLambdaVPCAccessExecuteRoleというポリシーをアタッチしておく

VPCアクセスの注意
    - 設定したタイミングからインターネットにアクセスできない
    - パブリックIPアドレスは割り当てられない
    - 必要な場合はNATインスタンスを用意 or Amazon VPC Natゲートウェイを利用

ENIまたはサブネットIPが無い場合はリクエストに失敗する
    - 非同期呼び出しの場合はこのエラーはCloudWatch Logに記録されない
    - コンソールで実行するなど、同期実行でエラー応答は取得可能

    ※ENIキャパシティ:Projected peak concurrent executions * (Memory in GB/3GB)

1日1%成長する ~Amazon Elastic Container Service for Kubernetes (Amazon EKS)~

AWSの学習メモ

Amazon Elastic Container Service for Kubernetes (Amazon EKS)

Control plane
    - 永続ストレージ:etcd
    - マスターを選出する機構がある
    - apiserverがマスターとなったetcdにアクセスする
        - Kubernetesマスターにはapiserverに対してトラフィックを流すLoad balancerがある

EKS概要
    - 運用難易度の高いKubernetesをマネージドで
    - K8sの1.12、1.11、1.10
    - K8sパッチバージョ/どのK8sAPIサーバのフラグが有効かなど
    - SLA:99.9%
    - コンプライアンス
        - HIPAA-eligible
        - ISO 9001, 27001, 27017, 27018
        - PCI DSS Level 1
    - 開始
        - preparation
            - クライアントセットアップ
                - kubectlのインストール
                - aws-iam-authenticatorのインストール
            - AWS環境のセットアップ
                - EKSサービスロールの作成
                - EKS用のVPCを作成
        - Create EKS cluster
            - aws eks create-cluster --name ~
                - cli作成

        - Provision worker nodes
            - デプロイ用AWS CloudFormationテンプレートを提供
            - AmazonLinux2のEKS最適化AMIが存在する
        - Launch add-ons
        - Launch workloads

EKSアーキテクチャ
    - Customer VPC
        - EC2 Worker Nodes
        - ENI
    - EKS VPC
        - Network Load Balancer
        - EKS Control Plane

K8s APIサーバエンドポイントへのアクセス
    - WorkNode/kubectlとEKSにより提供されているK8sAPI
    - Endpoint Public Accessを無効化=インターネットアクセス無効
    - Private Accessを有効化
        - enableDnsHostnames
        - enableDnsSupport
設定:kubeconfig
    - aws eks --region xxx update-kubeconfig --name xxx

CNI(CNIプラグイン)
    - 複数のPodはVPC内に存在するようにPod内に同じVPCアドレスを持つ
    - シンプルでセキュアなネットワーク
    - GitHub上で公開されているオープンソース
    - amazon-vpc-cni-k8s

    このプラグインVPCにアドレスを要求して取得し、
    各Podに割り当てる

1日1%成長する ~Amazon Elastic Container Service for Kubernetes (Amazon EKS)~

AWSの学習メモ

Amazon Elastic Container Service for Kubernetes (Amazon EKS)

コンテナ関連サービス
    レジストリ:ECR
    コントロールプレーン:ECS、EKS
    データプレーン:EC2、Fargate

Kubernets(K8s)概要
    - 複数のホスト間でコンテナ化されたアプリケーションを管理するOSS
    - デプロイ、メンテナンス、スケーリングを提供
    - Cloud Native Computing Foundation(CNCF)で管理

Kubernetsで実現できること
    - ホスト管理、スケジューリング
    - コンテナ死活監視、オートリカバリー
    - サービスディスカバリーやロードバランシングで分散処理
    - シークレット(パスワード)やアプリケーション設定管理
    - バッチ実行とか

アーキテクチャ
    Kubectl => k8s master
                - WorkerNode(複数)

    Kubectl
        k8s APIを実行するためのCI
    Workloadsリソース
        - Pod
        - ReplicaSet
        - Deployment
        - DeamonSet
        - Job
        - CronJob
        - StatefuleSet

Pods
    - 作成、スケジュール管理できる最小のデプロイ可能な単位
        - シンプルなユースケースだと1pod=1コンテナとか

    - 同じPod内のコンテナはVolumeやNetworkを共有
    - Pod内のコンテナはlocalhostで通信

ReplicaSet
    - Podのレプリカを作成してPodを指定した数を維持
        - longrun向け
        - WorkerNode障害時には指定されたPodの数を維持するために別のNodeにPod作成を行う

Deployment
    - 複数のReplicaSetを管理「Deployment -> ReplicaSet -> Pod」

DeamonSet
    - 選択したノード組に対して各ノードにPodを1つ動かすためのリソース
        - 1台のWorkderNodeに複数づつPodを配置することはできない
    - ユースケース
        - 各WorkerNodeで動かすログ収集用のdeamon(fluentdなど)
        - 各WorkerNodeで動かすモニタリング用のdeamon

Job
    - 1つ以上のPodを作成し、指定された数のPodが正常に完了するようなコントロール
    - JobとReplicaSetの違い
        - ReplicaSetはロングラン向け
        - Jobは終了が予想されるPod向け

Service/Ingress
    コンテナを公開するときにする

Service
    - Podの論理セットとアクセスするためのポリシーを定義
    - コンテナに対してトラフィックを流すことができる(L4ロードバランサー)
    - ServiceにIPアドレスを割り当てることも可能(バランサっぽい感じ)

Ingress
    - コンテナに対しトラフィックを流すことができる(L7ロードバランサー)
    - AWS ALB Ingressコントローラー:AWSがサポート
        - IngressリソースとしてALBを活用可能
        - ホスト名またはパスによるコンテントベースルーティング、L7の負荷分散

1日1%成長する ~AWS Aurora Mysql~

AWSの学習メモ

    レプリケーション
        Binlogのレプリケーションではない。
        Shared Multi-AZ Storageを使用していて、ここにMasterが書き込む。
            ※master/replicaは同様のデータを使用する
        ReplicaはShared Storageを参照して更新するのだが、
        ここで10~20ms程度の遅延が発生する。
        ただし、Shared Storageに書き込まれてさえいれば
        レプリケーションは機能するのでフェイルオーバーのデータロスはない。

    アダプティブスレッドプール
        RDSだとコネクション数に応じてスケールしない。
        Auroraはアクティブなスレッドにコネクションを集約していく。
        スレッドプール数は動的に調整される。
            -> r3.8xlインスタンスで同時5000まで可能

    フェイルオーバー
        クラッシュリカバリーの処理が常にストレージ側で行われている。
        40sec程度で対応する
    フェイルオーバーテスト
        SQLでノード、ディスク、ネットワーク障害をシュミレート可能
            Alter system crash[{instance|dispatcher|node}]
            Alter system simulate percentage_of_failure ....

            - ディスク障害もシュミレート可能

    - S3へ増分バックアップを継続的に行っている
    - ディスクの仕組みでパフォーマンス影響を与えない
    - ポイントタイムリカバリで5分前からBackup Retention Periodまで秒単位で復元可能

    Global Transaction ID support
        Aurora Mysql2.04以降で対応

    Auroraのバックアップの金額が見えるようになった
    昔は常に最新バージョンだったが今はバージョン指定が可能
    Custom Endpoints
        分析クエリー用、オンラインクエリ用と分けたい場合に利用可能
        ただし、通常のEndpointがあるのでこちらを使ってしまうと全てに振り分けられてしまう。
        そのため、カスタムエンドポイントを設ける

    Global Database
        一部のリージョンで対応。(バージニア北部、オハイオオレゴンアイルランド)
        リージョンをまたいだレプリケーションだが、
        レプリカには書き込みできない
            ※クロスレプリケーションはレプリ先に書き込み可能

    Aurora Serverless
        不可の少ないアプリケーション
        可変不可アプリケーション
        エンドポイントだけアプリから見える状態で、
        request routerが受け付ける。
        受け付けたあとに処理を振り分けるがこのときにinstanceを起動するケースもあるので、
        タイムアウトを1分くらいにしておく。
        また、0からスタート可能なのでリクエスト受付でインスタンス起動させて処理させることも可能。
            ※単純なクエリならコンソールから実行可能

    Perfomance Insights
        パフォーマンスの可視化。
        メモリ量が増えたり、本番に影響が出る可能性もあるため、
        開発やテスト環境など、パフォーマンスチェックのために利用する。

    Backtrack
        データベースの状態を瞬時に特定の時点へ巻き戻す
        一度、オンラインから外してもどす。
        また、ある地点に戻してからすすめることも可能。(DB全体を対象とする)
         ※ポイントタイムリカバリだとスナップショットから戻すなど時間がかかっていた
        チェンジレコードにつき$0.014なので直近のオペミスによる切り戻しなどで利用する

    Database cloning
        ストレージコストを増やすことなく、データベースをコピー可能。
        変更すると課金される。
        ユースケースだと本番のデータでのみ障害が起こるなど、
        プロダクションデータでのテストが必要な場合に利用可能。

    Lab modeに新しい機能をだしていく(ただし、実験バージョンなのであくまで確認用)

1日1%成長する ~AWS API gateway~

AWSの学習メモ

AWS API gateway

REST API
    リソースとメソッド
        「/」を最上位としたツリー構造にて「リソース」を定義
        各リソースに受け付けるHTTPメソッドを指定(パスパラメータの利用も可能)

    リソース:/
        リソース:/pets
            GET
            リソース:/{petId}
                GET、PUT、POST、HEAD
        リソース:/echo
            ANY

WebSocket API

    Websocket URL:wss://
    Callback URL:https://

    事前定義:$connect、$disconnect、$default

    メッセージデータ
    {
        "action": "join"
    }
        -> $request.body.action -> action:joinへ

その他の主要機能
    APIの認証認可
        AWS署名v4
            AWS SDKAPIクライアントSDkを利用
                -> 認証したプリンシパルのIAMポリシー上、
                  このAPI呼び出しを行う権限が認可
        Lambdaオーソライザー
            Bearerトークン or パラメータ付リクエスト
                -> Lambda認証関数がポリシー&プリンシパルIDを返却
        Cognitoオーソライザー
            ユーザプールで認証を行う取得したトークンをHTTPヘッダーに指定
                -> トークン検証

    統合タイプ
        Lambda関数
        HTTP
            public ipがあればAWSもしくはオンプレでもOK
        Mock
            固定の値を応答
        AWSサービス
        VPCリンク
            NLBを参照する「VPCリンク」を登録しそれを経由してVPC内リソースへアクセス

リクエスト/レスポンス変換
    - VTL(Velocity Template Language)とJSONPathや予約変数($input等)を利用し記述
    - リクエストやレスポンスのデータを別の形式に変換することが可能

APIキーと使用量プラン
    APIのメータリングとスロットリングを実現
        しきい値を超えるとHTTPステータスコード429(too many request)
        APIキーを「認証」目的にりようしないこと
            -> 計測のための識別用途のためのものだから

1日1%成長する ~Amazon API Gateway~

AWSの学習メモ

AWS API Gateway

API=Application Programming Interface
    => AWS APIGateway = Web API

2005年からWebApiを作成するトレンドは好調
    => なぜ?
    => 集中型から分散コンピューティングの流れがあるのかもしれない

ポイント
    - インフラ管理(可用性やスケーラビリティ)
    - APIの管理(設定やデプロイの制御)
    - 認証と認可(アクセスの制御)
    - 流量制御と保護(スロットリング)-ddosを防ぐとか

全体像
    API Gatewayは玄関口にあたる
    - インターネット
    - 自社企業・企業グループ内でのプライベートなWebAPI
    - AWSサービス例(Amazon DynamoDB等)を独自のWeb API化
    - サーバレスアーキテクチャを実現する手段

    自動スケール、管理不要、従量課金

扱うAPI
    - REST
        - ステートレス
        - 単一HTTPメッセージで1つの操作に関する情報を含む
        - 扱う情報をURIで表現する「リソース」として定義
    - WebSocket
        - ステートフル
        - HTTPの上でクライアントとサーバの間の双方向通信を実現する
        - 1つのコネクションで継続的なデータ送受信が可能
        - URIスキームはセキュアWebSocket用のwss://

RESTのエンドポイント
    - エッジ最適化
        - 一旦エッジロケーションにルーティング
    - リージョン
        - リージョンに直接ルーティング
        - リクエスト元が同一リージョンの場合はレイテンシ削減
        - CloudFrontと組み合わせ可
    - プライベート
        - publicからのアクセスはできず、
         VPC内からAWS PrivateLink = VPCエンドポイント経由でアクセス

ステージ:個別の環境セット
    エンドポイントのURLが異なる
    prod:https://~.execute-api..amazonaws.com/prod/xxxx
    staging:~staging/xxx
    dev:~dev/xxx

API作成
    「既存APIのクローン」or「Swagger(OpenAPI)ファイルインポート」
    Swaggerに関してx-amazon-apigateway-*でAPIgatewayの設定が指定可能
        => エクスポートも可能

1日1%成長する ~AWS Lambda3~

AWSの学習メモ

AWS Lambda3

コールドスタート
    1. 関数コードのダウンロード
    2. 新しいコンテナ開始
    3. runtimeの起動
ウォームスタート
    1. 関数コードの実行


コールドスタートの一部をX-Rayで確かめられる
    initialization部分がランタイム初期化時間
        -> ここがコールドスタートにあたる
        -> 2回目からなくなる(ウォームスタートした場合)
    invocation部分が関数コード実行

    VPCにアクセスできる形にするとX−Ray上で分類されない部分で時間がかかる
    initializationの前に時間がかかる。
        -> ウォームスタート時はもう作成済なので関数コード実行になる

コールスタートを早くするには?
    - コンピューティングリソースを増やす
        - メモリしか設定できない(メモリサイズでCPUも決まる)
            - メモリを上げることで早く終るケースもあるので上げてしまうのも有り
            - 一番減らし引き上げていき処理時間が変わらないところまで引き上げるなど
        - 
    - ランタイムを変える(JVMとか遅いから)
        - 一度温まるとコンパイル言語のほうが早い
    - パッケージサイズを小さくする
        - サイズが大きくなるとコールドスタート時のコードダウンロード時間がかかる
        - 依存関係を減らす、不要なモジュールは含めない
        - コード最適化ツールを使って(難読化ツール)で減らす
    - VPCは必要でない限り使用しない
        - どうしてもVPC内リソースにアクセスする必要がある場合
        - RDSとか
        - Amazon Elasticsesarch ServiceはIAMでアクセス制御できるのでパブリックもあり
        - VPCアクセスを有効すると10~30秒かかる

関数コード
    - コードの最適化 => 各言語のベストプラクティスや最適化手法
    - Fatでモノリシックな関数にならないようにする
        - 1つの関数はなるべく単機能
        - 関数内でのオーケストレーションは禁物
    - ハンドラとコアロジックは分離させる
        - ビジネスロジックは単体できる
コンテナ再利用
    - グローバルスコープを活用
        - ウォームスタート時に有効になっているため
        - def handler以下は毎回実行させる

必要なものだけ読み込む
     response = s3_client.get_object(...)
     response = s3_client.select_object_content(
        expression="SELECT SUBSTR(obj._1, 1, 8), obj._2 FROM s3object as obj"
     )
     - まるまるとるのと絞って取り込むのとでは費用が異なる

コード内ではオーケストレーションしない
    - Fatでモノリシックな関数はつくらない
    - タイムアウトを起こしやす
        -> Step Functionsを利用する