AWSの各サービスを雑に紹介する

えー、投稿しておいて何ですが、本稿本当に雑ですので、ご利用にあたってはあくまで自己責任ということで、よろしくお願いします。

コンピューティング

  • Elastic Compute Cloud (EC2)
    仮想専用サーバ、従量課金制 ≫公式

  • EC2 Container Registry (ECR)
    DockerHubみたいなやつ ≫英語公式 / Google翻訳 ≫Developers.IO

  • EC2 Container Service (ECS)
    Dockerオーケストレーション(デプロイ、起動停止制御) ≫公式 ≫@IT

  • Lightsail
    仮想専用サーバ、定額制 ≫公式

  • AWS Batch
    ECS対応バッチジョブスケジューラ ≫公式 ≫公式 ≫Developers.IO

  • Elastic Beanstalk
    プログラム実行環境 (Java, PHP, .NET, Node.js, Python, Ruby)、EC2を使用 ≫公式 ≫YouTube

  • AWS Lambda
    プログラム実行環境 (Node.js, Java, C#, Python)、サーバレス ≫公式

  • Auto Scaling
    EC2対応オートスケール制御 ≫公式

  • Elastic Load Balancing
    負荷分散、BIG-IPとかその手のヤツのクラウド版 ≫公式 ≫@IT

ストレージ

  • Amazon Simple Storage Service (S3)
    オブジェクトストレージ。ファイルサーバとしても一応使える ≫公式

  • Amazon Elastic Block Store (EBS)
    ブロックデバイス ≫CodeZine

  • Elastic File System (EFS)
    ファイルサーバ ≫公式

  • Glacier
    バックアップストレージ ≫公式

  • Snowball
    HDDをFedExで送るオフラインデータ転送

  • Storage Gateway
    バックアップデバイスはお客様各自のオンプレミスにてご用意下さい、AWSは対向するインターフェースを提供します、というもの ≫CodeZine ≫Developers.IO

データベース

ネットワーキング & コンテンツ配信

移行

  • Application Discovery Service
    オンプレミスサーバの構成管理情報を収集する ≫公式

  • Database Migration Service (DMS)
    RDBをオンプレミスからAWSへ乗り換えるときに使う支援ツール

  • Server Migration Service (SMS)
    サーバをオンプレミスからAWSへ乗り換えるときに使う支援ツール

開発者用ツール

  • CodeCommit
    GitHubみたいなやつ

  • CodeBuild
    従量課金制ビルド

  • CodeDeploy
    コードデプロイ

  • CodePipeline
    Continuous Integration (CI) オーケストレーション。ビルド→デプロイの自動実行フロー定義。

  • AWS X-Ray
    分散アプリケーションのトレース ≫Serverworks

管理ツール

セキュリティ、アイデンティティ、コンプライアンス

  • AWS Identity and Access Management (IAM)
    AWSの認証、権限管理単位 ≫Developers.IO

  • Inspector
    脆弱性検出 ≫公式

  • Certificate Manager
    X.509証明書の管理 ≫公式

  • AWS Cloud Hardware Security Module (HSM)
    秘密鍵の保管(暗号、署名) ≫公式

  • AWS Directory Service
    Active Directory ≫Developers.IO

  • AWS Web Application Firewall (WAF)
    ファイアーウォール ≫公式

  • AWS Shield
    DDoS対策 ≫公式

分析

人工知能

IoT

ゲーム開発

モバイルサービス

  • Mobile Hub
    AWSのいろんなmBaaS系サービスを統合的に使えるコンソール画面 ≫Qiita

  • Cognito
    ソーシャル認証+データ同期。FacebookログインとかTwitterログインとか ≫Cookpad

  • AWS Device Farm
    テスト環境。Android, iOSの実機にリモートアクセスしてテストができる ≫公式

  • Mobile Analytics
    アプリの使用データの測定、追跡、分析 ≫公式 ≫Developers.IO

  • Pinpoint
    プッシュ ≫Qiita

アプリケーションサービス

  • Step Functions
    フローチャートみたいなビジュアルワークフローを画面上に描いて分散アプリケーションを構築する、というもの ≫公式

  • Amazon Simple Workflow (SWF)
    旧世代サービス。現在はStep Functionsを推奨 ≫公式

  • API Gateway
    HTTP API化 ≫公式

  • Elastic Transcoder
    動画、音声のフォーマット変換。つんでれんこaaSみたいなヤツ ≫Serverworks

メッセージング

  • Amazon Simple Queue Service (SQS)
    メッセージキュー ≫公式

  • Amazon Simple Notification Service (SNS)
    プッシュ ≫公式

  • Amazon Simple Email Service (SES)
    E-mail配信。メルマガとか ≫公式

ビジネスの生産性

デスクトップとアプリケーションのストリーミング

  • Amazon WorkSpaces
    仮想デスクトップ ≫impress

  • Amazon WorkSpaces Application Manager (WAM)
    Amazon WorkSpaces端末にアプリを配信するツール ≫serverworks

  • AppStream 2.0
    Citrix XenAppみたいなやつ ≫Developers.IO

参考文献

AWS ドキュメント
https://aws.amazon.com/jp/documentation/

AWS re:Invent 2016 発表サービスを三行でまとめる
http://qiita.com/szk3/items/a642c62ef56eadd4a12c

続きを読む

ECSのチュートリアル – コンテナ運用を現実のものにする

皆さんこんにちは

以前にコンテナの何がいいのかを説明する資料を作りました。
「やっぱりコンテナ運用しか無いな」
「コンテナを使わざるを得ない」
「とりあえずdocker入れとけばいいや」
という声が聞こえてきそうです(幻聴)

一方で、コンテナで運用するとなると、新たなる監視体制が必要となります。
例えば、Dockerのコンテナが突然停止した場合、その状況を検知し、新しくコンテナを立ち上げる必要があります。
また、そもそもコンテナが乗っている環境をスケールする必要が出たりして、その場合は新しくスケールされた環境でもコンテナを立ち上げなければならないし、その設定をサーバに書かなければならないけど、そうなると結局コンテナが乗っているサーバがブラックボックス化したりするわけで、なんとかうまく回そうとすると、それなりに気を配ることが多くなってきます。

最近はlaradockを使用する開発者が増えてきた(ような気がする)ので、コンテナ運用で幸せになるためにECSを使ってみた記録をチュートリアル形式で再現しておきます。

え?備忘録?ははは

ECSとは

ECSはAWSが提供しているコンテナ運用サービスです。
ECSの概念のちょっとしたものは以前に書いたECSで困ったときに読むための俺的Q&Aに書いてありますが、今回はECSでたてるWEBサーバに絞って超かんたんなポンチ絵を作ってみました。

ecs.png

あまりややこしいところはなさそうですが、簡単に見ていきましょう。

クラスター、コンテナインスタンス

コンテナインスタンスはdockerのコンテナのホストになるインスタンスで、クラスターはこのコンテナインスタンスの群れ( オートスケーリンググループ )です。
コンテナインスタンスにはdockerとコンテナの状態を監視してこちらに伝えてくれるエージェントが入っています。
コンテナ運用時には、個々のインスタンスには興味が無いので、「クラスター」と一括りにしてしまいます。

タスク、ECR

タスクはアプリケーションのまとまりを一つ以上のコンテナ動作で定義します。
今回の例ではnginxを動かすコンテナとphp-fpmを動かすコンテナのふたつで、webサーバのタスクを定義していて、nginxが外部からのリクエストを受け付け、php-fpmに渡しています。
コンテナを定義するイメージはECRというAWSが提供しているプライベートなdockerイメージのレジストリから取得しています。

サービス

サービスは3つの仕事をします。
1つ目はタスクが現在必要とされている個数を保っているかを監視し、その数を下回っていた場合、タスクを立ち上げて必要数を保つことです。
2つ目は現在の負荷状況を鑑みて、タスクを増減させます。この設定はCloudWatchのアラーム機能と連携させます。
3つ目はtarget groupと立ち上がったタスクを紐付けることです。

また、タスクの配置を各AZに均等に配置したりと、よく気配りのきくやつです。

ALB、target group

ALBはロードバランサーです。昔のクラシックなELBと違って、間にtarget groupと言うものを設置して、細かくルーティングできるようになっています。
target groupは実際のサーバへの振り分けを実施し、ヘルスチェックもします。

今回はこれらを利用して簡単なWEBサーバを運用できる状況に持っていきましょう

コンテナの準備

とりあえずコンテナを作る

運用したくとも、そのもととなるコンテナイメージがないと何も始まりません。
そこで、例によってLaraDockを利用してlaravelアプリを作ってみましょう。
プロジェクトの作成はここを見てもらうとして(ダイマ)、LaraDockとほぼ同じ動作をしてもらうために、Dockerfileをコピーしちゃいましょう。

$ cp -r ../laradock/nginx ./
$ cp -r ../laradock/php-fpm ./

これでDockerfileと設定ファイルをコピーできます。

今回、コンテナの中は完全に固定化…つまり、スクリプトを内部に含ませてしまうため、各Dockerfileの後部に

COPY ./ /var/www/

これを追加しておきます
また、nginxのdefaultのコンフィグファイルも必要なので、nginxのDockerfileには

COPY nginx/sites/default.conf /etc/nginx/conf.d/

も追加しておきます。
なにはともあれ、イメージを作成してみましょう。

$ cp nginx/Dockerfile ./ && docker build -t niisan/nginx .
$ cp php-fpm/Dockerfile-70 ./Dockerfile && docker build -t niisan/php-fpm .

これでイメージが作られているので、試しにサーバを立ててみましょう。

$ docker run -d --name php-fpm niisan/php-fpm
$ docker run -d --link php-fpm:php-fpm -p 80:80  niisan/nginx
$ curl 127.0.0.1
<!DOCTYPE html>
<html lang="en">
    <head>
...

うまく動いているようです。

コンテナをアップロードする

次にECRにコンテナをアップロードするのですが、初めての場合、ちょっとビビります。
けばけばしいタイトルとともに「今すぐ始める」ボタンが登場し、その次のページで妙な選択肢を迫ってきます。

ECSを始めることを。。。強いられているんだ!

(こういうところ、あまり好きじゃないです)
ここではとりあえず、「Amazon ECR によりコンテナイメージをセキュアに保存する」だけを選択しておきます。
すると、リポジトリの作成用のウイザードが迫ってきます。

ECR

とりあえずリポジトリ名にnginxと入れて次のステップへ
今度はECRにイメージをアップロードする手順が出てきますので、この通りにやってみます。
前回の記事でも言及したように、ここだけはAWS CLIを使用する必要がありますので、頑張って入れておきましょう。

$ aws ecr get-login

これで出てくるログインコマンドをコマンドラインにコピーして実行すればログイン完了です。
既にイメージは作ってあるので、タグを張り替え、アップロードしましょう。

$ docker tag niisan/nginx:latest **************.ecr.ap-northeast-1.amazonaws.com/nginx:latest
$ docker push *****************.ecr.ap-northeast-1.amazonaws.com/nginx:latest

これで完了です。
手順ページの完了ボタンを押すと、いまアップロードしたイメージのレジストリができていることを確認できます。

そのまま、左のバーにあるリポジトリを選択し、同じようにphp-fpmもアップロードしてみましょう。
1分もかからず終わるでしょう。

ECR登録済み

デプロイ

タスクを定義する

コンテナのイメージもアップロードできたことですし、早速タスクを定義していきましょう。
と言っても、今回の場合、内容は異様なほど簡単ですんで、すぐに終わるでしょう。

タスクの名前は適当に決めていいと思います。(今回は webtest という名前にしました。)
早速コンテナを入れていきましょう。まずはphp-fpmから行きます。「コンテナを追加」ボタンを押すと次のモーダルが出てきます。

タスクを設定

php-fpmの設定はこれだけで十分でしょう。
次にnginxを設定します。基本的にはphp-fpmと同様にイメージと名前を設定するわけですが、二つほど、違う設定があります。

ポートフォワード

まずはポートの設定です。
nginxは外部から接続できなければならないので、ホストからポートフォワードするように設定しました。

内部リンク

もう一つはphp-fpmへのリンクです。
これで、タスクの定義は完了しました。

クラスターを作る

タスクを作ったので、こいつを動かしてみましょう。
こいつを動かすためには、動作環境が必要となりますが、それがクラスターです。
早速クラスターを作っていきましょう。

クラスターの作成

せこいですが、コンテナが動作するインスタンスは一番ちっちゃいやつを使います。
次にネットワーキングの設定ですが、これはデフォルトのvpcを使ってお茶を濁しておきます。

商用環境では独自のVPC使おう

では作成しましょう。

クラスター作成完了

クラスターが出来上がりました。

作ったクラスターを選択して、早速タスクを動かしてみましょう。
クラスター名を選択し、タスクタブからタスクの開始ボタンを押すと、動作するタスクを選択する画面になります。

タスクの実行

では動作してみましょう。
しばらくすると、次のような状態になっていると思います。

動いているっぽい

どうやら動いているようです。
ECSインスタンスからコンテナのホストになっているインスタンスを参照して、public dnsを調べましょう。
それをブラウザにはっつけると、Laravelのページが表示されます。
Webアプリのデプロイ完了
うまくいきました!

サービスを使う

とりあえずデプロイできて、動作も確認できました。
とはいえ、これを運用するのはまだまだ厳しいところです。

  • タスクが死んだ場合の復旧をどうすればいいのか
  • コンテナを更新したときのデプロイ方法はどうなるのか
  • コンテナのスケーリングはどうするのか

この辺をサービスに解決してもらうとしましょう。

タスクを停止してみる

とりあえず、タスクを停止します。クラスターのタスクタブで、先ほど動かしたタスクを落とします。
当然ですが、落としたタスクは復活したりしないので、この時点で先に動かしたWEBサーバはダウン状態となります。

イメージを更新する

これからロードバランサーを使用するに当たり、ヘルスチェック用のルーティングをします。
今回はlaravel5.4を使う(使っちゃってる)ので次のようなroutingを用意します。

routes/web.php
Route::get('/healthcheck', function () {
    return ['health'=>'ok'];
});

この状態で、Dockerのイメージビルドを再実行します。
コンテナを再度動かすと次のような挙動を示します。

$ docker run -d --name php-fpm niisan/php-fpm
$ docker run -d --link php-fpm:php-fpm -p 80:80  niisan/nginx
curl 127.0.0.1/healthcheck
{"health":"ok"}

これをECRに再アップロードしておきます。

タスクを更新する

次に、タスクを更新していきます。
タスクはバージョン管理されていて、タスクはの更新は正確には新しいリビジョンを作るということになります。

例えば、今動いているリビジョンのタスクを新しいリビジョンのタスクに置き換えることで、サーバを更新したことと同じ状況にできますし、いざ新しいリビジョンが障害を起こすようなものであった場合は古いリビジョンに戻してロールバックすることもできます。

タスク定義->webtestでタスク定義のリビジョン一覧が現れます。今は一個しか無いと思うので、それを選択し、新しいリビジョンの作成ボタンを押しましょう。
今回の変更はnginxのポートの部分になります。

ダイナミックポート

なんとホストポートが空欄になっていますが、これがダイナミックポートという仕組みになります。
これはコンテナインスタンスで開いているポートを選んで、nginxコンテナの80ポートに繋げる仕組みで、ALB + target groupと組み合わせるときに使用します。

ALBを用意する

ひとまずコンテナの調整はこの辺にしておいて、ロードバランサーの設定を始めましょう。
まず、サービス -> EC2 -> サイドバーのロードバランサーを選択し、ロードバランサーを作成ボタンを押しましょう。
ALBの設定
Application load balancer を選択して、次へを押すとロードバランサーの設定に移ります。
今回はデフォルトのVPCを使うので、名前以外は全部デフォルトで問題なしです。
サブネットも二つあると思うので、両方共チェックしておきましょう。
一応、プロトコルはHTTPにしておきましょう。
セキュリティの警告は、今回は別に秘密通信でもないので、必要ないです。

セキュリティブループの設定

セキュリティグループはとにかく設定しておきましょう。
覚えやすい名前にしておくと、後で便利かもしれません。

空のターゲットグループ

ターゲットの登録画面になりますが、今はターゲットがないので、そのまま次へで、作成を完了させます。
これで、とりあえずロードバランサーの作成が完了しました。

最後に、ロードバランサーのセキュリティグループからコンテナインスタンスのセキュリティグループへの通信経路を確保しておきましょう。
コンテナインスタンスのセキュリティグループ( EC2ContainerService-*** )のinboundを編集しておきましょう。

セキュリティグループの設定

ロードバランサーからのinboundで全てのtcpを選択しておきましょう。
ダイナミックポートを使うと、開いているポートを使うのでどのポートが割り当てられるかわかりません。

サービスの作成

ここまで来てようやくサービスの作成が初められます。
再びEC2 Container Serviceから先程作成したクラスターを選択し、サービスを選択します。
作成ボタンがあるので、これを押しましょう。
サービス作成
まず、タスクはWebtestを選ぶわけですが、ここではリビジョンを含めて指定することになります。
サービス名は・・・とりあえずタスクのファミリー名と同じにしています。
画面下部に行くとELBを設定するボタンがあるので押してみましょう。
スクリーンショット 2017-03-18 22.39.45.png
するとこんな画面になるので、さっき作ったALBを選択し、負荷分散用のコンテナがnginxで、ポートが0:80になっていることを確認したら、ELBへの追加ボタンを押しましょう
スクリーンショット 2017-03-18 22.41.36.png
するとこんな画面になるのでターゲットグループを先程追加したものに変更して保存を押しましょう。

すると、サービスにALBの情報が登録されるので、この状態でサービスを作成しましょう。

スクリーンショット 2017-03-18 23.41.08.png

クラスターの状態がこのようになれば、成功です。
あとは、ロードバランサーのDNSにアクセスして、
Webアプリのデプロイ完了
これが出れば成功です。

まとめ

実はこれ書き始めたのって随分と前なのですが、途中でコンテナ運用の何がいいのかを説明するための資料作りしていたら、時間が立ってしまったのです。
まあ、ECSって使ってみるとすごく楽で、更にスケーリングしたり、他のサービスと相乗りさせたりマイクロサービス化させたりがすごく簡単にできるのですが、Webアプリを動かすに当たっては、わりとハマりどころが多いので、一貫したチュートリアル形式のものを作ってみました。
特にハマりどころなのは、ALB -> コンテナインスタンスにおけるセキュリティグループの設定だと思います。
考えてみれば当たり前なのですが、まあ、忘れることが多いです。
とはいえ、そんなところを超えてしまえば、後はコンテナで簡単に運用できる環境を量産できるので、皆さん是非とも使ってみてください。

今回はそんなところです。

参考

コンテナに挫折したあなたへ – 超わかりやすい発表資料です!師匠と呼びたい

続きを読む

ECS 導入における三つの明確な傾向

Datadog 上の原典ポストへのリンク:
https://www.datadoghq.com/blog/3-clear-trends-in-ecs-adoption/

以下は、Datadog が 2016 年末に公開した、”3 clear trends in ECS adoption” のポストを @jhotta が日本語化にしたものです。プロの翻訳ではなく、 もっぱら素早く ECS の普及状況を共有することを目的としています。技術的な要素で日本語の表記に問題がある場合は、コメントなどにより連絡をもらえますと助かります。


Last year, we published a study of Docker usage across our broad customer base. The data, which we then updated in June 2016, shows that the excitement around Docker is not just hype. Docker is being used at a large and ever-increasing number of organizations, and the companies that try Docker tend to stick with it.

As this young technology finds increasing use in production environments, we decided to take a deeper look at how organizations are managing their containerized application infrastructure. At Datadog, we have seen a tremendous amount of interest in container orchestration tools such as Kubernetes and Amazon ECS, but we wanted to see if our anecdotal observations were backed up by actual usage data.

Because we have thousands of customers running Docker, we can see usage and adoption trends emerging in real-time. In this article we’ll examine how organizations are using ECS specifically, although we plan to study container orchestration more broadly in the future. We’ve chosen to focus on ECS initially because Datadog’s integration with ECS has been generally available for well over a year, giving our customers plenty of time to start using it.

お客さまの利用状況を基に、2015年 Docker の使用状況に関する調査を公開しました。2016年6月に更新した同調査のデータでは、 Docker の周りで起きている盛り上がりは、単なる一時的な流行ではないことを示しています。 Docker は、ますます多くの組織で使用され、又 Docker を採用している組織の規模も大きくなってきています。そして、Docker を試してみた企業は、それを引き続き使い続ける傾向にあります。

公開されて間もないこのテクノロジーが実運用環境で次々と採用されるようになってきたのを踏まえ、 Docker を採用した組織が、コンテナ化されたアプリケーション インフラストラクチャを、どのように管理しているかを詳しく調査することにしました。 Datadog では、 Kubernetes や Amazon ECS などのコンテナ オーケストレーション ツールに、多くの技術者が関心を寄せているのを既に把握しています。しかし、この高い関心を、実際の利用状況のデータがバックアップしているかどうかを確認したいと考えました。

弊社には、Docker を使用している何千ものお客さまがいるため、利用状況と採用状況の傾向をリアルタイムで判定できます。将来的には、コンテナ オーケストレーションについてより広く検証していく予定ですが、この記事では Docker を採用した組織が ECS をどのように使用しているかについて検証していきます。今回、 ECS を選んだ理由は、ECS インテグレーションは一般的に利用できるようなってから一年以上が経過しており、組織が採用を決断するには十分な時間が経過していると判断したからです。

基礎知識: ECS の仕組み

Amazon’s EC2 Container Service (ECS) is a hosted service for managing and orchestrating Docker containers in the AWS cloud. As the name suggests, ECS allows you to run Docker containers on a cluster of EC2 instances. ECS handles the scheduling and placement of containers across your cluster, balances load across containerized services, and can be configured to automatically scale your container infrastructure based on demand. And of course ECS integrates neatly with other AWS services, such as CloudWatch, ELB (Elastic Load Balancing) and Auto Scaling.

Amazon の EC2 コンテナサービス(ECS)は、 AWS クラウドの Docker コンテナを管理およびオーケストレーションするためのホスト型サービスです。 その名前が示すように、 ECS では EC2 インスタンスのクラスタ上で Docker コンテナを実行できます。 ECS は、クラスタ全体のコンテナのスケジューリングと配置を処理し、コンテナ化されたサービス間の負荷のバランスをとり、需要に基づいてコンテナインフラストラクチャを自動的に拡張するように構成できます。 もちろん、 ECS は CloudWatch、ELB(Elastic Load Balancing)、自動スケーリングなどの他の AWS サービスときちんと統合されています。

トレンド 1: ECS は静かに、着実に人気を獲得している

ECS does not have the buzz or community that buoys the open source competitor Kubernetes, but our data shows that ECS is getting plenty of real-world use. In the year-plus since Datadog’s ECS integration was first released, ECS adoption has climbed steadily from zero to 15 percent of Docker organizations using Datadog. (And more than 10 percent of all Datadog customers are now using Docker.)

ECS is steadily gaining steam for Docker orchestration.

The graph of ECS adoption as a share of Docker users shows a slight flattening in recent months, but it’s important to note that this analysis may underestimate the share of Docker users in Datadog’s customer base who run ECS.1

ECS には、オープンソースの競合である Kubernetes のように、バズって人気を押し上げてくるコミュニティはありません。しかしデータは、 ECS が実際に多くの利用を獲得ていることを示しています。 Datadog が ECS インテグレーションをリリースしてからの一年ちょっとの期間で、Dcoker 採用組織内での ECS 採用組織の割合が 0% から 15% に安定的に増えていきました。(尚現在、Datadog の全利用者の 10% 以上が、 Docker を使用しています。)

ECS は Docker オーケストレーションを実現するツールとして着実に人気を集めています。

Docker ユーザ内の ECS ユーザの割合としての ECS 採用グラフは、ここ数ヶ月でわずかに平坦化しています。しかしこの分析結果は、Datadog の顧客ベース内で ECS を採用している Docker ユーザを過小評価している可能性があるこに注意してください。(脚注:1)

トレンド 2: コンテナの増加は、問題の増加

As you might expect, orchestration is more prevalent in organizations with more Docker. After all, manually shepherding your containers is fine for small projects, but can become untenable as the number of hosts and containers grows.

Among Datadog users, we see very limited usage of ECS in organizations where fewer than five unique hosts report Docker metrics over the course of a month.2 But as the Docker infrastructure grows, so does the likelihood that a given organization will orchestrate its containers using ECS. Nearly 40 percent of organizations monitoring large Docker installations of more than 100 hosts are also monitoring ECS.

ECS usage correlates with larger, more complex Docker infrastructure.

Bucketing organizations by the number of unique Docker images in use, rather than unique hosts, reveals a similar pattern: The more images an organization uses, the higher the rate of ECS use.

予想が付くと思いますが、オーケストレーション ツールは、扱う Dcoker (コンテナ)が多い組織ほど、一般的に普及しています。結局のところ、コンテナを手動で取り扱うことは、小規模なプロジェクトではうまくいきますが、ホストやコンテナの数が増えるにつれて容認できなくなってきます。

Datadog ユーザの間では、一ヶ月間に 5 台以下のホストが Docker メトリックを送信してくる組織では、 ECS の使用が非常に限定されています。(脚注:2) しかし、 Docker インフラストラクチャが拡大するにつれて、組織が ECS を使ってコンテナを編成する可能性も高くなります。100 台以上の Docker ホストを有する大型の Docker 環境を監視するような組織では、40% 近くが ECS も監視しています。

ECS の使用は、より大きくより複雑な Docker インフラストラクチャと相関します。

ホスト単位ではなく、使用中の Docker イメージ単位で組織を分類しても同様のパターンが明らかになります: 組織が使用するイメージが多いほど、 ECS の使用率は高くなります。

トレンド 3: オーケストレーション == 多産家系

Whether increasingly complex infrastructure demands orchestration, or orchestration opens the door to more complex container infrastructure, one thing is clear: the typical organization’s container infrastructure grows significantly right around the time that they start using ECS.

The graphs below track the increase in running containers and Docker hosts associated with a typical organization’s adoption of ECS (as inferred from the first arrival of ECS metrics). The counts are normalized per organization so that a value of 1.0 represents the organization’s average value across the time window.

We include a 60-day “before” window to show that the baseline prior is fairly steady, then starts to increase around 10 days before ECS adoption. This early ramp-up could be explained by organizations making changes to their infrastructure in preparation for a cutover, or by a lag between the actual adoption of ECS and the start of monitoring ECS with Datadog.

Companies start using more containers and Docker hosts when they adopt ECS.

In the 30 days after an organization starts reporting ECS metrics, we see a 35 percent increase in the number of running containers as compared to the 60-day baseline that came before. Using the same parameters, we see a 27 percent increase in the number of running Docker hosts.

益々複雑化するインフラストラクチャがオーケストレーションに走らせるのか、又は、オーケストレーションが複雑なコンテナインフラストラクチャを可能にしているのかというという問いのたいして言えることは、典型的な組織のコンテナ インフラストラクチャは、 ECS の使用を開始する頃に大きく成長します。

以下のグラフは、標準的な組織の ECS 採用に関連したコンテナおよび Docker ホストの増加を追跡しています(ECS メトリクスを最初に受信した時を基準にしています)。カウントは組織ごとに正規化されるため、値の1.0 は、全の時間をサンプル対象にしたその組織の平均値になります。

ECS 導入の前のベースラインがほぼ安定していることを示すために、採用前 60 日を表示しています、その後 ECS 導入の約 10 日前に増加が始まります。この初期の立ち上げは、企業がカットオーバに備えるためにインフラストラクチャを変更することによって、またはECSの実際の採用とDatadogによるECSの監視の開始の遅れによって説明できます。

企業は、ECS を導入すると、より多くのコンテナと Docker ホストを使用し始める。

組織が ECS メトリクスの収集を開始してから 30 日後には、実行中のコンテナ数は、”60日間のベースライン”に比べて 35% 増加しています。 同じパラメータを使った場合、実行中の Docker ホスト数は、 27% 増加します。

オーケストラのチューニング (構成要素のチューニング)

Docker is still a young technology, and the tooling around it is younger still. But all indications from our ECS analysis and our larger Docker adoption study are that plenty of organizations are already getting serious about containerization.

As container orchestration marches closer to the mainstream, we will continue to keep an eye on emerging trends. Look out for new and updated analyses on Docker adoption, ECS usage, and other infrastructure trends in the coming months.

Docker はまだ若い技術であり、その周辺のツールもまだ若いです。しかし、今回の ECS の導入実態に関する分析と、これまでの Docker 導入調査からは、多くの組織がすでにコンテナ化について真剣に取り組んでいるということです。

コンテナ オーケストレーションが主流になっていくにつれ、新たな傾向が読み取れないか、引き続き注力していきたいと思います。
現在準備している 更新版の Docker の導入分析、 ECS の使用状況分析、及び今後のインフラストラクチャ動向に関する分析にもご期待ください。

脚注


  1. The percentages in this graph are calculated by selecting all the organizations that enabled the Docker integration in Datadog, and determining which of those organizations also have ECS enabled in their account. But some organizations may run ECS without native Docker instrumentation, so they are excluded from the calculation. [return]
  2. These percentages are calculated from host and image counts during the month of October 2016. [return]
  1. グラフのパーセンテージは、 Datadog で Docker インテグレーションを有効にしたすべての組織を抽出し、その中から ECS のアカウントで有効になっている組織を抽出して計算されています。しかし、一部の組織では、Docker インテグレーションなどの Datadog では一般的な Docker の監視方法を使用せずに ECS を起動していることがあるため、それらの組織については計算に含まれていません。
  2. これらのパーセンテージは、2016年10月の月間のホスト数とイメージ数から計算されます。

続きを読む

RedmineをElasticBeanstalkのMulti-Container Dockerで起動してみた

ElasticBeanstalkをいろいろ試している最中。
今回はMulti−Container Dockerのお試し。

方針

  • Redmineのコンテナとリバースプロキシ用のNginxコンテナを使う。
  • AWSなのでデータベースはRDSを使う。
  • お試しなのでDocker RegistoryはDockerhubを使う。
  • RedmineのDockerイメージはお約束のsameersbn/redmine

EBアプリケーションのソースバンドル作成

この時点ではまだAWSを触る必要はない。
ディレクトリとファイルの構成は以下のような感じ。

.
├── Dockerrun.aws.json
├── nginx/
│   └── conf.d/
│       └── default.conf
└── redmine/
    └── data/
        └── .gitkeep

Dockerrun.aws.jsonにコンテナの構成を記載する。
どうやらECSのTask Definisionと同じような内容のようだ。

Dockerrun.aws.json
{
  "AWSEBDockerrunVersion": 2,
  "volumes": [
    {
      "name": "redmine-data",
      "host": {
        "sourcePath": "/var/app/current/redmine/data"
      }
    },
    {
      "name": "nginx-conf",
      "host": {
        "sourcePath": "/var/app/current/nginx/conf.d"
      }
    }
  ],
  "containerDefinitions": [
    {
      "name": "redmine",
      "image": "sameersbn/redmine",
      "essential": true,
      "memory": 512,
      "mountPoints": [
        {
          "sourceVolume": "redmine-data",
          "containerPath": "/home/redmine/data"
        }
      ],
      "environment": [
        {
          "name": "REDMINE_RELATIVE_URL_ROOT",
          "value": "/redmine"
        },
        {
          "name": "DB_ADAPTER",
          "value": "postgresql"
        }
      ]
    },
    {
      "name": "nginx-proxy",
      "image": "nginx",
      "essential": true,
      "memory": 128,
      "mountPoints": [
        {
          "sourceVolume": "nginx-conf",
          "containerPath": "/etc/nginx/conf.d",
          "readOnly": true
        }
      ],
      "portMappings": [
        {
          "hostPort": 80,
          "containerPort": 80
        }
      ],
      "links": [
        "redmine:redmine"
      ]
    }
  ]
}

ホストの環境変数を自動で引き継いでくれるみたいなのでDB_HOSTやDB_NAMEなどはEBの環境変数で渡せるためここでは書かない。逆にここに書いちゃうと環境ごとに作らないとなので絶対にやらない。
logConfigurationでCloudWatch LogsやFluentdが使えるみたいだけど、今回は割愛。

Redmineはサブディレクトリにしてみた。
複数アプリケーションをNginxでパスルーティングできることのフィジビリティ確保。(ALB使えや)
Route53でドメイン名を複数このEBに紐付けてホスト名での振り分けもできそう。
ホスト名でのルーティングはALBでは(今のところ)できない。

nginx/conf.d/default.conf
server {
    listen       80;
    server_name  localhost;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    location /redmine {
      proxy_set_header X-Real-IP  $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_pass http://redmine;
    }
    error_page  404              /404.html;
    error_page  500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

で、ローカルのGitリポジトリにcommitしておく。

git init && git add ./* && git commit -m "initial commit."

必要なリソースを事前準備

RDSとセキュリティグループは事前に作成しておかないと最初のデプロイでコケるので事前に作成しておく。

  • VPC * 1, Internet Gateway * 1, RouteTable * 1, Subnet * 1
  • ElasticBeanstalk用のSecurity Group (80/tcp 0.0.0.0/0) * 1
  • PostgreSQLのRDS (EBで作成しない)
    • RDSのSecurityGroupで上で作ったSecurityGroupからのアクセスを許可しておく。

ElasticBeanstalkの環境を作成する

マネジメントコンソールでもできるけど、ElasticBeanstalkはeb-cliを使ったほうが便利。(というかcliじゃないとできない設定が多すぎる)

# アプリケーションの作成
eb init --region ap-northeast-1 -p "multi-container-docker-1.12.6-(generic)" test-app
eb create -r ap-northeast-1 -c CNAMEのプレフィクス -i t2.small -k EC2キーペア 
  -p "multi-container-docker-1.12.6-(generic)" --single 
  --envvars "DB_HOST=RDSエンドポイント,DB_NAME=RDSのDB名,DB_USER=RDSのマスタユーザ,DB_PASS=RDSパスワード" 
  --vpc --vpc.id VPCのID --vpc.ec2subnets サブネットのID --vpc.securitygroups セキュリティグループID 
  --vpc.publicip 
  test-app-env

http://CNAMEのプレフィクス.ap-northeast-1.elasticbeanstalk.com/redmine にアクセスしてRedmineが表示されればOK。
ElasticBeanstalkって作るまでは本当に簡単。カスタマイズは大変だけど。

続きを読む

Elasticsearchの5系をECS上で起動しようとしてエラーになった時の対応方法

ECS上で動いていたElasticsearchを2.3を5.2にバージョンアップしてエラーが出た際の対応記録です。

メモリエラーへの対応

エラーログ
OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000085330000, 2060255232, 0) failed; error='Cannot allocate memory' (errno=12)

ホスト側で解決するならswap領域メモリの量を増やすことで解決します。
http://qiita.com/waytoa/items/7010cfe2852d816c9513

docker内で解決するならJavaのヒープサイズを設定しても良いようです。

FDエラーへの対応

エラーログ
max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]

ホスト側のulimitの設定をしてもdocker側には反映されないので、docker起動時の引数で渡す必要があります。

docker run --ulimit nofile=1024:1024

ECS上ではスクリーンショットのようにNOFILEのリミットに対して、65536を割り当てます。

Screen Shot 2017-03-09 at 17.15.55.png

メモリマップ数エラーへの対応

エラーログ
max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

ホスト側で設定した値がdocker側にも反映されたので以下で解決します。

sudo sysctl -w vm.max_map_count=262144

続きを読む

[JAWS-UG CLI] AWS Batch #3 より実践的な使い方

前提条件

EC2への権限

EC2、ECS、AWS Batch などに対してフル権限があること。

0. 準備

0.1. ジョブの作成と実行の完了

AWS Batch #2 ジョブの作成と実行 が終わっていること

0.2. 変数の確認

#1, #2 から引き続き利用する変数を確認します

コマンド
cat << ETX

    CFN_STACK_NAME:       ${CFN_STACK_NAME}
    COMPUTE_ENV_NAME:     ${COMPUTE_ENV_NAME}
    JOB_QUEUE_NAME:       ${JOB_QUEUE_NAME}
    JOB_DEFINITION_NAME:  ${JOB_DEFINITION_NAME}
    CONRAINER_PROPS_FILE: ${CONRAINER_PROPS_FILE}

ETX
結果(例)

    CFN_STACK_NAME:       aws-batch-xxxxxxxxxx
    COMPUTE_ENV_NAME:     aws-batch-managed-xxxxxxxxxx
    JOB_QUEUE_NAME:       aws-batch-job-queue-xxxxxxxxxx
    JOB_DEFINITION_NAME:  aws-batch-job-def-xxxxxxxxxx
    CONRAINER_PROPS_FILE: aws_batch_container_props.json

0.3. AWS CLIのバージョン

以下のバージョンで動作確認済

  • AWS CLI 1.11.36
コマンド
aws --version
結果(例)
 aws-cli/1.11.36 Python/2.7.5 Darwin/13.4.0 botocore/1.4.93

バージョンが古い場合は最新版に更新しましょう。

コマンド
sudo -H pip install -U awscli

1. サンプルアプリケーション

  • AWS Batch で 定例バッチ1 を実装してみます
  • COBOL での帳票出力を AWS Batch で動かします
  • 作成された帳票は S3 へアップロード
  • ジョブには S3 へのアップロード権限があるロールを付与
  • CloudWatch Events + Lambda から毎分ごとに Job を Submit

1.1 Docker リポジトリの作成

ジョブ実行ロジックを push するためのリポジトリを作ります

コマンド
DOCKER_REPO=$( aws ecr create-repository 
  --repository-name ${CFN_STACK_NAME}/sample 
  | jq -r '.repository.repositoryUri' 
) && echo ${DOCKER_REPO}
結果(例)
xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/aws-batch-xxxxxxxxxx

1.2. #1 で生成したスタックから変数の取得

CloudFormation スタックの生成結果を再取得

コマンド
CFN_STACK_RESULT=$( aws cloudformation describe-stacks 
  --stack-name ${CFN_STACK_NAME})

スタックの生成結果(Output)から、必要な変数を抜き出します。

コマンド
S3_BUCKET_NAME=$( echo ${CFN_STACK_RESULT} 
  | jq '.Stacks[].Outputs[]' 
  | jq -r 'select(.OutputKey=="S3Bucket").OutputValue' )

BATCH_JOB_ROLE=$( echo ${CFN_STACK_RESULT} 
  | jq '.Stacks[].Outputs[]' 
  | jq -r 'select(.OutputKey=="BatchJobRole").OutputValue' )

cat << ETX

    S3_BUCKET_NAME: ${S3_BUCKET_NAME}
    BATCH_JOB_ROLE: ${BATCH_JOB_ROLE}

ETX
結果

    S3_BUCKET_NAME: aws-batch-xxxxxxxxxx-s3bucket-xxxxxxxxxxx
    BATCH_JOB_ROLE: arn:aws:iam::xxxxxxxxxxxx:role/aws-batch-xxxxxxxxxx-BatchJobRole-xxxxxxxxxxxxx

1.3. ジョブ定義の作成

コンテナ定義ファイルを再生成します。

コマンド
cat << EOF > ${CONRAINER_PROPS_FILE}
{
  "image": "${DOCKER_REPO}",
  "command": ["Ref::Arg1", "Ref::Arg2"],
  "jobRoleArn": "${BATCH_JOB_ROLE}",
  "environment": [
    { "name": "AWS_DEFAULT_REGION", "value": "${AWS_DEFAULT_REGION}"},
    { "name": "AWS_S3_BUCKET", "value": "${S3_BUCKET_NAME}"},
    { "name": "APP_VERSION", "value": "production!"}
  ],
  "vcpus": 1,
  "memory": 100
}
EOF
cat ${CONRAINER_PROPS_FILE}

コンテナ定義ファイルの検証

コマンド
jsonlint -q ${CONRAINER_PROPS_FILE}

これを使い、ジョブ定義を更新します

コマンド
aws batch register-job-definition 
  --job-definition-name ${JOB_DEFINITION_NAME} 
  --container-properties file://${CONRAINER_PROPS_FILE} 
  --type container
結果(例)
{
    "jobDefinitionArn": "arn:aws:batch:us-east-1:xxxxxxxxxxxx:job-definition/aws-batch-job-def-xxxxxxxxxx:1", 
    "jobDefinitionName": "aws-batch-job-def-xxxxxxxxxx", 
    "revision": 2
}

1.4. ジョブ投入に使う変数の確認

流したジョブを識別できるよう名前を決めます

コマンド
JOB_NAME="job-`date +%s`"

リビジョンが最新のジョブ定義 ARN を取得します

コマンド
JOB_DEFINITION_ARN=$( aws batch describe-job-definitions 
  --job-definition-name ${JOB_DEFINITION_NAME} 
  --status ACTIVE 
  | jq -r '.jobDefinitions | max_by(.revision).jobDefinitionArn' 
) && echo ${JOB_DEFINITION_ARN}
結果(例)
 arn:aws:batch:us-east-1:xxxxxxxxxxxx:job-definition/aws-batch-job-def-xxxxxxxxxx:2

2. ジョブ投入のための追加リソース生成

2.1. CloudFormation スタックの生成

テンプレートの取得

コマンド
curl --location --output ${CFN_STACK_NAME}-job.yaml 
  https://raw.githubusercontent.com/supinf/aws-batch-refarch/master/cloudformation/job-executor.yaml

CloudFormation スタックの生成

コマンド
aws cloudformation create-stack 
  --stack-name ${CFN_STACK_NAME}-job 
  --template-body file://${CFN_STACK_NAME}-job.yaml 
  --parameters ParameterKey=JobName,ParameterValue=${JOB_NAME} 
               ParameterKey=JobQueueName,ParameterValue=${JOB_QUEUE_NAME} 
               ParameterKey=JobDefinitionArn,ParameterValue=${JOB_DEFINITION_ARN} 
  --capabilities CAPABILITY_IAM
結果(例)
{
    "StackId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/aws-batch-xxxxxxxxxx-job/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

このスタックにより以下のリソースが作成されます

  • Job 投入 Lambda
  • 定期的にその Lambda を蹴る CloudWatch Events

2.2. 生成されたリソースから変数を取得

スタックの生成を待機

コマンド
aws cloudformation wait stack-create-complete 
  --stack-name ${CFN_STACK_NAME}-job
結果
返り値なし

生成結果を取得

コマンド
CFN_STACK_RESULT=$( aws cloudformation describe-stacks 
  --stack-name ${CFN_STACK_NAME}-job 
) && echo ${CFN_STACK_RESULT} | jq .

スタックの生成結果(Output)から、必要な変数を抜き出します。

コマンド
TRIGGER_ARN=$( echo ${CFN_STACK_RESULT} 
  | jq '.Stacks[].Outputs[]' 
  | jq -r 'select(.OutputKey=="BatchJobEvent").OutputValue' )
echo ${TRIGGER_ARN}
結果(例)
arn:aws:events:us-east-1:xxxxxxxxxxxx:rule/BatchJobTriggerRule

3. 実行するジョブの準備

引数 2 つ、環境変数 2 つを受け取り、ファイルを生成する
以下の COBOL プログラムをジョブとして動かしてみます。

https://github.com/pottava/docker-cobol/blob/master/examples/batch.cbl

(サンプルには COBOL 言語を使っていますが、もちろんシェルスクリプトでも、Java でも Python でも、Swift でも Elixir でも Docker にさえすれば AWS Batch 上で動きます)

3.1. エントリーポイントの用意

AWS Batch からの引数をうまいこと受け取り、かつ出力されたファイルを S3 にアップロードするためのラッパースクリプトを用意します。

ファイル名を決め

コマンド
DOCKER_ENTRYPOINT_FILE="entrypoint.sh"

生成します

entrypoint.sh
cat << EOF > ${DOCKER_ENTRYPOINT_FILE}
#!/bin/bash

if [ -z "$AWS_DEFAULT_REGION" ]; then
  echo "Missing environment variable 'AWS_DEFAULT_REGION'." 1>&2
  exit 1
fi
if [ -z "$AWS_S3_BUCKET" ]; then
  echo "Missing environment variable 'AWS_S3_BUCKET'." 1>&2
  exit 1
fi
if [ -z "$AWS_S3_KEY" ]; then
  AWS_S3_KEY="result-$(date +%Y%m%d%H%M)"
fi

/usr/local/bin/batch $@

rc=$?
if [ $rc -ne 0 ] ;then
  echo "[Error] Executing batch went wrong..." 1>&2
  echo "ARGUMENTS: "$@ 1>&2
  echo "APP_VERSION: "${APP_VERSION} 1>&2
  echo "APP_TARGET: "${APP_TARGET} 1>&2
  exit $rc
fi

aws --region $AWS_DEFAULT_REGION s3api put-object \
    --bucket $AWS_S3_BUCKET --key $AWS_S3_KEY \
    --body result.txt

rc=$?
if [ $rc -ne 0 ] ;then
  echo "[Error] Sending job results went wrong..." 1>&2
  echo "ARGUMENTS: "$@ 1>&2
  echo "APP_VERSION: "${APP_VERSION} 1>&2
  echo "APP_TARGET: "${APP_TARGET} 1>&2
  echo "AWS_S3_BUCKET: "${AWS_S3_BUCKET} 1>&2
  echo "AWS_S3_KEY: "${AWS_S3_KEY} 1>&2
  exit $rc
fi
EOF

3.2. Dockerfile の作成

お決まりのファイル名で

コマンド
DOCKER_FILE="Dockerfile"

生成します

Dockerfile
cat << EOF > ${DOCKER_FILE}
FROM debian:wheezy-slim

ADD https://raw.githubusercontent.com/pottava/docker-cobol/master/examples/batch.cbl /usr/local/src/
ADD entrypoint.sh /

RUN BUILD_PACKAGES="build-essential curl" \
    && apt-get update && apt-get autoremove -y \
    && apt-get install -y ${BUILD_PACKAGES} open-cobol python \
    && chmod +x /entrypoint.sh \

    # Build application
    && cd /usr/local/bin \
    && cobc -x /usr/local/src/batch.cbl \

    # Install AWS-CLI
    && curl --location --silent --show-error \
        https://bootstrap.pypa.io/get-pip.py | python \
    && pip install "awscli==1.11.56" \

    # Clean up
    && apt-get purge -y --auto-remove ${BUILD_PACKAGES} \
    && find / -depth -type d -name test -exec rm -rf {} \; \
    && find / -depth -type d -name __pycache__ -exec rm -rf {} \; \
    && rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/* /root/.cache

WORKDIR /app

ENV AWS_DEFAULT_REGION=ap-northeast-1 \
    AWS_S3_BUCKET="" \
    AWS_S3_KEY="" \
    APP_VERSION=0.1.0 \
    APP_TARGET=executor

ENTRYPOINT ["/entrypoint.sh"]
EOF

3.3. アプリケーションの Docker イメージ化

ECR のリポジトリ名を指定しつつ、ビルドします。
回線が細いと 15 分ほどかかるかもしれません。

コマンド
docker build -t ${DOCKER_REPO} .
結果(例)
Sending build context to Docker daemon 24.06 kB
Step 1/7 : FROM debian:wheezy-slim
 ---> b7230ec23103
Step 2/7 : ADD https://raw.githubusercontent.com/pottava/docker-cobol/master/examples/batch.cbl /usr/local/src/
Downloading 2.687 kB
 ---> Using cache
 ---> 723925bd3df1

(中略)

Step 7/7 : ENTRYPOINT /entrypoint.sh
 ---> Running in 94ca4974b074
 ---> ca617324a141
Removing intermediate container 94ca4974b074
Successfully built ca617324a141

ECR にログインし、Docker イメージを push しましょう

コマンド
aws ecr get-login | sh
docker push ${DOCKER_REPO}
結果(例)
The push refers to a repository [xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/aws-batch-xxxxxxxxxx/sample]
de07e4081e81: Pushed
f0c9c1e82d65: Pushed
4e4c70200302: Pushed
d4a5f6671fae: Pushed
6db2a2c16cbd: Pushed
latest: digest: sha256:c7e5ef31e1bde0a6ec4327118e5d2976da098e7a5e9fa5a7ee236ceb942e094a size: 1361

4. ジョブの投入

Docker イメージも準備できました。
では事前に CloudFormation で用意しておいた Lambda を CloudWatch Events から定期的に起動し、AWS Batch へ Job を Submit してみましょう。

4.1. CloudWatch Events の有効化

1 分おきに Lambda を蹴るルールは定義済みですが
DISABLED で停止している状態になっています。
ENABLE に更新して処理を開始してみましょう。

コマンド
aws events enable-rule 
  --name $( aws events list-rules | jq '.Rules' 
    | jq "map(select(.Arn=="${TRIGGER_ARN}"))" 
    | jq -r '.[].Name' )
結果
返り値なし

4.2. Job ステータスの確認

流れてくる Job の様子を確認します。
1 分おきに結果が増えていくはずです。

コマンド
aws batch list-jobs 
  --job-queue ${JOB_QUEUE_NAME} 
  --job-status SUCCEEDED 
  | jq '.jobSummaryList' 
  | jq "map(select(.jobName=="${JOB_NAME}"))"
結果(例)
[
  {
    "jobName": "job-1488375104",
    "jobId": "71895de8-b28c-41eb-b94f-43fe2fb7878a"
  },
  {
    "jobName": "job-1488375104",
    "jobId": "cbc64814-a27a-48cc-9376-d67c95984505"
  }
]

4.3. 出力された帳票の確認

まずは帳票の一覧を表示してみます

コマンド
aws s3api list-objects 
  --bucket ${S3_BUCKET_NAME} 
  | jq '.Contents' 
  | jq 'map({Key: .Key, LastModified: .LastModified})'
結果(例)
[
  {
    "Key": "result-201703011749",
    "LastModified": "2017-03-01T17:49:13.000Z"
  },
  {
    "Key": "result-201703011750",
    "LastModified": "2017-03-01T17:50:18.000Z"
  }
]

どれかを選び、ダウンロードしてみましょう

コマンド
S3_KEY="result-201703011749"
コマンド
aws s3api get-object 
  --bucket ${S3_BUCKET_NAME} 
  --key ${S3_KEY} ${S3_KEY}
結果(例)
{
    "AcceptRanges": "bytes",
    "ContentType": "binary/octet-stream",
    "LastModified": "Wed, 01 Mar 2017 17:49:13 GMT",
    "ContentLength": 121,
    "ETag": ""190d1fecd45c7996ab8f124cd60a42ee"",
    "Metadata": {}
}

ファイルを開いてみます

コマンド
cat ${S3_KEY}
結果(例)
     2 17:48:59        from-AWS-Lambda
production!     0dfc1g7b47
   1 49 12
   2 49 12
   3 49 12
   4 49 12
   5 49 12

完了

より実践的な使い方は以上です。
AWS Batch #4 環境の破棄

 


  1. AWS Batch にはまる ユースケース ではないものの、できないわけではありません。ネタです。 

続きを読む

AWS Batch とは何か

AWS re:Invent 2016 で発表された AWS Batch。
語感から、誤解されるサービス No.1 な気がします。
定時バッチなどとは何がどう違うのかをメモ。

機能概要

以下公式資料とドキュメント、実際さわってみた所感を合わせて。

結局何なのか

科学技術計算・ハイパフォーマンスコンピューティング用途で真価を発揮する、
大規模なスケール、ジョブの依存定義 が可能なマネージド 並列分散 処理基盤。

主な機能、ポイント

  • クラスタ管理、ジョブキュー、ジョブスケジューラを AWS にお任せできる
  • 処理すべきジョブの数に応じ、適切に 自動伸縮1 するクラスタ
  • ジョブに 依存関係 が定義できる(B は A に依存した処理である2、など)
  • 優先度 を持ったキューを複数定義できる
  • 処理能力ごとにクラスタを分割管理することもできる
  • リソース調達が EC2 より直感的、かつ Spot Fleet も統合済み
  • クラスタは ECS 上に構築される
  • サードパーティのデータ分析ワークフローエンジンのサポートあり

これがマネージドされると僕らは何がうれしいのか

  • 本来やりたい、ジョブの実行依頼(submit)と実処理だけを考えればよくなる
  • クラスタ全体で利用可能なリソースの把握、過不足に応じたその調整が不要3
  • 前処理、集約処理、後処理といった流れのある処理も基盤側に制御を移譲できる
  • 依頼者や状況に応じた優先的リソース配分が容易に実現できる
  • CPU / GPU でそれぞれクラスタを作り、前処理 CPU、本処理 GPU なども簡単
  • クラスタごとに可用性、パフォーマンス、コストのバランスが定義しやすい
  • Docker イメージにさえしてしまえばどんな処理も AWS Batch に乗せられる
  • すでにデータ分析パイプラインの定義があれば移行しやすい(かもしれない)

逆に現在4サポートしていないこと

以下 API を駆使してプログラムは書けるものの、標準機能にはありません。

  • cron のように事前指定した時間での起動など、定期タスク管理
  • ジョブの処理そのものや待機状態のタイムアウト
  • 処理が失敗した場合のリトライ
  • リソース不足時、どのリソースがどれだけ足りないかの把握

定時バッチのマネージドサービスではないよという話

再掲:「AWS Black Belt Online Seminar 2017 AWS Batch」10 ページ目
https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-2017-aws-batch/10

ストリーミングではなく、(本来の意味の)バッチ的に渡ってくるタスクを
スケーラブルに並列処理させるための仕組みとのことです。

ユースケース

公式

以下からも明らかに主なターゲットはシミュレーションやデータ解析のための処理。
変数を変えながら大量に流す処理細切れにして並列に流せる処理 が向いている。

公式(番外編)

膨大なパラメタを探索したり、予め大量の画像に推論したラベルを貼るといった
昨今話題となっている深層学習分野にも有用、今後利用は広がりそう。

個人的印象

上の深層学習の例では API 消費にレートリミットをかけるという位置付けで
AWS Batch を使っていますが、この使い方はとても汎用的だと思います。
ということで、以下あたりも向いていそう。

  • レートリミットをかけたい処理の実行

例えば同時に流してよい処理がクラスタ全体で一つだけであるとか、
3 つ程度にしたいといった時にクラスタとジョブの定義だけで調整可能。

  • ECS で RunTask していた非同期タスク

科学技術計算といった高度なものではなく、もっとシンプルなタスク。
Web / スマホアプリでも定期的に必要になる小さなジョブなども
予め Docker イメージになっているようであればすぐ使えて便利。

リソースの管理とジョブのスケジューリング

業界によって意味の異なる言葉の整理。

HPC 界隈、コンテナ(Web)界隈、業務システム界隈それぞれで
少しずつ意味が異なるようなので、比較しながら併記します。
(AWS Batch での意味 = HPC 分野での意味)

クラスタ、リソース管理

AWS Batch のいうクラスタは、将来的には HPC 方向に機能強化されるはず・・

  • HPC: 施設・研究者で共有される 巨大なリソース をクラスタとして管理。
    ジョブの要求するハードウェア性能は一般にとてもシビアであり、
    どこでどんな性能のノードが使えるかといった情報の収集も厳密。
  • コンテナ: 複数のサービスでシェアされる特定サーバ群のことで
    一般には可用性やスケーラビリティが重視された構成が取られる。
    どのホストで稼働するかは重要ではなく、むしろどこでも動くよう設計される。
  • 業務: データセンタ内のリソースを管理。あまり包括的には扱われない。
    稼働するアプリケーションは頻繁に変わるものではなく
    とにかく安定的・効率的にサービスが稼働することが大切。

スケジューラ

  • HPC: 実行したいジョブはキューに投げる。リソースが空いたら次の処理が始まる。
    ジョブ同士の依存関係が強い。順序や処理間のデータ移動も重要。
    優先的に処理したいジョブは割り込める必要がある。
    多くは試行錯誤のためのジョブ、FAIL してもいいが処理時間はとにかく長い。
  • コンテナ: 各サービスの要求するリソースを見つけ次第どこかに投入される。
    サービスの理想状態を別途管理する必要があり、異常終了時などの再起動や
    すでに起動しているサービスの状態を考慮した配置も必要になる。
  • 業務: 業務やその時間、ワークフローに応じてジョブを起動・停止する。
    ジョブ同士の依存関係も強く、処理に失敗した場合のワークフローは最も複雑。
    ユーザごとにそのあたりを設定変更できる柔軟さが必要。

AWS Batch の概念・機能

コンピューティング環境

AWS Batch には「コンピューティング環境」という概念がありますが
いわゆる「クラスタ」のようなもので、複数インスタンスの集合です。

そしてそれは、用途に応じて 2 種類あります。

Managed 環境

Unmanaged でなければいけない理由がなければ Managed 環境がオススメ。
Managed 環境の特徴は以下の通り。

  • 待機ジョブの深さに応じてクラスタがオートスケールアウト / イン
  • ECS クラスタを裏で作成・管理してくれる
  • Spot Fleet が簡単に使えて便利

Unmanaged 環境

ちょっと変わったクラスタにカスタマイズする必要がある場合はこちら。
AWS Batch の生成する ECS クラスタに「関連づけるインスタンス」を
自由にカスタマイズ可能。例えばこんなとき。

  • 特定の AMI を使いたい
  • あれこれ調整した AutoScaling グループを使いたい
  • EFS を使いたい
  • GPU を使いたい

Unmanaged 環境の場合はキューの深さによるオートスケールが働かないため
このようなアーキテクチャ で別途用意する必要があります。

ジョブ定義・実行

ジョブの定義は JSON で事前に宣言 することになります。
ジョブの処理ロジックについては、さらにそれ以前に Docker イメージにして
DockerHub や ECR などに push しておく必要があります。

実行時パラメタ

ジョブの基本的な起動パラメタは事前に JSON に定義するものの、
実行時に挙動を変える手段が AWS Batch には 2 つのあります

  • Ref:XXX & –parameters : 事前に XXX と定義したパラメタを実行時に指定
  • 環境変数 : コンテナへ渡す環境変数を実行時に指定

依存関係のあるジョブ

ジョブ投入時に --depends-on オプションで、すでに投入済みの
依存するジョブの ID を渡すことで依存関係を定義できます。

ジョブ間のデータ連携

HPC 系バッチコンピューティングを支援するマネージドサービスということで
そのデータの連携には以下サービス群の利用が想定されているようです。

  • EFS: まだ東京リージョンに来てないけども・・
  • EBS: 前処理したタイミングでスナップショットを取り展開、など
  • S3: AWS といえば S3 の活用ですが、もちろん大活躍
  • RDS / DynamoDB: 使いどころはたくさんありそう

他サービスとの連携

AWS を使い倒せば、よりセキュアで安定したサービスにも

  • CloudWatch Logs: ジョブの標準出力は全てここに連携されます
  • IAM: ECS ベースなこともあり、ジョブごとの権限管理にはロールが使える
  • KMS: 秘密情報の管理には KMS + IAM ロールがほんとに便利
  • Lambda + CloudWatch Events: Unmanaged 環境の自前オートスケールなど

他サービスとの使い分け

Lambda や EMR、ECS とどう使い分けるの?という。Batch を選択する意味。

なぜ Batch がでたのか

Azure には AWS より以前に、同名の Azure Batch というサービスがありましたが
こちらも狙いは、汎用的な 科学技術計算や HPC 基盤のマネージド提供でした。

AWS にも EMR や MachineLearning といったある種の問題解決に特化した
マネージドサービスはありましたが、汎用的なバッチ環境としては
AWS Batch が最も適切なサービスとなりそうです。

使い分け

上記のメリットに合致したジョブなら AWS Batch。
悩ましいとしたら、例えば

  • Lambda では難しい(運用・開発効率、サーバ性能、タイムアウト、言語)
  • EMR 向けに作りこまれたものではない(既存の処理を使いたい)

のならば AWS Batch を使う、など。

使ってみよう

実際にジョブを流してみると感覚がつかめると思います。

ハンズオン


  1. Managed 環境だった場合の挙動 

  2. A が正常終了(SUCCEEDED)すると B が開始され、A が異常終了(FAILED)した場合は B も FAILED になる 

  3. 厳密には待機ジョブの数で調整がかかるので、CPU やメモリなどに応じたリソースの調達・解放がしたい場合は API を利用したプログラムが別途必要 

  4. 2017/03/01 時点 

続きを読む