AWS EC2(3)AMIとインスタンス

AMI

AMI(Amazon Machine Image)は、EC2インスタンスの起動に必要な情報を提供するイメージファイルで、

  • OSやアプリケーションなどのルートボリュームのテンプレート
  • 起動を許可するAWSアカウント
  • インスタンスにアタッチするボリュームのマッピング

などの情報が含まれている。

AMIは、AWSや様々な組織が公開しており、これを利用することができる。特にAmazon Linuxは、AWSが提供しているRHEL系のAMIで、AWS CLI Amazon EC2 API 等がパッケージに含まれているため便利で使い勝手が良い。また、自身が作成したインスタンスから生成したAMI(カスタムAMI)を登録/利用することもできる

なお、AMIは同一リージョン内や別のリージョンにコピーを作成することや、他のAWSアカウントとイメージを共有することが可能である。別リージョンにバックアップシステムを構築する場合、AMIのコピーはシステム構築の有用な手段となる。AMIの共有は、公開範囲をパブリックに指定するか、「イメージパーミッションの変更」設定から、許可するAWSアカウントの追加を行う。他者が公開しているAMIを利用する際は、機密データが第3者に送信されていないかや、認証情報が事前に設定されていないかなどを十分に検証する必要がある。

リージョンをまたがるコピー

作成したAMIを別リージョンで使用する際は、AWS CLIのリージョン設定やプログラムのデフォルトリージョン設定をハードコーディングせずに、シェルスクリプト等で変更できるようにしておくと良い。自身のリージョン情報を取得するには、AWS CLIから以下のコマンドを入力する。

 $ curl -s https://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//g' 

AMIの作成

既存のインスタンス、もしくはスナップショットからAMIを作成することが可能である。AMIの作成は、インスタンス上のすべての動作を停止し、作成プロセス中に一貫した状態が保たれるようにするために、インスタンスをシャットダウンしてから行う。自身で作成したAMIを共有する場合は、以下のように、共有キーやコマンド履歴の削除等の対策を行う。

$ sudo shred -u /etc/ssh/*_key /etc/ssh/*_key.pub
$ shred -u ~/.*history
$ history -c
$ exit

インスタンスからの Linux AMI の作成

ストレージ

ストレージは以下の2種類が存在する。どちらのデバイスから起動させるか選択することも可能であるが、高速で永続的なEBS-basedの起動方法が奨励されている。

Instance Store

  • EC2と不可分の内蔵ディスクで、EC2をTERMINATEするとクリアされる。ただし、再起動ではクリアされない
  • インスタンス停止(STOP)することができない。
  • 無料

instance store-backed のインスタンス

Elastic Block Store

  • ネットワークで接続されたディスクで、EC2とは独立しており、別途課金される。同じアベイラビリティゾーン内でレプリケーションされるため、高い可用性を有している。
  • デフォルトでは、DeleteOnTermination フラグが true に設定されているので、TERMINATEすると消去されてしまうことに注意が必要である。消去されたボリュームは、ゼロで上書きされて他のアカウントで使用される。機密データを有している場合は、暗号化の検討が必要である。
  • スナップショットを取ることが可能である。スナップショットは、過去のスナップショットとの差分として記録される。スナップショットを取得する際には、EBSをアンマウントすることが望ましい。一方で、スナップショットが開始されれば、スナップショット取得処理中であってもEBSをアタッチして使用して問題ない
  • インスタンスとEBSボリュームはネットワーク経由で接続されているため、他の通信の影響を受ける。EBS最適化インスタンスを利用することで、インスタンスとEBSとの間のスループットが保証され、他の通信の影響を受けない。

Amazon EBS-backed インスタンス

容量と性能

汎用SSD(gp2)のパフォーマンスは、ボリュームサイズに比例する。つまり、小さい容量のEBSの場合は、I/O性能も低い。したがって、高頻度のI/Oが発生する可能性があるアプリケーションが動作する場合などは、使用する容量が低くても、I/Oの性能を向上させるために、大きな容量を設定しておく必要がある。

各ボリュームは、最初に540万I/Oクレジットを受け取り、標準性能を超えたI/O処理(バースト)は、このクレジットから消費されていく。一方、標準性能を下回るI/Oであった場合はクレジットに加算されていく。ただし、加算できるクレジットは、初期値と同じ540万I/Oクレジットまで。クレジットが枯渇するとバースト性能を利用できなくなり、標準性能で頭打ちとなる。なお、汎用SSD(gp2)は、

  • 容量が33.4GB以下であれば、標準性能100IOPS
  • 容量が1000GB以下であれば、3000IOPSのバースト性能を利用可能
  • 容量が3333GBに標準性能10000IOPSに達して、容量16TBまでこの性能を維持

と定義されている。また、スループットは、170GB以下では128 MB/秒170GBを超えると160MB/秒である。

インスタンス

概要

  • EC2は、1500MTUに加えてジャンボフレームをサポートする。
  • ルートデバイスがEBSの場合は、インスタンスタイプを変更することが可能である。このときインスタンスIDは変更されない。パブリックアドレスは変更される。インスタンスタイプを変更する場合は、インスタンスを一度停止する必要がある。

インスタンスのライフサイクル

インスタンスは、以下のライフサイクルで動作する。インスタンスがStopのときは課金されない。ただし、EBSボリュームに対する課金は継続される。時期やタイミングによっては、EC2のリソースが枯渇し新たなインスタンスが起動できない場合もあるので、リソースを確保しておきたい場合は、インスタンスを作成し、使用するまで停止しておくとよい。

インスタンスのライフサイクル

インスタンスを再起動した場合は、同一ハードウェアで起動し、ボリュームやネットワーク設定等は前回起動の情報を保持する。一方、インスタンスを一度停止し起動した場合は、別のハードウェアで起動し、これらの情報は引き継がれない。ハードウェア障害が発生した場合など、明示的に別のハードウェアでインスタンスを起動する必要がある場合には、再起動ではなく停止と開始を行う

インスタンスの公開鍵

EC2に使用するSSHキーペアは、リージョンごとに別管理であるため、他のリージョンでEC2を使用する場合、通常は別途新たにキーペアを作成する必要がある。ただし、これでは管理する際に問題が生じるので、共通のキーペアで運用すると良い。手元の秘密鍵から公開鍵を生成し、AWSマネージメントコンソールから登録を行う。

キーペアのインポート

インスタンスの時刻

デフォルトでは UTC(協定世界時間)時間帯に設定されている。他のタイムゾーンを設定する場合は、起動時に以下を実行する。

vi /etc/rc.local
ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

インスタンスの復旧

ハードウェア障害が発生した場合に、自動的に再起動を行うことが可能なCloudWatchアラームを作成することができる。復旧したインスタンスは、ボリュームやネットワーク設定等は前回起動の情報を保持する。自動復旧は、1インスタンスにつき1日3回までである。

また、AWSがインスタンスの再起動や停止/開始、メンテナンスを事前に予告して実施する場合がある。再起動には、自身でスケジューリング可能なインスタンスリブートと、強制的に再起動されてしまうシステムリブートがある。また、ネットワークや電源のメンテナンスが実施される場合もある。

インスタンスメタデータ

実行中のインスタンスのメタデータは、以下のURLから取得することが可能である。AMIのIDや、ホスト名、リージョン、ネットワーク設定、セキュリティグループ名などを取得することができる。

https://169.254.169.254/latest/meta-data/

AWS CLI(1)初期設定とコマンド例

初期設定とリージョンの設定

AWS CLIは、AWSのサービスをコマンドラインインタフェースで操作することのできるコマンド群である。AWS CLIを使う前に、aws configureコマンドを使ってアクセスキーやデフォルトリージョンの設定を行っておく。

$ aws configure
AWS Access Key ID [None]: 
AWS Secret Access Key [None]: 
Default region name [None]: 
Default output format [None]: 

Access Keyは、IAMで設定取得したものを指定する。Default output formatには、通常はjsonを指定する。またこれらの設定情報は、ホームディレクトリ直下の.awsディレクトリ(~/.aws/config, ~/.aws/credentials)に保存される。

なおデフォルトリージョンを設定しない場合は、各コマンドにリージョンオプション(–region ap-northeast-1など)を付けることでリージョンを指定することが可能である。EC2で自作のAMIを作成し複数のリージョンで運用する場合などは、デフォルトリージョンを指定せずに、シェルスクリプト等で都度リージョンを指定する方が設定を変更せずに汎用的に使うことが可能である。

現在のリージョンを取得する

以下のコマンドを実行することで、EC2で現在のリージョンを取得することが可能である。

$ curl -s https://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//g'

上記コマンドを用いることで、シェルスクリプトから動的にリージョンを指定することも可能である。

region=`curl -s https://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//g'`
aws dynamodb scan --table-name TABLE_NAME --region ${region} > /tmp/TABLE_NAME.json

コマンド例

s3 – AWS CLI Command Reference

S3にファイルをコピーする

aws s3 cp /SRC_DIR/FILE_NAME s3://BUCKET_NAME/DIR

バケットを生成する

aws s3 mb s3://BUCKET_NAME

dynamodb – AWS CLI Command Reference

テーブルを作成する

aws dynamodb create-table --table-name TABLE_NAME --attribute-definitions AttributeName=ATTR_NAME,AttributeType=ATTR_TYPE --key-schema AttributeName=ATTR_NAME,KeyType=HASH --provisioned-throughput ReadCapacityUnits=NUM,WriteCapacityUnits=NUM

アイテムを書き込む

  • Number型の場合でも「””」で値を囲む必要がある
aws dynamodb put-item --table-name TABLE_NAME --item '{"ATTR_NAME": {"ATTR_TYPE": "ATTR_VAL"}, "ATTR_NAME": {"ATTR_TYPE": "ATTR_VAL"}}'

指定したテーブルをスキャンする

aws dynamodb scan --table-name TABLE_NAME

kinesis – AWS CLI Command Reference

ストリームを生成する

aws kinesis create-stream --stream-name STREAM_NAME --shard-count N 

ストリーム保持期間を変更する

  • Kinesis Recordは、通常24時間でデータが消去されてしまう。AWS CLIからこの保持期間を最大7日間(168時間)まで延長することができる
aws kinesis increase-stream-retention-period  --stream-name STREAM_NAME --retention-period-hours 168

ストリームの設定内容を確認する

aws kinesis describe-stream --stream-name STREAM_NAME

シャードイテレータを取得する

SHARD_IDは、上述のdescribe-streamコマンドから取得する

aws kinesis get-shard-iterator --shard-id SHARD_ID --shard-iterator-type TRIM_HORIZON --stream-name STREAM_NAME

レコードを取得する

SHARD_ITERATORは、上述のget-shard-iteratorコマンドから取得する

aws kinesis get-records --shard-iterator SHARD_ITERATOR

AWS EC2(1)EC2の概要

EC2(Elastic Compute Cloud)とは

EC2は、クラウド内で規模の変更が可能なコンピュータ処理能力を提供するウェブサービス。様々な種類の仮想サーバを起動し、Webコンソールやターミナルから操作することが可能である。

リージョンとアベイラビリティーゾーン

東京リージョンは、コード名:ap-northeast-1、名称:アジアパシフィック(東京)である。AWS SDK for Javaなどは、デフォルトのリージョンがバージニア州(us-east-1)に指定されていることに注意が必要である。すべてのインスタンスを 1 か所でホストしている場合、同じ場所にあるインスタンスすべてに影響する障害が起きたときに、インスタンスがすべて利用できなくなるため、複数のアベイラビリティゾーンにインスタンスを分散配置することが望ましい。

インスタンスを起動するときは、同じリージョン内にある AMI を選択する必要がある。AMI が別のリージョンにある場合は、これから使用するリージョンに AMI をコピーできる。異なるアベイラビリティゾーンにインスタンスを移行したい場合は、AMIを作成し、このAMIを用いて希望するアベイラビリティゾーンにインスタンスを生成する。

アベイラビリティーゾーンは、各アカウントの識別子に個別にマッピングされる。つまり、アカウントAのap-northeast-1aと、アカウントBのap-northeast-1aは、同じアベイラビリティゾーンを指していない場合がある。また、各アカウントごとに指定できるアベイラビリティゾーンの使用が制限され、アカウントによってリージョン内で使用できるアベイラビリティーゾーンの数が異なる場合がある。

リージョンとアベイラビリティーゾーンに関する概念

インスタンスファミリー

利用用途に合わせて様々なインスタンスの種類が存在する。

カテゴリ 名称 特徴/用途
汎用 M4 通常用途
バーストパフォーマンス T2 普段は殆ど負荷がないが一時的に負荷がある 開発機、小規模システム
コンピューティング最適化 C4 CPU性能が必要な用途 APサーバ、画像処理
メモリ最適化 R3 コアあたりのメモリが大きく大量のメモリが必要な用途 DBサーバ
ストレージIO最適化 I2 高速なIOPSを実現するSSDを内蔵 DBサーバ、ビッグデータ
ストレージ密度最適化 D2 大容量HDDを内蔵 DBサーバ、ビッグデータ
GPUインスタンス G2 GPUコアが必要な用途 グラフィック表示、画像処理

IP

  • Elastic IP
    • 明示的に割り当てられたIP。使用していないと課金される
  • Public IP
    • ランダムに割り当てられるPublic IP
    • EC2をStop/Startすると別のIPが割り当てられる
  • Private IP
    • 必ず割り当てられるIP
    • EC2をStop/Startしても同じIPが割り当てられる

Amazon Linux

デフォルトユーザはec2-user、sudo権限が付与されている。

AWS Kinesis(1)Kinesisの概要

Kinesisとは

Kinesisは、大量のデータを受け付けて配信先に順序通りに配信するバッファ機構である。Kinesisを利用することで高速かつ継続的にデータの取り込みと集約を行うことが可能であり、ログデータやセンサーデータなどの継続的に入力されるストリームの処理に適している。Kinesisにデータが入力されて取得できるようになるまでは1秒未満である。瞬時に処理を実行することが可能である。各クライアントから直接S3やDynamoDB, RDS等にデータ入力するのと比べ、より信頼性が高く安価なシステム構築が可能である。なお、データレコードは通常はストリームに追加されてから24 時間のみアクセス可能(オプションを使用すれば、最大168時間までアクセス可能)である。

Amazon Kinesis の主要なコンセプト - Amazon Kinesis

Kinesisに入力されたデータは、 Amazon Kinesis Client Library を用いたプログラム( Amazon Kinesis Application)をEC2上で動作させることで、加工や抽出・他のデータベースへの転送を行うことができる。Amazon Kinesis Applicationは、 DynamoDB上に制御テーブルを用意して、現在のチェックポイントを記録する。このため複数のプログラムを同時に実行させて、重複することなく並列でデータ処理を行うことが可能である。Application名は一意である必要があり、DynamoDBの制御名にも利用される。なお、「シャード」は、Kinesis上のデータ処理経路を、「プロデューサ」はKinesisへのデータの入力部分を、「コンシューマ」はKinesisからのデータ取得部分(役割)を指す。

レコードの順序

シャードイテレータは、シャード単位でデータを取得する。データの取得方法に関しては以下の4つが規定されている。

ShardIteratorType 取得方法
AT_SEQUENCE_NUMBER 特定のシーケンス番号からデータを取得
AFTER_SEQUENCE_NUMBER 特定のシーケンス番号の次のデータを取得
TRIM_HORIZON シャードの中でトリムされていない一番古いデータから取得
LATEST シャードの一番新しいデータから取得

レコードを取得(GetRecords)する際には、レコード毎に付与されたシーケンス番号がキーとなる。シーケンス番号は、シャード単位で管理されており、レコードを入力(PutRecords)した際にシャードごとにインクリメントされる。したがって、シーケンス番号順に取得するということは、すなわち各シャードに入力されたレコードを時系列順に取得するということと等しい。

ただし、シーケンス番号はシャード単位で管理されているため、1つのKinesis Client Libraryが、複数のシャードから同時にレコードを取得した場合などは、複数シャードのレコードが混在して取得されることから、取得データが時系列順に並ぶとは限らない。また、シャードへのデータ入力処理は並列で実施されるために、シャードへレコードが同時に入力された場合には、シーケンス番号が意図した通りにインクリメントされるとは限らない。レコード入力の際に、シャード内で厳密にシーケンス番号をインクリメントさせる場合には、SequenceNumberForOrderingパラメータを付与して、レコードの入力を行う。

時系列順に厳密にレコードを取得する必要がある場合には、プロデューサごとに毎回同じパーティションキーを使用し、かつSequenceNumberForOrderingパラメータを付与した上でレコードの入力を行う。これによって同一のプロデューサからのレコードは、同一のシャードに入力される。また、レコードを取得する際も、1シャードにつき1つのKinesis Client Libraryを用意することで、複数シャードのレコードを混在させることなく、レコードを取得・処理することが可能となる。ただし、各プロデューサごとに同じパーティションキーを使用する手法は、シャードごとにレコード量の偏りを生じる可能性もあるので注意が必要である。

課金

  • 無料枠は存在しない
  • シャード時間および PUT ペイロードユニットによる従量課金制

AWS CLIを用いたデータの取得

Kinesisの雰囲気をつかむためにawscliで操作する – Qiita

  • シャードイテレータの取得
    aws kinesis get-shard-iterator --shard-id shardId-000000000000 --shard-iterator-type TRIM_HORIZON --stream-name STREAM_NAME
    {
        "ShardIterator": "AAAAAAAAAAEJa+Y5A5ZF3pdoe9Yfwefjiwfweifw9eOy5kguQL7aglWO4VI+Fcb/A9bzR/tKQBW8Yxco9RyOlRfs0q8RgFC0g6wHCnznhzDjpP9Xpfg6vuY/EPPHhYyxDdSKwePQjojgmTTqQlZzbkRHSEo/qSB+Nuqbg4asIsKiYwv96vvJoqxGkQi6RTN3DVf83Vf4nirQ0Sa4tg2A1sAyPfvr/r4etOX"
    }
  • シャードイテレータを使ったレコードの取得
    aws kinesis get-records --shard-iterator AAAAAAAAAAEJa+Y5A5ZF3pdoe9Yfwefjiwfweifw9eOy5kguQL7aglWO4VI+Fcb/A9bzR/tKQBW8Yxco9RyOlRfs0q8RgFC0g6wHCnznhzDjpP9Xpfg6vuY/EPPHhYyxDdSKwePQjojgmTTqQlZzbkRHSEo/qSB+Nuqbg4asIsKiYwv96vvJoqxGkQi6RTN3DVf83Vf4nirQ0Sa4tg2A1sAyPfvr/r4etOX
  • レコードの例
  • Data部分はBase64エンコードされる
  • レコードが存在しない場合は、Recordsが空の状態でレコードが返る
    {
      "Records":[ {
        "Data":"dGVzdGRhdGE=",
        "PartitionKey":"Batch-SagbXhGLwl”,
        "SequenceNumber":"49544985256907370027570885864065577703022652638596431874"
      } ],
      "MillisBehindLatest":24000,
      "NextShardIterator":"AAAAAAAAAAEDOW3ugseWPE4503kqN1yN1UaodY8unE0sYslMUmC6lX9hlig5+t4RtZM0/tALfiI4QGjunVgJvQsjxjh2aLyxaAaPr+LaoENQ7eVs4EdYXgKyThTZGPcca2fVXYJWL3yafv9dsDwsYVedI66dbMZFC8rPMWc797zxQkv4pSKvPOZvrUIudb8UkH3VMzx58Is="
    }

文献

AWS Cognito(1)Cognitoの概要

Cognitoとは

Facebookなどのパブリックログインプロバイダ認証を元に、AWSの認証を得ることのできるサービス。このサービスを利用することで、例えば特定のSNSアカウントに紐づけられたユーザにのみS3へのアクセスを許可するなど、AWSリソースへのアクセスを設定することができる。また、各ユーザごとにkey, Value型のデータを保存することが可能であるので、例えばゲームの設定情報やスコア情報などを、デバイス間で共有することやバックアップすることも可能である。

アプリケーションユーザーの認証

  • 対応しているパブリックログインプロバイダ
    • Facebook
    • Google
    • Amazon
    • OpenID Connect
    • Twitter
    • Gigits
  • パブリックログインプロバイダから返されるOAuth や OpenID Connect のトークンを渡すと、Cognito IDと呼ばれる一意のIDが割り振られる
  • Cognito IDによって、AWSのリソースにアクセスすることが可能となる
  • パブリックログインプロバイダ認証は自分で実装する必要がある
    • Cognitoはプロバイダ認証の結果を受けて、プロバイダのトークンの確認やCognito IDとの紐づけを行う
  • AWSリソースへのアクセス権限はIAMで指定する
  • 未認証ゲストをサポートすることもできる

アプリケーションデータの保存

  • 各ユーザのデータ(データセット)は一度ユーザーのローカルデバイスに保存され、その後 AWS クラウドと同期される
    • アプリケーションデータを同期する際は、同期メソッドを明示的に呼び出す必要がある
  • データセットの取得や解析には、Kinesisストリームを利用する

課金

  • ストア容量とデータ同期回数に基づいて課金を行う
  • 1 か月につき 10 GB の同期ストア容量と 100 万回の同期オペレーションまでは無料枠が設定されている

Cognitoの設定

1. Identity Poolを作成する

  • 「Create new identity pool」をクリックする

Create new identity poolをクリック

Identity pools – Amazon Cognito – Amazon Web Services

2. 名称とプロバイダ情報を入力する

  1. 東京リージョンを選択する
  2. identity pool名を入力する
  3. 各種プロバイダ情報を入力する
  4. 登録を実行する

名称とプロバイダ情報を入力
New identity pool

3. ユーザのロールを設定

  • ダッシュボードから「Edit identity pool」をクリック
    • ダッシュボードには、各種データが表示される

ダッシュボード

  • 「Unauthenticated role」の「Create new role」をクリック
  • 「Authenticated role」の「Create new role」をクリック

Create new role

  • ロール名が自動入力されるので、作成ウィザードで登録を行う
    • Unauthenticated role
      Unauthenticated role
      –Authenticated role
      Authenticated role
  • IAMのロール一覧を開き、先ほど作成したロールを選択する
  • 作成済みのロールポリシーを確認する
{
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "mobileanalytics:PutEvents",
                    "cognito-sync:*"
                ],
                "Resource": [
                    "*"
                ]
            }
        ]
    }

次回は、JavaScriptを用いたコンテンツ側の実装を確認する。

AWS Lambda(1)Lambdaの概要

Lambdaとは

AWS Lambdaは、イベントをトリガにクラウド上で独自のコードを実行させるサービス。EC2インスタンス等の管理が不要で負荷に合わせて自動でスケールアウトすることのできるフルマネージドのサービスである。100ミリ秒単位の処理時間で従量課金される。例えば、画像がアップロードされたタイミングでサムネイル画像を生成したり、DynamoDBへの書き込みタイミングプッシュ通知を行うなどをLambdaを用いて実現できる。イベントの発生元となるAWSリソースは、S3, Kinesis, DynamoDB, Cognitoなどで、Pull/Pushの2種類のイベントモデルが存在する。

コードはブラウザ上で直接編集するか、Zip形式のファイルをアップロードすることで編集可能である。各種ライブラリはZipファイルに含めることで実行が可能となる。

データの永続化やS3DynamoDBを使用する。/tmpも使用できる。

LambdaのIAM権限は、誰がファンクションを実行できるかを記述したInvocation Roleと、どのようなことを実行できるかを記述したExecution Roleの2種類が存在する。

コンテクスト

実行コンテナは、タイムアウト(Timeout)した場合や、”context.done()“が呼び出された場合(Controlled termination)、全ての処理を終了した場合(Default termination)、クラッシュや”process.exit()“した場合に処理を終了する。実行コンテナは、前回の処理からある程度の時間が経過していた場合は新規で作成されるが、前回使用したものを再利用することもある。context.done()を記述することで予想外の実行を防ぐことができる。

内容
context.succeed(Object result) ファンクションおよびコールバックが正常終了
context.fail(Object result) ファンクションおよびコールバックがエラー
context.done(String message, Object result) ファンクションが終了. messageに値が入力されているとエラー
awsRequestId ファンクション呼び出しID
logStreamName CloudWatch LogsのLogストリーム名
clientContext クライアントアプリおよびデバイスの情報
Identity CognitoのIdentity Provider情報